summaryrefslogtreecommitdiffstats
path: root/deluge/ui/web
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/web')
-rw-r--r--deluge/ui/web/__init__.py8
-rw-r--r--deluge/ui/web/auth.py257
-rw-r--r--deluge/ui/web/common.py48
-rw-r--r--deluge/ui/web/css/deluge.css568
-rw-r--r--deluge/ui/web/css/ext-all-notheme.css5349
-rw-r--r--deluge/ui/web/css/ext-extensions-debug.css261
-rw-r--r--deluge/ui/web/css/ext-extensions.css1
-rw-r--r--deluge/ui/web/icons/active.pngbin0 -> 503 bytes
-rw-r--r--deluge/ui/web/icons/add.pngbin0 -> 358 bytes
-rw-r--r--deluge/ui/web/icons/add_file.pngbin0 -> 520 bytes
-rw-r--r--deluge/ui/web/icons/add_magnet.pngbin0 -> 589 bytes
-rw-r--r--deluge/ui/web/icons/add_url.pngbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/icons/alert.pngbin0 -> 462 bytes
-rw-r--r--deluge/ui/web/icons/all.pngbin0 -> 533 bytes
-rw-r--r--deluge/ui/web/icons/back.pngbin0 -> 443 bytes
-rw-r--r--deluge/ui/web/icons/bottom.pngbin0 -> 346 bytes
-rw-r--r--deluge/ui/web/icons/checking.pngbin0 -> 489 bytes
-rw-r--r--deluge/ui/web/icons/connection_manager.pngbin0 -> 464 bytes
-rw-r--r--deluge/ui/web/icons/connections.pngbin0 -> 560 bytes
-rw-r--r--deluge/ui/web/icons/create.pngbin0 -> 541 bytes
-rw-r--r--deluge/ui/web/icons/deluge-192.pngbin0 -> 6604 bytes
-rw-r--r--deluge/ui/web/icons/deluge-32.pngbin0 -> 1126 bytes
-rw-r--r--deluge/ui/web/icons/deluge-512.pngbin0 -> 20126 bytes
-rw-r--r--deluge/ui/web/icons/deluge-apple-180.pngbin0 -> 5367 bytes
-rw-r--r--deluge/ui/web/icons/deluge.pngbin0 -> 551 bytes
-rw-r--r--deluge/ui/web/icons/dht.pngbin0 -> 582 bytes
-rw-r--r--deluge/ui/web/icons/document.pngbin0 -> 406 bytes
-rw-r--r--deluge/ui/web/icons/down.pngbin0 -> 427 bytes
-rw-r--r--deluge/ui/web/icons/downloading.pngbin0 -> 462 bytes
-rw-r--r--deluge/ui/web/icons/drive.pngbin0 -> 381 bytes
-rw-r--r--deluge/ui/web/icons/edit_trackers.pngbin0 -> 589 bytes
-rw-r--r--deluge/ui/web/icons/error.pngbin0 -> 730 bytes
-rw-r--r--deluge/ui/web/icons/expand_all.pngbin0 -> 612 bytes
-rw-r--r--deluge/ui/web/icons/favicon.icobin0 -> 15086 bytes
-rw-r--r--deluge/ui/web/icons/find_more.pngbin0 -> 557 bytes
-rw-r--r--deluge/ui/web/icons/forward.pngbin0 -> 436 bytes
-rw-r--r--deluge/ui/web/icons/help.pngbin0 -> 772 bytes
-rw-r--r--deluge/ui/web/icons/high.pngbin0 -> 505 bytes
-rw-r--r--deluge/ui/web/icons/home.pngbin0 -> 550 bytes
-rw-r--r--deluge/ui/web/icons/inactive.pngbin0 -> 431 bytes
-rw-r--r--deluge/ui/web/icons/install_plugin.pngbin0 -> 674 bytes
-rw-r--r--deluge/ui/web/icons/login.pngbin0 -> 469 bytes
-rw-r--r--deluge/ui/web/icons/logout.pngbin0 -> 599 bytes
-rw-r--r--deluge/ui/web/icons/low.pngbin0 -> 358 bytes
-rw-r--r--deluge/ui/web/icons/move.pngbin0 -> 524 bytes
-rw-r--r--deluge/ui/web/icons/no_download.pngbin0 -> 581 bytes
-rw-r--r--deluge/ui/web/icons/normal.pngbin0 -> 436 bytes
-rw-r--r--deluge/ui/web/icons/ok.pngbin0 -> 766 bytes
-rw-r--r--deluge/ui/web/icons/pause.pngbin0 -> 331 bytes
-rw-r--r--deluge/ui/web/icons/preferences.pngbin0 -> 694 bytes
-rw-r--r--deluge/ui/web/icons/queue.pngbin0 -> 432 bytes
-rw-r--r--deluge/ui/web/icons/queued.pngbin0 -> 410 bytes
-rw-r--r--deluge/ui/web/icons/recheck.pngbin0 -> 557 bytes
-rw-r--r--deluge/ui/web/icons/remove.pngbin0 -> 194 bytes
-rw-r--r--deluge/ui/web/icons/seeding.pngbin0 -> 505 bytes
-rw-r--r--deluge/ui/web/icons/start.pngbin0 -> 358 bytes
-rw-r--r--deluge/ui/web/icons/top.pngbin0 -> 325 bytes
-rw-r--r--deluge/ui/web/icons/traffic.pngbin0 -> 394 bytes
-rw-r--r--deluge/ui/web/icons/up.pngbin0 -> 420 bytes
-rw-r--r--deluge/ui/web/icons/update.pngbin0 -> 675 bytes
-rw-r--r--deluge/ui/web/icons/upload_slots.pngbin0 -> 422 bytes
-rw-r--r--deluge/ui/web/icons/warning.pngbin0 -> 521 bytes
-rw-r--r--deluge/ui/web/images/s.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/images/spinner-split.gifbin0 -> 49 bytes
-rw-r--r--deluge/ui/web/images/spinner.gifbin0 -> 3186 bytes
-rw-r--r--deluge/ui/web/index.html48
-rw-r--r--deluge/ui/web/js/deluge-all-debug.js9868
-rw-r--r--deluge/ui/web/js/deluge-all/.order2
-rw-r--r--deluge/ui/web/js/deluge-all/AboutWindow.js129
-rw-r--r--deluge/ui/web/js/deluge-all/AddConnectionWindow.js117
-rw-r--r--deluge/ui/web/js/deluge-all/AddTrackerWindow.js94
-rw-r--r--deluge/ui/web/js/deluge-all/Client.js199
-rw-r--r--deluge/ui/web/js/deluge-all/ConnectionManager.js429
-rw-r--r--deluge/ui/web/js/deluge-all/Deluge.js186
-rw-r--r--deluge/ui/web/js/deluge-all/EditConnectionWindow.js134
-rw-r--r--deluge/ui/web/js/deluge-all/EditTrackerWindow.js83
-rw-r--r--deluge/ui/web/js/deluge-all/EditTrackersWindow.js239
-rw-r--r--deluge/ui/web/js/deluge-all/EventsManager.js118
-rw-r--r--deluge/ui/web/js/deluge-all/FileBrowser.js43
-rw-r--r--deluge/ui/web/js/deluge-all/FilterPanel.js175
-rw-r--r--deluge/ui/web/js/deluge-all/Formatters.js181
-rw-r--r--deluge/ui/web/js/deluge-all/Keys.js138
-rw-r--r--deluge/ui/web/js/deluge-all/LoginWindow.js134
-rw-r--r--deluge/ui/web/js/deluge-all/Menus.js388
-rw-r--r--deluge/ui/web/js/deluge-all/MoveStorage.js85
-rw-r--r--deluge/ui/web/js/deluge-all/MultiOptionsManager.js218
-rw-r--r--deluge/ui/web/js/deluge-all/OptionsManager.js279
-rw-r--r--deluge/ui/web/js/deluge-all/OtherLimitWindow.js82
-rw-r--r--deluge/ui/web/js/deluge-all/Plugin.js106
-rw-r--r--deluge/ui/web/js/deluge-all/RemoveWindow.js77
-rw-r--r--deluge/ui/web/js/deluge-all/Sidebar.js144
-rw-r--r--deluge/ui/web/js/deluge-all/Statusbar.js362
-rw-r--r--deluge/ui/web/js/deluge-all/StatusbarMenu.js79
-rw-r--r--deluge/ui/web/js/deluge-all/Toolbar.js206
-rw-r--r--deluge/ui/web/js/deluge-all/TorrentGrid.js510
-rw-r--r--deluge/ui/web/js/deluge-all/UI.js292
-rw-r--r--deluge/ui/web/js/deluge-all/add/.order1
-rw-r--r--deluge/ui/web/js/deluge-all/add/AddWindow.js321
-rw-r--r--deluge/ui/web/js/deluge-all/add/FilesTab.js99
-rw-r--r--deluge/ui/web/js/deluge-all/add/Infohash.js10
-rw-r--r--deluge/ui/web/js/deluge-all/add/OptionsPanel.js146
-rw-r--r--deluge/ui/web/js/deluge-all/add/OptionsTab.js217
-rw-r--r--deluge/ui/web/js/deluge-all/add/UrlWindow.js98
-rw-r--r--deluge/ui/web/js/deluge-all/add/Window.js29
-rw-r--r--deluge/ui/web/js/deluge-all/data/.order1
-rw-r--r--deluge/ui/web/js/deluge-all/data/PeerRecord.js53
-rw-r--r--deluge/ui/web/js/deluge-all/data/SortTypes.js37
-rw-r--r--deluge/ui/web/js/deluge-all/data/TorrentRecord.js121
-rw-r--r--deluge/ui/web/js/deluge-all/details/DetailsPanel.js81
-rw-r--r--deluge/ui/web/js/deluge-all/details/DetailsTab.js98
-rw-r--r--deluge/ui/web/js/deluge-all/details/FilesTab.js233
-rw-r--r--deluge/ui/web/js/deluge-all/details/OptionsTab.js417
-rw-r--r--deluge/ui/web/js/deluge-all/details/PeersTab.js166
-rw-r--r--deluge/ui/web/js/deluge-all/details/StatusTab.js155
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js203
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/CachePage.js61
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/DaemonPage.js85
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js124
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js99
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js83
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/InterfacePage.js304
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/NetworkPage.js257
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/OtherPage.js100
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/PluginsPage.js277
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js246
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/ProxyField.js225
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/ProxyPage.js62
-rw-r--r--deluge/ui/web/js/deluge-all/preferences/QueuePage.js234
-rw-r--r--deluge/ui/web/js/extjs/ext-all-debug.js52270
-rw-r--r--deluge/ui/web/js/extjs/ext-all.js21
-rw-r--r--deluge/ui/web/js/extjs/ext-base-debug.js3352
-rw-r--r--deluge/ui/web/js/extjs/ext-base.js21
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions-debug.js2931
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/JSLoader.js40
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/Spinner.js474
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/StatusBar.js422
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js208
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js50
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js68
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js13
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js206
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js75
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js270
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js39
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js68
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js468
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js123
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js40
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js18
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js149
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js33
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js9
-rw-r--r--deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js158
-rw-r--r--deluge/ui/web/js/gettext.js322
-rw-r--r--deluge/ui/web/json_api.py1019
-rw-r--r--deluge/ui/web/pluginmanager.py161
-rw-r--r--deluge/ui/web/render/404.html10
-rw-r--r--deluge/ui/web/render/tab_status.html29
-rw-r--r--deluge/ui/web/server.py806
-rw-r--r--deluge/ui/web/themes/css/xtheme-access.css1933
-rw-r--r--deluge/ui/web/themes/css/xtheme-blue.css1793
-rw-r--r--deluge/ui/web/themes/css/xtheme-gray.css1791
-rw-r--r--deluge/ui/web/themes/images/access/box/corners-blue.gifbin0 -> 1010 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/corners.gifbin0 -> 1005 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/l-blue.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/l.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/r-blue.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/r.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/tb-blue.gifbin0 -> 843 bytes
-rw-r--r--deluge/ui/web/themes/images/access/box/tb.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/arrow.gifbin0 -> 833 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/btn.gifbin0 -> 2871 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/group-cs.gifbin0 -> 2459 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/group-lr.gifbin0 -> 861 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/group-tb.gifbin0 -> 70 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow-b-noline.gifbin0 -> 904 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow-b.gifbin0 -> 943 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow-bo.gifbin0 -> 961 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow-noline.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow-o.gifbin0 -> 155 bytes
-rw-r--r--deluge/ui/web/themes/images/access/button/s-arrow.gifbin0 -> 956 bytes
-rw-r--r--deluge/ui/web/themes/images/access/editor/tb-sprite.gifbin0 -> 1994 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/checkbox.gifbin0 -> 2061 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/clear-trigger.gifbin0 -> 2027 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/clear-trigger.psdbin0 -> 41047 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/date-trigger.gifbin0 -> 1620 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/date-trigger.psdbin0 -> 46095 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/error-tip-corners.gifbin0 -> 4183 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/exclamation.gifbin0 -> 614 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/radio.gifbin0 -> 1746 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/search-trigger.gifbin0 -> 1534 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/search-trigger.psdbin0 -> 49761 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/text-bg.gifbin0 -> 66 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/trigger-tpl.gifbin0 -> 908 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/trigger.gifbin0 -> 1451 bytes
-rw-r--r--deluge/ui/web/themes/images/access/form/trigger.psdbin0 -> 44793 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/arrow-left-white.gifbin0 -> 825 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/arrow-right-white.gifbin0 -> 825 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/col-move-bottom.gifbin0 -> 868 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/col-move-top.gifbin0 -> 869 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/columns.gifbin0 -> 962 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/dirty.gifbin0 -> 68 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/done.gifbin0 -> 133 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/drop-no.gifbin0 -> 947 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/drop-yes.gifbin0 -> 860 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/footer-bg.gifbin0 -> 834 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-blue-hd.gifbin0 -> 829 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-blue-split.gifbin0 -> 47 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-hrow.gifbin0 -> 855 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-loading.gifbin0 -> 701 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-split.gifbin0 -> 817 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid-vista-hd.gifbin0 -> 829 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid3-hd-btn.gifbin0 -> 419 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid3-hrow-over.gifbin0 -> 268 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid3-hrow.gifbin0 -> 164 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid3-special-col-bg.gifbin0 -> 162 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/grid3-special-col-sel-bg.gifbin0 -> 162 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/group-by.gifbin0 -> 917 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/group-collapse.gifbin0 -> 77 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/group-expand-sprite.gifbin0 -> 131 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/group-expand.gifbin0 -> 82 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hd-pop.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-asc.gifbin0 -> 931 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-desc.gifbin0 -> 930 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-lock.gifbin0 -> 955 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-lock.pngbin0 -> 484 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-unlock.gifbin0 -> 971 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/hmenu-unlock.pngbin0 -> 548 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/invalid_line.gifbin0 -> 46 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/loading.gifbin0 -> 771 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/mso-hd.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/nowait.gifbin0 -> 884 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-first-disabled.gifbin0 -> 340 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-first.gifbin0 -> 96 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-last-disabled.gifbin0 -> 340 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-last.gifbin0 -> 96 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-next-disabled.gifbin0 -> 195 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-next.gifbin0 -> 82 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-prev-disabled.gifbin0 -> 197 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/page-prev.gifbin0 -> 82 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/pick-button.gifbin0 -> 1036 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/refresh.gifbin0 -> 91 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/row-check-sprite.gifbin0 -> 1083 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/row-expand-sprite.gifbin0 -> 955 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/row-over.gifbin0 -> 823 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/row-sel.gifbin0 -> 823 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/sort-hd.gifbin0 -> 2075 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/sort_asc.gifbin0 -> 74 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/sort_desc.gifbin0 -> 73 bytes
-rw-r--r--deluge/ui/web/themes/images/access/grid/wait.gifbin0 -> 1100 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/checked.gifbin0 -> 959 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/group-checked.gifbin0 -> 856 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/item-over.gifbin0 -> 820 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/menu-parent.gifbin0 -> 73 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/menu.gifbin0 -> 826 bytes
-rw-r--r--deluge/ui/web/themes/images/access/menu/unchecked.gifbin0 -> 941 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/corners-sprite.gifbin0 -> 577 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/left-right.gifbin0 -> 52 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/light-hd.gifbin0 -> 161 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/tool-sprite-tpl.gifbin0 -> 971 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/tool-sprites.gifbin0 -> 1981 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/tools-sprites-trans.gifbin0 -> 2843 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/top-bottom.gifbin0 -> 116 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/white-corners-sprite.gifbin0 -> 1366 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/white-left-right.gifbin0 -> 52 bytes
-rw-r--r--deluge/ui/web/themes/images/access/panel/white-top-bottom.gifbin0 -> 115 bytes
-rw-r--r--deluge/ui/web/themes/images/access/progress/progress-bg.gifbin0 -> 151 bytes
-rw-r--r--deluge/ui/web/themes/images/access/qtip/close.gifbin0 -> 972 bytes
-rw-r--r--deluge/ui/web/themes/images/access/qtip/tip-anchor-sprite.gifbin0 -> 951 bytes
-rw-r--r--deluge/ui/web/themes/images/access/qtip/tip-sprite.gifbin0 -> 3376 bytes
-rw-r--r--deluge/ui/web/themes/images/access/shared/glass-bg.gifbin0 -> 103 bytes
-rw-r--r--deluge/ui/web/themes/images/access/shared/hd-sprite.gifbin0 -> 673 bytes
-rw-r--r--deluge/ui/web/themes/images/access/shared/left-btn.gifbin0 -> 77 bytes
-rw-r--r--deluge/ui/web/themes/images/access/shared/right-btn.gifbin0 -> 79 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/e-handle-dark.gifbin0 -> 248 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/e-handle.gifbin0 -> 753 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/ne-handle-dark.gifbin0 -> 66 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/ne-handle.gifbin0 -> 115 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/nw-handle-dark.gifbin0 -> 66 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/nw-handle.gifbin0 -> 114 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/s-handle-dark.gifbin0 -> 246 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/s-handle.gifbin0 -> 494 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/se-handle-dark.gifbin0 -> 65 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/se-handle.gifbin0 -> 114 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/square.gifbin0 -> 123 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/sw-handle-dark.gifbin0 -> 66 bytes
-rw-r--r--deluge/ui/web/themes/images/access/sizer/sw-handle.gifbin0 -> 116 bytes
-rw-r--r--deluge/ui/web/themes/images/access/slider/slider-bg.pngbin0 -> 185 bytes
-rw-r--r--deluge/ui/web/themes/images/access/slider/slider-thumb.pngbin0 -> 512 bytes
-rw-r--r--deluge/ui/web/themes/images/access/slider/slider-v-bg.pngbin0 -> 154 bytes
-rw-r--r--deluge/ui/web/themes/images/access/slider/slider-v-thumb.pngbin0 -> 481 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/scroll-left.gifbin0 -> 996 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/scroll-right.gifbin0 -> 999 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-left-bg.gifbin0 -> 130 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-right-bg.gifbin0 -> 513 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-btm-left-bg.gifbin0 -> 512 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-btm-right-bg.gifbin0 -> 117 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-close.gifbin0 -> 76 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-strip-bg.gifbin0 -> 827 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tab-strip-btm-bg.gifbin0 -> 70 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tabs/tabs-sprite.gifbin0 -> 1221 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/bg.gifbin0 -> 82 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/btn-arrow-light.gifbin0 -> 916 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/btn-arrow.gifbin0 -> 919 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/btn-over-bg.gifbin0 -> 837 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/gray-bg.gifbin0 -> 832 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/more.gifbin0 -> 67 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/s-arrow-bo.gifbin0 -> 186 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/tb-btn-sprite.gifbin0 -> 1127 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/tb-xl-btn-sprite.gifbin0 -> 1663 bytes
-rw-r--r--deluge/ui/web/themes/images/access/toolbar/tb-xl-sep.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/arrows.gifbin0 -> 183 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-add.gifbin0 -> 1001 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-between.gifbin0 -> 907 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-no.gifbin0 -> 949 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-over.gifbin0 -> 911 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-under.gifbin0 -> 911 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/drop-yes.gifbin0 -> 1016 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-end-minus-nl.gifbin0 -> 86 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-end-minus.gifbin0 -> 104 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-end-plus-nl.gifbin0 -> 89 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-end-plus.gifbin0 -> 108 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-end.gifbin0 -> 844 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-line.gifbin0 -> 846 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-minus-nl.gifbin0 -> 86 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-minus.gifbin0 -> 106 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-plus-nl.gifbin0 -> 89 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow-plus.gifbin0 -> 111 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/elbow.gifbin0 -> 850 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/folder-open.gifbin0 -> 342 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/folder.gifbin0 -> 340 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/leaf.gifbin0 -> 945 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/loading.gifbin0 -> 771 bytes
-rw-r--r--deluge/ui/web/themes/images/access/tree/s.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/icon-error.gifbin0 -> 256 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/icon-info.gifbin0 -> 172 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/icon-question.gifbin0 -> 217 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/icon-warning.gifbin0 -> 173 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/left-corners.pngbin0 -> 137 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/left-right.pngbin0 -> 83 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/right-corners.pngbin0 -> 138 bytes
-rw-r--r--deluge/ui/web/themes/images/access/window/top-bottom.pngbin0 -> 105 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/corners-blue.gifbin0 -> 1010 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/corners.gifbin0 -> 1005 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/l-blue.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/l.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/r-blue.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/r.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/tb-blue.gifbin0 -> 851 bytes
-rw-r--r--deluge/ui/web/themes/images/default/box/tb.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/arrow.gifbin0 -> 828 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/btn.gifbin0 -> 4298 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/group-cs.gifbin0 -> 2459 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/group-lr.gifbin0 -> 861 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/group-tb.gifbin0 -> 846 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow-b-noline.gifbin0 -> 898 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow-b.gifbin0 -> 937 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow-bo.gifbin0 -> 139 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow-noline.gifbin0 -> 863 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow-o.gifbin0 -> 937 bytes
-rw-r--r--deluge/ui/web/themes/images/default/button/s-arrow.gifbin0 -> 937 bytes
-rw-r--r--deluge/ui/web/themes/images/default/dd/drop-add.gifbin0 -> 1001 bytes
-rw-r--r--deluge/ui/web/themes/images/default/dd/drop-no.gifbin0 -> 949 bytes
-rw-r--r--deluge/ui/web/themes/images/default/dd/drop-yes.gifbin0 -> 1016 bytes
-rw-r--r--deluge/ui/web/themes/images/default/editor/tb-sprite.gifbin0 -> 2072 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/checkbox.gifbin0 -> 2061 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/clear-trigger.gifbin0 -> 1988 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/clear-trigger.psdbin0 -> 11804 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/date-trigger.gifbin0 -> 1603 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/date-trigger.psdbin0 -> 12377 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/error-tip-corners.gifbin0 -> 4183 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/exclamation.gifbin0 -> 996 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/radio.gifbin0 -> 1746 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/search-trigger.gifbin0 -> 2182 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/search-trigger.psdbin0 -> 15601 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/text-bg.gifbin0 -> 819 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/trigger-square.gifbin0 -> 1810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/trigger-square.psdbin0 -> 36542 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/trigger-tpl.gifbin0 -> 1487 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/trigger.gifbin0 -> 1816 bytes
-rw-r--r--deluge/ui/web/themes/images/default/form/trigger.psdbin0 -> 37599 bytes
-rw-r--r--deluge/ui/web/themes/images/default/gradient-bg.gifbin0 -> 1472 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/arrow-left-white.gifbin0 -> 825 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/arrow-right-white.gifbin0 -> 825 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/col-move-bottom.gifbin0 -> 868 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/col-move-top.gifbin0 -> 869 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/columns.gifbin0 -> 962 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/dirty.gifbin0 -> 832 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/done.gifbin0 -> 133 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/drop-no.gifbin0 -> 947 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/drop-yes.gifbin0 -> 860 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/footer-bg.gifbin0 -> 834 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-blue-hd.gifbin0 -> 829 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-blue-split.gifbin0 -> 817 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-hrow.gifbin0 -> 855 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-loading.gifbin0 -> 701 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-split.gifbin0 -> 817 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid-vista-hd.gifbin0 -> 829 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-hd-btn.gifbin0 -> 1229 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-hrow-over.gifbin0 -> 823 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-hrow.gifbin0 -> 836 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-rowheader.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-special-col-bg.gifbin0 -> 837 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/grid3-special-col-sel-bg.gifbin0 -> 843 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/group-by.gifbin0 -> 917 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/group-collapse.gifbin0 -> 881 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/group-expand-sprite.gifbin0 -> 955 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/group-expand.gifbin0 -> 884 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hd-pop.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-asc.gifbin0 -> 931 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-desc.gifbin0 -> 930 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-lock.gifbin0 -> 955 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-lock.pngbin0 -> 484 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-unlock.gifbin0 -> 971 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/hmenu-unlock.pngbin0 -> 548 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/invalid_line.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/loading.gifbin0 -> 771 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/mso-hd.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/nowait.gifbin0 -> 884 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-first-disabled.gifbin0 -> 925 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-first.gifbin0 -> 925 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-last-disabled.gifbin0 -> 923 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-last.gifbin0 -> 923 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-next-disabled.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-next.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-prev-disabled.gifbin0 -> 879 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/page-prev.gifbin0 -> 879 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/pick-button.gifbin0 -> 1036 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/refresh-disabled.gifbin0 -> 577 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/refresh.gifbin0 -> 977 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/row-check-sprite.gifbin0 -> 1083 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/row-expand-sprite.gifbin0 -> 955 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/row-over.gifbin0 -> 823 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/row-sel.gifbin0 -> 823 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/sort-hd.gifbin0 -> 1473 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/sort_asc.gifbin0 -> 830 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/sort_desc.gifbin0 -> 833 bytes
-rw-r--r--deluge/ui/web/themes/images/default/grid/wait.gifbin0 -> 1100 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/collapse.gifbin0 -> 842 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/expand.gifbin0 -> 842 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/gradient-bg.gifbin0 -> 1472 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/mini-bottom.gifbin0 -> 856 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/mini-left.gifbin0 -> 871 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/mini-right.gifbin0 -> 872 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/mini-top.gifbin0 -> 856 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/ns-collapse.gifbin0 -> 842 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/ns-expand.gifbin0 -> 843 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/panel-close.gifbin0 -> 829 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/panel-title-bg.gifbin0 -> 838 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/panel-title-light-bg.gifbin0 -> 835 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/stick.gifbin0 -> 874 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/stuck.gifbin0 -> 92 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/tab-close-on.gifbin0 -> 880 bytes
-rw-r--r--deluge/ui/web/themes/images/default/layout/tab-close.gifbin0 -> 859 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/checked.gifbin0 -> 959 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/group-checked.gifbin0 -> 891 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/item-over.gifbin0 -> 820 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/menu-parent.gifbin0 -> 854 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/menu.gifbin0 -> 834 bytes
-rw-r--r--deluge/ui/web/themes/images/default/menu/unchecked.gifbin0 -> 941 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/corners-sprite.gifbin0 -> 1418 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/left-right.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/light-hd.gifbin0 -> 827 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/tool-sprite-tpl.gifbin0 -> 971 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/tool-sprites.gifbin0 -> 5421 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/tools-sprites-trans.gifbin0 -> 2843 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/top-bottom.gifbin0 -> 875 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/top-bottom.pngbin0 -> 160 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/white-corners-sprite.gifbin0 -> 1366 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/white-left-right.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/default/panel/white-top-bottom.gifbin0 -> 872 bytes
-rw-r--r--deluge/ui/web/themes/images/default/progress/progress-bg.gifbin0 -> 834 bytes
-rw-r--r--deluge/ui/web/themes/images/default/qtip/bg.gifbin0 -> 1091 bytes
-rw-r--r--deluge/ui/web/themes/images/default/qtip/close.gifbin0 -> 972 bytes
-rw-r--r--deluge/ui/web/themes/images/default/qtip/tip-anchor-sprite.gifbin0 -> 951 bytes
-rw-r--r--deluge/ui/web/themes/images/default/qtip/tip-sprite.gifbin0 -> 4271 bytes
-rw-r--r--deluge/ui/web/themes/images/default/s.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shadow-c.pngbin0 -> 71 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shadow-lr.pngbin0 -> 88 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shadow.pngbin0 -> 223 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/blue-loading.gifbin0 -> 3236 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/calendar.gifbin0 -> 979 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/glass-bg.gifbin0 -> 873 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/hd-sprite.gifbin0 -> 1099 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/large-loading.gifbin0 -> 3236 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/left-btn.gifbin0 -> 870 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/loading-balls.gifbin0 -> 2118 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/right-btn.gifbin0 -> 871 bytes
-rw-r--r--deluge/ui/web/themes/images/default/shared/warning.gifbin0 -> 960 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/e-handle-dark.gifbin0 -> 1062 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/e-handle.gifbin0 -> 1586 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/ne-handle-dark.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/ne-handle.gifbin0 -> 854 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/nw-handle-dark.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/nw-handle.gifbin0 -> 853 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/s-handle-dark.gifbin0 -> 1060 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/s-handle.gifbin0 -> 1318 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/se-handle-dark.gifbin0 -> 838 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/se-handle.gifbin0 -> 853 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/square.gifbin0 -> 864 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/sw-handle-dark.gifbin0 -> 839 bytes
-rw-r--r--deluge/ui/web/themes/images/default/sizer/sw-handle.gifbin0 -> 855 bytes
-rw-r--r--deluge/ui/web/themes/images/default/slider/slider-bg.pngbin0 -> 191 bytes
-rw-r--r--deluge/ui/web/themes/images/default/slider/slider-thumb.pngbin0 -> 626 bytes
-rw-r--r--deluge/ui/web/themes/images/default/slider/slider-v-bg.pngbin0 -> 161 bytes
-rw-r--r--deluge/ui/web/themes/images/default/slider/slider-v-thumb.pngbin0 -> 601 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/scroll-left.gifbin0 -> 1295 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/scroll-right.gifbin0 -> 1300 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/scroller-bg.gifbin0 -> 1100 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-left-bg.gifbin0 -> 886 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-right-bg.gifbin0 -> 1386 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-left-bg.gifbin0 -> 1402 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-over-left-bg.gifbin0 -> 191 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-over-right-bg.gifbin0 -> 638 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-btm-right-bg.gifbin0 -> 863 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-close.gifbin0 -> 896 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-strip-bg.gifbin0 -> 835 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-strip-bg.pngbin0 -> 95 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tab-strip-btm-bg.gifbin0 -> 826 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tabs/tabs-sprite.gifbin0 -> 2120 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/bg.gifbin0 -> 904 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/btn-arrow-light.gifbin0 -> 916 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/btn-arrow.gifbin0 -> 919 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/btn-over-bg.gifbin0 -> 837 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/gray-bg.gifbin0 -> 832 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/more.gifbin0 -> 845 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/tb-bg.gifbin0 -> 862 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/tb-btn-sprite.gifbin0 -> 1127 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/tb-xl-btn-sprite.gifbin0 -> 1663 bytes
-rw-r--r--deluge/ui/web/themes/images/default/toolbar/tb-xl-sep.gifbin0 -> 810 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/arrows.gifbin0 -> 617 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-add.gifbin0 -> 1001 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-between.gifbin0 -> 907 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-no.gifbin0 -> 949 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-over.gifbin0 -> 911 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-under.gifbin0 -> 911 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/drop-yes.gifbin0 -> 1016 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-end-minus-nl.gifbin0 -> 898 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-end-minus.gifbin0 -> 905 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-end-plus-nl.gifbin0 -> 900 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-end-plus.gifbin0 -> 907 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-end.gifbin0 -> 844 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-line.gifbin0 -> 846 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-minus-nl.gifbin0 -> 898 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-minus.gifbin0 -> 908 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-plus-nl.gifbin0 -> 900 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow-plus.gifbin0 -> 910 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/elbow.gifbin0 -> 850 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/folder-open.gifbin0 -> 956 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/folder.gifbin0 -> 952 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/leaf.gifbin0 -> 945 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/loading.gifbin0 -> 771 bytes
-rw-r--r--deluge/ui/web/themes/images/default/tree/s.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/icon-error.gifbin0 -> 1669 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/icon-info.gifbin0 -> 1586 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/icon-question.gifbin0 -> 1607 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/icon-warning.gifbin0 -> 1483 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/left-corners.pngbin0 -> 137 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/left-corners.psdbin0 -> 15576 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/left-right.pngbin0 -> 84 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/left-right.psdbin0 -> 24046 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/right-corners.pngbin0 -> 138 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/right-corners.psdbin0 -> 15530 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/top-bottom.pngbin0 -> 119 bytes
-rw-r--r--deluge/ui/web/themes/images/default/window/top-bottom.psdbin0 -> 32128 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/btn-arrow.gifbin0 -> 870 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/btn-sprite.gifbin0 -> 1222 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/btn.gifbin0 -> 3319 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/group-cs.gifbin0 -> 2459 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/group-lr.gifbin0 -> 861 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/group-tb.gifbin0 -> 846 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/s-arrow-bo.gifbin0 -> 123 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/button/s-arrow-o.gifbin0 -> 139 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/form/clear-trigger.gifbin0 -> 1425 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/form/date-trigger.gifbin0 -> 929 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/form/search-trigger.gifbin0 -> 2220 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/form/trigger-square.gifbin0 -> 1071 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/form/trigger.gifbin0 -> 1080 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/gradient-bg.gifbin0 -> 1472 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/col-move-bottom.gifbin0 -> 177 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/col-move-top.gifbin0 -> 178 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-hd-btn.gifbin0 -> 482 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-hrow-over.gifbin0 -> 56 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-hrow-over2.gifbin0 -> 107 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-hrow.gifbin0 -> 836 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-hrow2.gifbin0 -> 107 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg.gifbin0 -> 158 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg2.gifbin0 -> 158 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/grid3-special-col-sel-bg.gifbin0 -> 158 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/group-collapse.gifbin0 -> 136 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/group-expand-sprite.gifbin0 -> 196 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/group-expand.gifbin0 -> 138 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/page-first.gifbin0 -> 327 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/page-last.gifbin0 -> 325 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/page-next.gifbin0 -> 183 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/page-prev.gifbin0 -> 186 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/refresh.gifbin0 -> 570 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/row-expand-sprite.gifbin0 -> 196 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/sort-hd.gifbin0 -> 2731 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/sort_asc.gifbin0 -> 59 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/grid/sort_desc.gifbin0 -> 59 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/menu/group-checked.gifbin0 -> 295 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/menu/item-over-disabled.gifbin0 -> 49 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/menu/item-over.gifbin0 -> 850 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/menu/menu-parent.gifbin0 -> 165 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/corners-sprite.gifbin0 -> 1402 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/left-right.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/light-hd.gifbin0 -> 827 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/tool-sprite-tpl.gifbin0 -> 971 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/tool-sprites.gifbin0 -> 5835 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/tools-sprites-trans.gifbin0 -> 1981 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/top-bottom.gifbin0 -> 871 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/top-bottom.pngbin0 -> 160 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/white-corners-sprite.gifbin0 -> 1365 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/white-left-right.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/panel/white-top-bottom.gifbin0 -> 860 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/progress/progress-bg.gifbin0 -> 107 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/qtip/bg.gifbin0 -> 1024 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/qtip/close.gifbin0 -> 972 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/qtip/tip-anchor-sprite.gifbin0 -> 164 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/qtip/tip-sprite.gifbin0 -> 3241 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/s.gifbin0 -> 43 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/shared/hd-sprite.gifbin0 -> 305 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/shared/left-btn.gifbin0 -> 106 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/shared/right-btn.gifbin0 -> 107 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/e-handle.gifbin0 -> 753 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/ne-handle.gifbin0 -> 128 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/nw-handle.gifbin0 -> 114 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/s-handle.gifbin0 -> 494 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/se-handle.gifbin0 -> 114 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/square.gifbin0 -> 123 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/sizer/sw-handle.gifbin0 -> 116 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/slider/slider-thumb.pngbin0 -> 376 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/slider/slider-v-thumb.pngbin0 -> 333 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/scroll-left.gifbin0 -> 1260 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/scroll-right.gifbin0 -> 1269 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/scroller-bg.gifbin0 -> 1090 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-left-bg.gifbin0 -> 881 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-right-bg.gifbin0 -> 1383 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-left-bg.gifbin0 -> 1402 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-over-left-bg.gifbin0 -> 189 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-over-right-bg.gifbin0 -> 635 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-btm-right-bg.gifbin0 -> 863 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-close.gifbin0 -> 896 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.gifbin0 -> 835 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.pngbin0 -> 95 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tab-strip-btm-bg.gifbin0 -> 826 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tabs/tabs-sprite.gifbin0 -> 2109 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/bg.gifbin0 -> 854 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/btn-arrow-light.gifbin0 -> 916 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/btn-arrow.gifbin0 -> 919 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/btn-over-bg.gifbin0 -> 837 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/gray-bg.gifbin0 -> 815 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/more.gifbin0 -> 67 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/tb-bg.gifbin0 -> 862 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/toolbar/tb-btn-sprite.gifbin0 -> 1021 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tree/arrows.gifbin0 -> 407 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tree/elbow-end-minus-nl.gifbin0 -> 149 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tree/elbow-end-minus.gifbin0 -> 154 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tree/elbow-end-plus-nl.gifbin0 -> 151 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/tree/elbow-end-plus.gifbin0 -> 156 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/icon-error.gifbin0 -> 1669 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/icon-info.gifbin0 -> 1586 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/icon-question.gifbin0 -> 1607 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/icon-warning.gifbin0 -> 1483 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/left-corners.pngbin0 -> 205 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/left-right.pngbin0 -> 75 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/right-corners.pngbin0 -> 204 bytes
-rw-r--r--deluge/ui/web/themes/images/gray/window/top-bottom.pngbin0 -> 108 bytes
-rw-r--r--deluge/ui/web/web.py91
670 files changed, 95761 insertions, 0 deletions
diff --git a/deluge/ui/web/__init__.py b/deluge/ui/web/__init__.py
new file mode 100644
index 0000000..0be7eed
--- /dev/null
+++ b/deluge/ui/web/__init__.py
@@ -0,0 +1,8 @@
+from __future__ import unicode_literals
+
+from deluge.ui.web.web import Web
+
+
+def start():
+ web = Web()
+ web.start()
diff --git a/deluge/ui/web/auth.py b/deluge/ui/web/auth.py
new file mode 100644
index 0000000..fa95049
--- /dev/null
+++ b/deluge/ui/web/auth.py
@@ -0,0 +1,257 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import unicode_literals
+
+import hashlib
+import logging
+import os
+import time
+from datetime import datetime, timedelta
+from email.utils import formatdate
+
+from twisted.internet.task import LoopingCall
+
+from deluge.common import AUTH_LEVEL_ADMIN, AUTH_LEVEL_NONE
+from deluge.error import NotAuthorizedError
+from deluge.ui.web.json_api import JSONComponent, export
+
+log = logging.getLogger(__name__)
+
+
+def make_checksum(session_id):
+ checksum = 0
+ for value in [ord(char) for char in session_id]:
+ checksum += value
+ return checksum
+
+
+def get_session_id(session_id):
+ """
+ Checks a session id against its checksum
+ """
+ if not session_id:
+ return None
+
+ try:
+ checksum = int(session_id[-4:])
+ session_id = session_id[:-4]
+
+ if checksum == make_checksum(session_id):
+ return session_id
+ return None
+ except Exception as ex:
+ log.exception(ex)
+ return None
+
+
+def make_expires(timeout):
+ dt = timedelta(seconds=timeout)
+ expires = time.mktime((datetime.now() + dt).timetuple())
+ expires_str = formatdate(timeval=expires, localtime=False, usegmt=True)
+ return expires, expires_str
+
+
+class Auth(JSONComponent):
+ """
+ The component that implements authentification into the JSON interface.
+ """
+
+ def __init__(self, config):
+ super(Auth, self).__init__('Auth')
+ self.worker = LoopingCall(self._clean_sessions)
+ self.config = config
+
+ def start(self):
+ self.worker.start(5)
+
+ def stop(self):
+ self.worker.stop()
+
+ def _clean_sessions(self):
+ now = time.gmtime()
+ for session_id in list(self.config['sessions']):
+ session = self.config['sessions'][session_id]
+
+ if 'expires' not in session:
+ del self.config['sessions'][session_id]
+ continue
+
+ if time.gmtime(session['expires']) < now:
+ del self.config['sessions'][session_id]
+ continue
+
+ def _create_session(self, request, login='admin'):
+ """
+ Creates a new session.
+
+ :param login: the username of the user logging in, currently \
+ only for future use currently.
+ :type login: string
+ """
+ m = hashlib.sha256()
+ m.update(os.urandom(32))
+ session_id = m.hexdigest()
+
+ expires, expires_str = make_expires(self.config['session_timeout'])
+ checksum = str(make_checksum(session_id))
+
+ request.addCookie(
+ b'_session_id',
+ session_id + checksum,
+ path=request.base + b'json',
+ expires=expires_str,
+ )
+
+ log.debug('Creating session for %s', login)
+
+ if isinstance(self.config['sessions'], list):
+ self.config['sessions'] = {}
+
+ self.config['sessions'][session_id] = {
+ 'login': login,
+ 'level': AUTH_LEVEL_ADMIN,
+ 'expires': expires,
+ }
+ return True
+
+ def check_password(self, password):
+ config = self.config
+ if 'pwd_sha1' not in config.config:
+ log.debug('Failed to find config login details.')
+ return False
+
+ s = hashlib.sha1()
+ s.update(config['pwd_salt'].encode('utf8'))
+ s.update(password.encode('utf8'))
+ return s.hexdigest() == config['pwd_sha1']
+
+ def check_request(self, request, method=None, level=None):
+ """
+ Check to ensure that a request is authorised to call the specified
+ method of authentication level.
+
+ :param request: The HTTP request in question
+ :type request: twisted.web.http.Request
+ :param method: Check the specified method
+ :type method: function
+ :param level: Check the specified auth level
+ :type level: integer
+
+ :raises: Exception
+ """
+ cookie_sess_id = request.getCookie(b'_session_id')
+ if cookie_sess_id:
+ session_id = get_session_id(cookie_sess_id.decode())
+ else:
+ session_id = None
+
+ if session_id not in self.config['sessions']:
+ auth_level = AUTH_LEVEL_NONE
+ session_id = None
+ else:
+ session = self.config['sessions'][session_id]
+ auth_level = session['level']
+ expires, expires_str = make_expires(self.config['session_timeout'])
+ session['expires'] = expires
+
+ _session_id = request.getCookie(b'_session_id')
+ request.addCookie(
+ b'_session_id',
+ _session_id,
+ path=request.base + b'json',
+ expires=expires_str.encode('utf8'),
+ )
+
+ if method:
+ if not hasattr(method, '_json_export'):
+ raise Exception('Not an exported method')
+
+ method_level = getattr(method, '_json_auth_level')
+ if method_level is None:
+ raise Exception('Method has no auth level')
+
+ level = method_level
+
+ if level is None:
+ raise Exception('No level specified to check against')
+
+ request.auth_level = auth_level
+ request.session_id = session_id
+
+ if auth_level < level:
+ raise NotAuthorizedError(auth_level, level)
+
+ def _change_password(self, new_password):
+ """
+ Change the password. This is to allow the UI to change/reset a
+ password.
+
+ :param new_password: the password to change to
+ :type new_password: string
+ """
+ log.debug('Changing password')
+ salt = hashlib.sha1(os.urandom(32)).hexdigest()
+ s = hashlib.sha1(salt.encode('utf-8'))
+ s.update(new_password.encode('utf8'))
+ self.config['pwd_salt'] = salt
+ self.config['pwd_sha1'] = s.hexdigest()
+ return True
+
+ @export
+ def change_password(self, old_password, new_password):
+ """
+ Change the password.
+
+ :param old_password: the current password
+ :type old_password: string
+ :param new_password: the password to change to
+ :type new_password: string
+ """
+ if not self.check_password(old_password):
+ return False
+ return self._change_password(new_password)
+
+ @export(AUTH_LEVEL_NONE)
+ def check_session(self, session_id=None):
+ """
+ Check a session to see if it's still valid.
+
+ :returns: True if the session is valid, False if not.
+ :rtype: booleon
+ """
+ return __request__.session_id is not None
+
+ @export
+ def delete_session(self):
+ """
+ Removes a session.
+
+ :param session_id: the id for the session to remove
+ :type session_id: string
+ """
+ del self.config['sessions'][__request__.session_id]
+ return True
+
+ @export(AUTH_LEVEL_NONE)
+ def login(self, password):
+ """
+ Test a password to see if it's valid.
+
+ :param password: the password to test
+ :type password: string
+ :returns: a session id or False
+ :rtype: string or False
+ """
+ if self.check_password(password):
+ log.info('Login success (ClientIP %s)', __request__.getClientIP())
+ return self._create_session(__request__)
+ else:
+ log.error('Login failed (ClientIP %s)', __request__.getClientIP())
+ return False
diff --git a/deluge/ui/web/common.py b/deluge/ui/web/common.py
new file mode 100644
index 0000000..475f335
--- /dev/null
+++ b/deluge/ui/web/common.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import unicode_literals
+
+import gettext
+
+from mako.template import Template as MakoTemplate
+
+from deluge.common import PY2, get_version
+
+
+def _(text):
+ text_local = gettext.gettext(text)
+ if PY2:
+ return text_local.decode('utf-8')
+ return text_local
+
+
+def escape(text):
+ """
+ Used by gettext.js template to escape any translated language strings that
+ might contain newlines or quotes as they would break the script.
+ """
+ text = text.replace("'", "\\'")
+ text = text.replace('\r\n', '\\n')
+ text = text.replace('\r', '\\n')
+ text = text.replace('\n', '\\n')
+ return text
+
+
+class Template(MakoTemplate):
+ """
+ A template that adds some built-ins to the rendering
+ """
+
+ builtins = {'_': _, 'escape': escape, 'version': get_version()}
+
+ def render(self, *args, **data):
+ data.update(self.builtins)
+ rendered = MakoTemplate.render_unicode(self, *args, **data)
+ return rendered.encode('utf-8')
diff --git a/deluge/ui/web/css/deluge.css b/deluge/ui/web/css/deluge.css
new file mode 100644
index 0000000..b9fa03e
--- /dev/null
+++ b/deluge/ui/web/css/deluge.css
@@ -0,0 +1,568 @@
+html,
+body {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+ margin: 0;
+ padding: 0;
+ border: 0 none;
+ overflow: hidden;
+ height: 100%;
+}
+
+input {
+ color: Black;
+}
+
+/* remove dotted line on buttons in Firefox */
+button::-moz-focus-inner {
+ border: 0;
+}
+
+.x-deluge-main-panel {
+ background-image: url('../icons/deluge.png') !important;
+}
+
+.x-deluge-logo {
+ background-image: url('../ui_images/deluge-about.png');
+}
+
+#tbar-deluge-text * {
+ color: black !important;
+ font-weight: bold;
+}
+
+#tbar-deluge-text {
+ opacity: 1 !important;
+}
+
+.deluge-torrents td,
+.x-deluge-peers td {
+ height: 16px;
+ line-height: 16px;
+}
+
+.deluge-torrents .torrent-name,
+.x-deluge-peer,
+.x-deluge-seed {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+}
+
+.deluge-torrents .deluge-torrent-progress {
+ text-align: center;
+}
+
+/* Icon classes */
+.x-deluge-all {
+ background-image: url('../icons/all.png');
+}
+.x-deluge-active {
+ background-image: url('../icons/active.png');
+}
+.x-deluge-downloading,
+.x-btn .x-deluge-downloading,
+.x-deluge-peer {
+ background-image: url('../icons/downloading.png');
+}
+.x-deluge-seeding,
+.x-btn .x-deluge-seeding,
+.deluge-torrents .seeding,
+.x-deluge-seed {
+ background-image: url('../icons/seeding.png');
+}
+.x-deluge-queued,
+.x-btn .x-deluge-queued,
+.deluge-torrents .queued {
+ background-image: url('../icons/queued.png');
+}
+.x-deluge-paused,
+.x-btn .x-deluge-paused,
+.deluge-torrents .paused {
+ background-image: url('../icons/inactive.png');
+}
+.x-deluge-error,
+.deluge-torrents .error {
+ background-image: url('../icons/alert.png');
+}
+.x-deluge-checking,
+.deluge-torrents .checking {
+ background-image: url('../icons/checking.png');
+}
+.x-deluge-dht,
+.x-btn .x-deluge-dht {
+ background-image: url('../icons/dht.png');
+}
+.x-deluge-preferences,
+.x-btn .x-deluge-preferences {
+ background-image: url('../icons/preferences.png');
+}
+.x-deluge-connections,
+.x-btn .x-deluge-connections {
+ background-image: url('../icons/connections.png');
+}
+.x-deluge-connection-manager,
+.x-btn .x-deluge-connection-manager {
+ background-image: url('../icons/connection_manager.png');
+}
+.x-deluge-traffic,
+.x-btn .x-deluge-traffic {
+ background-image: url('../icons/traffic.png');
+}
+.x-deluge-edit-trackers,
+.x-btn .x-deluge-edit-trackers {
+ background-image: url('../icons/edit_trackers.png');
+}
+.x-deluge-freespace,
+.x-btn .x-deluge-freespace {
+ background-image: url('../icons/drive.png');
+}
+
+.x-deluge-install-plugin,
+.x-btn .x-deluge-install-plugin {
+ background-image: url('../icons/install_plugin.png');
+}
+.x-deluge-find-more,
+.x-btn .x-deluge-find-more {
+ background-image: url('../icons/find_more.png');
+}
+
+/* Torrent Details */
+#torrentDetails dl,
+#torrentDetails dl.singleline {
+ float: left;
+ min-height: 120px;
+}
+
+#torrentDetails dl dt,
+dl.singleline dt {
+ float: left;
+ font-weight: bold;
+ height: 19px;
+}
+
+#torrentDetails dl dd,
+dl.singleline dd {
+ margin-left: 100px;
+ width: 140px;
+ height: 19px;
+}
+
+dl.singleline {
+ float: left;
+}
+
+dl.singleline dt {
+ width: 80px;
+}
+
+dl.singleline dd {
+ margin-left: 85px;
+ width: auto;
+}
+
+.x-deluge-plugins {
+ background: White;
+}
+
+/* Torrent Details - Status Tab */
+.x-deluge-status-progressbar {
+ margin: 5px;
+}
+
+.x-deluge-status {
+ margin: 10px;
+}
+
+.x-deluge-status dd.downloaded,
+.x-deluge-status dd.uploaded,
+.x-deluge-status dd.share,
+.x-deluge-status dd.announce,
+.x-deluge-status dd.tracker_status {
+ width: 200px;
+ margin-left: 100px;
+}
+
+.x-deluge-status dd.downspeed,
+.x-deluge-status dd.upspeed,
+.x-deluge-status dd.eta,
+.x-deluge-status dd.pieces {
+ margin-left: 100px;
+}
+
+.x-deluge-status dd.active_time,
+.x-deluge-status dd.seeding_time,
+.x-deluge-status dd.seed_rank,
+.x-deluge-status dd.time_added {
+ width: 100px;
+}
+.x-deluge-status dd.last_seen_complete {
+ width: 100px;
+}
+
+/* Torrent Details - Details Tab */
+#torrentDetails dd.torrent_name,
+#torrentDetails dd.status,
+#torrentDetails dd.tracker,
+#torrentDetails dd.path,
+#torrentDetails dd.comment {
+ width: auto;
+}
+
+.detailsPanel .x-panel-header {
+ height: 0;
+ padding: 0;
+ border: 0;
+}
+
+.detailsPanel .x-tool {
+ height: 15px;
+ z-index: 1;
+ position: fixed;
+ right: 0;
+ margin: 5px 10px;
+}
+
+/* Login Window */
+.x-deluge-login-window-icon {
+ background: url('../icons/login.png') no-repeat 2px;
+}
+
+/* Remove Window */
+.x-deluge-remove-window-icon {
+ background: url('../icons/remove.png') no-repeat 2px;
+}
+
+/* Add Window */
+.x-deluge-add-window-icon {
+ background: url('../icons/add.png') no-repeat 2px;
+}
+
+.x-deluge-add-torrent-name {
+ line-height: 20px;
+}
+
+.x-deluge-add-torrent-name-loading {
+ padding-left: 20px;
+ line-height: 20px;
+ background: url('/themes/default/tree/loading.gif') no-repeat 2px;
+}
+
+/* Add Url Window */
+.x-deluge-add-file,
+.x-btn .x-deluge-add-file {
+ background: url('../icons/add_file.png') no-repeat 2px;
+}
+
+.x-deluge-add-url-window-icon {
+ background: url('../icons/add_url.png') no-repeat 2px;
+}
+
+/* Connect Window */
+.x-deluge-connect-window-icon {
+ background: url('../icons/connection_manager.png') no-repeat 2px;
+}
+
+/* Statusbar */
+.x-deluge-statusbar {
+ background: no-repeat 2px !important;
+ padding-left: 20px !important;
+}
+
+.x-not-connected {
+ background-image: url('../icons/error.png') !important;
+}
+
+.x-connected {
+ background-image: none !important;
+}
+
+/* Styles for renderered progress bars */
+.x-progress-renderered .x-progress-bar {
+ height: 16px;
+}
+
+.x-progress-renderered .x-progress-bar .x-progress-text {
+ margin-top: -1px;
+ height: 18px;
+}
+
+/* Adjust progressbar for torrent files tree */
+.x-tree .x-progress-wrap {
+ width: 100px;
+}
+
+.x-tree .x-progress-renderered .x-progress-inner {
+ height: 12px;
+}
+
+.x-tree .x-progress-renderered .x-progress-bar {
+ height: 12px;
+}
+
+.x-tree .x-progress-renderered .x-progress-text {
+ vertical-align: top;
+ height: 12px;
+ font-size: 11px;
+ font-weight: normal;
+ padding: 0px;
+ margin-top: 0px;
+}
+
+.x-tree .x-progress-renderered .x-progress-bar .x-progress-text {
+ margin-top: 0px;
+}
+
+/* Files TreeGrid */
+.x-treegrid-root-table {
+ border-right: 1px solid;
+}
+
+.x-treegrid-root-node {
+ overflow: auto;
+}
+
+.x-treegrid-hd-hidden {
+ visibility: hidden;
+ border: 0;
+ width: 0;
+}
+
+.x-treegrid-col {
+ border-bottom: 1px solid;
+ height: 20px;
+ overflow: hidden;
+ vertical-align: top;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.x-treegrid-text {
+ padding-left: 4px;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+}
+
+.x-treegrid-resizer {
+ border-left: 1px solid;
+ border-right: 1px solid;
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+
+.x-treegrid-header-inner {
+ overflow: hidden;
+}
+
+.x-treegrid-root-table,
+.x-treegrid-col {
+ border-color: #ededed;
+}
+
+.x-treegrid-resizer {
+ border-left-color: #555;
+ border-right-color: #555;
+}
+
+/* Options Tab Styles */
+.x-deluge-options-label {
+ margin-right: 10px;
+}
+
+.x-deluge-indent-checkbox {
+ padding-left: 10px;
+}
+
+/* Sidebar styles */
+#sidebar .x-grid3-col-filter {
+ height: 16px;
+ line-height: 16px;
+ padding: 2px;
+ cursor: pointer;
+}
+
+#sidebar .x-deluge-filter {
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: left;
+ padding-left: 20px;
+ line-height: 16px;
+}
+
+#sidebar .x-list-selected em {
+ font-weight: bold;
+}
+
+/* MessageBox icon styles */
+.x-deluge-icon-warning {
+ background: url('../icons/warning.png') no-repeat 2px;
+}
+
+.x-deluge-icon-error {
+ background: url('../icons/error.png') no-repeat 2px;
+}
+
+.x-tree-node-leaf .x-deluge-file {
+ background-image: url('../icons/document.png');
+}
+
+.x-deluge-add-file-checkbox {
+ margin-top: 2px;
+}
+
+/* Filepriority styles */
+.x-no-download,
+.x-low-download,
+.x-normal-download,
+.x-high-download,
+.x-mixed-download {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ line-height: 16px;
+}
+
+.x-no-download {
+ background-image: url(../icons/no_download.png);
+}
+
+.x-low-download {
+ background-image: url(../icons/low.png);
+}
+
+.x-normal-download {
+ background-image: url(../icons/normal.png);
+}
+
+.x-high-download {
+ background-image: url(../icons/high.png);
+}
+
+.x-mixed-download {
+ /*background-image: url(../icons/mixed.png);*/
+}
+
+/**
+ * Deluge Default Icon Set
+ * n.b. this needs to be forked out at some point
+ */
+
+.icon-create {
+ background-image: url('../icons/create.png') !important;
+}
+
+.icon-add {
+ background-image: url('../icons/add.png') !important;
+}
+
+.icon-add-url {
+ background-image: url('../icons/add_url.png') !important;
+}
+
+.icon-add-magnet {
+ background-image: url('../icons/add_magnet.png') !important;
+}
+
+.icon-pause {
+ background-image: url('../icons/pause.png') !important;
+}
+
+.icon-resume {
+ background-image: url('../icons/start.png') !important;
+}
+
+.icon-options {
+ background-image: url('../icons/preferences.png') !important;
+}
+
+.icon-queue {
+ background-image: url('../icons/queue.png') !important;
+}
+
+.icon-top {
+ background-image: url('../icons/top.png') !important;
+}
+
+.icon-up {
+ background-image: url('../icons/up.png') !important;
+}
+
+.icon-down {
+ background-image: url('../icons/down.png') !important;
+}
+
+.icon-bottom {
+ background-image: url('../icons/bottom.png') !important;
+}
+
+.icon-update-tracker {
+ background-image: url('../icons/update.png') !important;
+}
+
+.icon-edit-trackers,
+.icon-edit {
+ background-image: url('../icons/edit_trackers.png') !important;
+}
+
+.icon-remove {
+ background-image: url('../icons/remove.png') !important;
+}
+
+.icon-recheck {
+ background-image: url('../icons/recheck.png') !important;
+}
+
+.icon-move {
+ background-image: url('../icons/move.png') !important;
+}
+
+.icon-help {
+ background-image: url('../icons/help.png') !important;
+}
+
+.icon-logout {
+ background-image: url('../icons/logout.png') !important;
+}
+
+.icon-back {
+ background-image: url('../icons/back.png') !important;
+}
+
+.icon-forward {
+ background-image: url('../icons/forward.png') !important;
+}
+
+.icon-home {
+ background-image: url('../icons/home.png') !important;
+}
+
+.icon-ok {
+ background-image: url('../icons/ok.png') !important;
+}
+
+.icon-error {
+ background-image: url('../icons/error.png') !important;
+}
+
+.icon-upload-slots {
+ background-image: url('../icons/upload_slots.png') !important;
+}
+
+.icon-expand-all {
+ background-image: url('../icons/expand_all.png') !important;
+}
+
+.icon-do-not-download {
+ background-image: url('../icons/no_download.png') !important;
+}
+
+.icon-low {
+ background-image: url('../icons/low.png') !important;
+}
+
+.icon-normal {
+ background-image: url('../icons/normal.png') !important;
+}
+
+.icon-high {
+ background-image: url('../icons/high.png') !important;
+}
diff --git a/deluge/ui/web/css/ext-all-notheme.css b/deluge/ui/web/css/ext-all-notheme.css
new file mode 100644
index 0000000..40bac82
--- /dev/null
+++ b/deluge/ui/web/css/ext-all-notheme.css
@@ -0,0 +1,5349 @@
+/*
+This file is part of Ext JS 3.4
+
+Copyright (c) 2011-2013 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as
+published by the Free Software Foundation and appearing in the file LICENSE included in the
+packaging of this file.
+
+Please review the following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department
+at http://www.sencha.com/contact.
+
+Build date: 2013-04-03 15:07:25
+*/
+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-forced-border-box, .ext-forced-border-box * {
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+.ext-el-mask {
+ z-index: 100;
+ position: absolute;
+ top:0;
+ left:0;
+ -moz-opacity: 0.5;
+ opacity: .50;
+ filter: alpha(opacity=50);
+ width: 100%;
+ height: 100%;
+ zoom: 1;
+}
+
+.ext-el-mask-msg {
+ z-index: 20001;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border:1px solid;
+ background:repeat-x 0 -16px;
+ padding:2px;
+}
+
+.ext-el-mask-msg div {
+ padding:5px 10px 5px 10px;
+ border:1px solid;
+ cursor:wait;
+}
+
+.ext-shim {
+ position:absolute;
+ visibility:hidden;
+ left:0;
+ top:0;
+ overflow:hidden;
+}
+
+.ext-ie .ext-shim {
+ filter: alpha(opacity=0);
+}
+
+.ext-ie6 .ext-shim {
+ margin-left: 5px;
+ margin-top: 3px;
+}
+
+.x-mask-loading div {
+ padding:5px 10px 5px 25px;
+ background:no-repeat 5px 5px;
+ line-height:16px;
+}
+
+/* class for hiding elements without using display:none */
+.x-hidden, .x-hide-offsets {
+ position:absolute !important;
+ left:-10000px;
+ top:-10000px;
+ visibility:hidden;
+}
+
+.x-hide-display {
+ display:none !important;
+}
+
+.x-hide-nosize,
+.x-hide-nosize * /* Emulate display:none for children */
+ {
+ height:0px!important;
+ width:0px!important;
+ visibility:hidden!important;
+ border:none!important;
+ zoom:1;
+}
+
+.x-hide-visibility {
+ visibility:hidden !important;
+}
+
+.x-masked {
+ overflow: hidden !important;
+}
+.x-masked-relative {
+ position: relative !important;
+}
+
+.x-masked select, .x-masked object, .x-masked embed {
+ visibility: hidden;
+}
+
+.x-layer {
+ visibility: hidden;
+}
+
+.x-unselectable, .x-unselectable * {
+ user-select: none;
+ -o-user-select: none;
+ -ms-user-select: none;
+ -moz-user-select: -moz-none;
+ -webkit-user-select: none;
+ cursor:default;
+}
+
+.x-repaint {
+ zoom: 1;
+ background-color: transparent;
+ -moz-outline: none;
+ outline: none;
+}
+
+.x-item-disabled {
+ cursor: default;
+ opacity: .6;
+ -moz-opacity: .6;
+ filter: alpha(opacity=60);
+}
+
+.x-item-disabled * {
+ cursor: default !important;
+}
+
+.x-form-radio-group .x-item-disabled {
+ filter: none;
+}
+
+.x-splitbar-proxy {
+ position: absolute;
+ visibility: hidden;
+ z-index: 20001;
+ 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;
+ cursor: pointer;
+}
+
+.x-color-palette a {
+ border: 1px solid;
+ float: left;
+ padding: 2px;
+ text-decoration: none;
+ -moz-outline: 0 none;
+ outline: 0 none;
+ cursor: pointer;
+}
+
+.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel {
+ border: 1px solid;
+}
+
+.x-color-palette em {
+ display: block;
+ border: 1px solid;
+}
+
+.x-color-palette em span {
+ cursor: pointer;
+ display: block;
+ height: 10px;
+ line-height: 10px;
+ width: 10px;
+}
+
+.x-ie-shadow {
+ display: none;
+ position: absolute;
+ overflow: hidden;
+ left:0;
+ top:0;
+ zoom:1;
+}
+
+.x-shadow {
+ display: none;
+ position: absolute;
+ overflow: hidden;
+ left:0;
+ top:0;
+}
+
+.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-color: transparent;
+}
+
+.x-shadow .xst, .x-shadow .xsb {
+ height: 6px;
+ overflow: hidden;
+ width: 100%;
+}
+
+.x-shadow .xsml {
+ background: transparent repeat-y 0 0;
+}
+
+.x-shadow .xsmr {
+ background: transparent repeat-y -6px 0;
+}
+
+.x-shadow .xstl {
+ background: transparent no-repeat 0 0;
+}
+
+.x-shadow .xstc {
+ background: transparent repeat-x 0 -30px;
+}
+
+.x-shadow .xstr {
+ background: transparent repeat-x 0 -18px;
+}
+
+.x-shadow .xsbl {
+ background: transparent no-repeat 0 -12px;
+}
+
+.x-shadow .xsbc {
+ background: transparent repeat-x 0 -36px;
+}
+
+.x-shadow .xsbr {
+ background: transparent repeat-x 0 -6px;
+}
+
+.loading-indicator {
+ background: no-repeat 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-image:url(../images/default/s.gif);
+ z-index: 20000;
+}
+
+.x-clear {
+ clear:both;
+ height:0;
+ overflow:hidden;
+ line-height:0;
+ font-size:0;
+}
+
+.x-spotlight {
+ z-index: 8999;
+ position: absolute;
+ top:0;
+ left:0;
+ -moz-opacity: 0.5;
+ opacity: .50;
+ filter: alpha(opacity=50);
+ width:0;
+ height:0;
+ zoom: 1;
+}
+
+#x-history-frame {
+ position:absolute;
+ top:-1px;
+ left:0;
+ width:1px;
+ height:1px;
+ visibility:hidden;
+}
+
+#x-history-field {
+ position:absolute;
+ top:0;
+ left:-1px;
+ width:1px;
+ height:1px;
+ visibility:hidden;
+}
+.x-resizable-handle {
+ position:absolute;
+ z-index:100;
+ /* ie needs these */
+ font-size:1px;
+ line-height:6px;
+ overflow:hidden;
+ 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,
+.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west
+{
+ background-position: left;
+}
+
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north
+{
+ background-position: top;
+}
+
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+ background-position: top left;
+}
+
+.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{
+ background-position:bottom right;
+}
+
+.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{
+ background-position: bottom left;
+}
+
+.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{
+ background-position: top right;
+}
+
+.x-resizable-proxy{
+ border: 1px dashed;
+ position:absolute;
+ overflow:hidden;
+ display:none;
+ left:0;
+ top:0;
+ z-index:50000;
+}
+
+.x-resizable-overlay{
+ width:100%;
+ height:100%;
+ display:none;
+ position:absolute;
+ left:0;
+ top:0;
+ z-index:200000;
+ -moz-opacity: 0;
+ opacity:0;
+ filter: alpha(opacity=0);
+}
+.x-tab-panel {
+ overflow:hidden;
+}
+
+.x-tab-panel-header, .x-tab-panel-footer {
+ border: 1px solid;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-tab-panel-header {
+ border: 1px solid;
+ padding-bottom: 2px;
+}
+
+.x-tab-panel-footer {
+ border: 1px solid;
+ padding-top: 2px;
+}
+
+.x-tab-strip-wrap {
+ width:100%;
+ overflow:hidden;
+ position:relative;
+ zoom:1;
+}
+
+ul.x-tab-strip {
+ display:block;
+ width:5000px;
+ zoom:1;
+}
+
+ul.x-tab-strip-top{
+ padding-top: 1px;
+ background: repeat-x bottom;
+ border-bottom: 1px solid;
+}
+
+ul.x-tab-strip-bottom{
+ padding-bottom: 1px;
+ background: repeat-x top;
+ border-top: 1px solid;
+ border-bottom: 0 none;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-top {
+ background:transparent !important;
+ padding-top:0 !important;
+}
+
+.x-tab-panel-header-plain {
+ background:transparent !important;
+ border-width:0 !important;
+ padding-bottom:0 !important;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+ border:1px solid;
+ height:2px;
+ font-size:1px;
+ line-height:1px;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer {
+ border-top: 0 none;
+}
+
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+ border-bottom: 0 none;
+}
+
+.x-tab-panel-footer-plain .x-tab-strip-bottom {
+ background:transparent !important;
+ padding-bottom:0 !important;
+}
+
+.x-tab-panel-footer-plain {
+ background:transparent !important;
+ border-width:0 !important;
+ padding-top:0 !important;
+}
+
+.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer,
+.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer {
+ height:3px;
+}
+
+ul.x-tab-strip li {
+ float:left;
+ margin-left:2px;
+}
+
+ul.x-tab-strip li.x-tab-edge {
+ float:left;
+ margin:0 !important;
+ padding:0 !important;
+ border:0 none !important;
+ font-size:1px !important;
+ line-height:1px !important;
+ overflow:hidden;
+ zoom:1;
+ background:transparent !important;
+ width:1px;
+}
+
+.x-tab-strip a, .x-tab-strip span, .x-tab-strip em {
+ display:block;
+}
+
+.x-tab-strip a {
+ text-decoration:none !important;
+ -moz-outline: none;
+ outline: none;
+ cursor:pointer;
+}
+
+.x-tab-strip-inner {
+ overflow:hidden;
+ text-overflow: ellipsis;
+}
+
+.x-tab-strip span.x-tab-strip-text {
+ white-space: nowrap;
+ cursor:pointer;
+ padding:4px 0;
+}
+
+.x-tab-strip-top .x-tab-with-icon .x-tab-right {
+ padding-left:6px;
+}
+
+.x-tab-strip .x-tab-with-icon span.x-tab-strip-text {
+ padding-left:20px;
+ background-position: 0 3px;
+ background-repeat: no-repeat;
+}
+
+.x-tab-strip-active, .x-tab-strip-active a.x-tab-right {
+ cursor:default;
+}
+
+.x-tab-strip-active span.x-tab-strip-text {
+ cursor:default;
+}
+
+.x-tab-strip-disabled .x-tabs-text {
+ cursor:default;
+}
+
+.x-tab-panel-body {
+ overflow:hidden;
+}
+
+.x-tab-panel-bwrap {
+ overflow:hidden;
+}
+
+.ext-ie .x-tab-strip .x-tab-right {
+ position:relative;
+}
+
+.x-tab-strip-top .x-tab-strip-active .x-tab-right {
+ margin-bottom:-1px;
+}
+
+/*
+ * For IE8/9 in quirks mode
+ */
+.ext-ie8 .x-tab-strip li {
+ position: relative;
+}
+.ext-border-box .ext-ie8 .x-tab-strip-top .x-tab-right, .ext-border-box .ext-ie9 .x-tab-strip-top .x-tab-right {
+ top: 1px;
+}
+.ext-ie8 .x-tab-strip-top, .ext-ie9 .x-tab-strip-top {
+ padding-top: 1px;
+}
+.ext-border-box .ext-ie8 .x-tab-strip-top, .ext-border-box .ext-ie9 .x-tab-strip-top {
+ padding-top: 0;
+}
+.ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close, .ext-ie9 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ top:3px;
+}
+.ext-border-box .ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close,
+.ext-border-box .ext-ie9 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ top:4px;
+}
+.ext-ie8 .x-tab-strip-bottom .x-tab-right, .ext-ie9 .x-tab-strip-bottom .x-tab-right{
+ top:0;
+}
+
+
+.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text {
+ padding-bottom:5px;
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+ margin-top:-1px;
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text {
+ padding-top:5px;
+}
+
+.x-tab-strip-top .x-tab-right {
+ background: transparent no-repeat 0 -51px;
+ padding-left:10px;
+}
+
+.x-tab-strip-top .x-tab-left {
+ background: transparent no-repeat right -351px;
+ padding-right:10px;
+}
+
+.x-tab-strip-top .x-tab-strip-inner {
+ background: transparent repeat-x 0 -201px;
+}
+
+.x-tab-strip-top .x-tab-strip-over .x-tab-right {
+ background-position:0 -101px;
+}
+
+.x-tab-strip-top .x-tab-strip-over .x-tab-left {
+ background-position:right -401px;
+}
+
+.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner {
+ background-position:0 -251px;
+}
+
+.x-tab-strip-top .x-tab-strip-active .x-tab-right {
+ background-position: 0 0;
+}
+
+.x-tab-strip-top .x-tab-strip-active .x-tab-left {
+ background-position: right -301px;
+}
+
+.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner {
+ background-position: 0 -151px;
+}
+
+.x-tab-strip-bottom .x-tab-right {
+ background: no-repeat bottom right;
+}
+
+.x-tab-strip-bottom .x-tab-left {
+ background: no-repeat bottom left;
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+ background: no-repeat bottom right;
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+ background: no-repeat bottom left;
+}
+
+.x-tab-strip-bottom .x-tab-left {
+ margin-right: 3px;
+ padding:0 10px;
+}
+
+.x-tab-strip-bottom .x-tab-right {
+ padding:0;
+}
+
+.x-tab-strip .x-tab-strip-close {
+ display:none;
+}
+
+.x-tab-strip-closable {
+ position:relative;
+}
+
+.x-tab-strip-closable .x-tab-left {
+ padding-right:19px;
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ opacity:.6;
+ -moz-opacity:.6;
+ background-repeat:no-repeat;
+ display:block;
+ width:11px;
+ height:11px;
+ position:absolute;
+ top:3px;
+ right:3px;
+ cursor:pointer;
+ z-index:2;
+}
+
+.x-tab-strip .x-tab-strip-active a.x-tab-strip-close {
+ opacity:.8;
+ -moz-opacity:.8;
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{
+ opacity:1;
+ -moz-opacity:1;
+}
+
+.x-tab-panel-body {
+ border: 1px solid;
+}
+
+.x-tab-panel-body-top {
+ border-top: 0 none;
+}
+
+.x-tab-panel-body-bottom {
+ border-bottom: 0 none;
+}
+
+.x-tab-scroller-left {
+ background: transparent no-repeat -18px 0;
+ border-bottom: 1px solid;
+ width:18px;
+ position:absolute;
+ left:0;
+ top:0;
+ z-index:10;
+ cursor:pointer;
+}
+.x-tab-scroller-left-over {
+ background-position: 0 0;
+}
+
+.x-tab-scroller-left-disabled {
+ background-position: -18px 0;
+ opacity:.5;
+ -moz-opacity:.5;
+ filter:alpha(opacity=50);
+ cursor:default;
+}
+
+.x-tab-scroller-right {
+ background: transparent no-repeat 0 0;
+ border-bottom: 1px solid;
+ width:18px;
+ position:absolute;
+ right:0;
+ top:0;
+ z-index:10;
+ cursor:pointer;
+}
+
+.x-tab-scroller-right-over {
+ background-position: -18px 0;
+}
+
+.x-tab-scroller-right-disabled {
+ background-position: 0 0;
+ opacity:.5;
+ -moz-opacity:.5;
+ filter:alpha(opacity=50);
+ cursor:default;
+}
+
+.x-tab-scrolling-bottom .x-tab-scroller-left, .x-tab-scrolling-bottom .x-tab-scroller-right{
+ margin-top: 1px;
+}
+
+.x-tab-scrolling .x-tab-strip-wrap {
+ margin-left:18px;
+ margin-right:18px;
+}
+
+.x-tab-scrolling {
+ position:relative;
+}
+
+.x-tab-panel-bbar .x-toolbar {
+ border:1px solid;
+ border-top:0 none;
+ overflow:hidden;
+ padding:2px;
+}
+
+.x-tab-panel-tbar .x-toolbar {
+ border:1px solid;
+ border-top:0 none;
+ overflow:hidden;
+ padding:2px;
+}/* all fields */
+.x-form-field{
+ margin: 0 0 0 0;
+}
+
+.ext-webkit *:focus{
+ outline: none !important;
+}
+
+/* ---- text fields ---- */
+.x-form-text, textarea.x-form-field{
+ padding:1px 3px;
+ background:repeat-x 0 0;
+ border:1px solid;
+}
+
+textarea.x-form-field {
+ padding:2px 3px;
+}
+
+.x-form-text, .ext-ie .x-form-file {
+ height:22px;
+ line-height:18px;
+ vertical-align:middle;
+}
+
+.ext-ie6 .x-form-text, .ext-ie7 .x-form-text {
+ margin:-1px 0; /* ie bogus margin bug */
+ height:22px; /* ie quirks */
+ line-height:18px;
+}
+
+.x-quirks .ext-ie9 .x-form-text {
+ height: 22px;
+ padding-top: 3px;
+ padding-bottom: 0px;
+}
+
+/* Ugly hacks for the bogus 1px margin bug in IE9 quirks */
+.x-quirks .ext-ie9 .x-input-wrapper .x-form-text,
+.x-quirks .ext-ie9 .x-form-field-trigger-wrap .x-form-text {
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+.x-quirks .ext-ie9 .x-input-wrapper .x-form-element {
+ margin-bottom: -1px;
+}
+
+.ext-ie6 .x-form-field-wrap .x-form-file-btn, .ext-ie7 .x-form-field-wrap .x-form-file-btn {
+ top: -1px; /* because of all these margin hacks, these buttons are off by one pixel in IE6,7 */
+}
+
+.ext-ie6 textarea.x-form-field, .ext-ie7 textarea.x-form-field {
+ margin:-1px 0; /* ie bogus margin bug */
+}
+
+.ext-strict .x-form-text {
+ height:18px;
+}
+
+.ext-safari.ext-mac textarea.x-form-field {
+ margin-bottom:-2px; /* another bogus margin bug, safari/mac only */
+}
+
+/*
+.ext-strict .ext-ie8 .x-form-text, .ext-strict .ext-ie8 textarea.x-form-field {
+ margin-bottom: 1px;
+}
+*/
+
+.ext-gecko .x-form-text , .ext-ie8 .x-form-text {
+ padding-top:2px; /* FF won't center the text vertically */
+ padding-bottom:0;
+}
+
+.ext-ie6 .x-form-composite .x-form-text.x-box-item, .ext-ie7 .x-form-composite .x-form-text.x-box-item {
+ margin: 0 !important; /* clear ie bogus margin bug fix */
+}
+
+textarea {
+ resize: none; /* Disable browser resizable textarea */
+}
+
+/* select boxes */
+.x-form-select-one {
+ height:20px;
+ line-height:18px;
+ vertical-align:middle;
+ border: 1px solid;
+}
+
+/* multi select boxes */
+
+/* --- TODO --- */
+
+/* 2.0.2 style */
+.x-form-check-wrap {
+ line-height:18px;
+ height: auto;
+}
+
+.ext-ie .x-form-check-wrap input {
+ width:15px;
+ height:15px;
+}
+
+.x-form-check-wrap input{
+ vertical-align: bottom;
+}
+
+.x-editor .x-form-check-wrap {
+ padding:3px;
+}
+
+.x-editor .x-form-checkbox {
+ height:13px;
+}
+
+.x-form-check-group-label {
+ border-bottom: 1px solid;
+ margin-bottom: 5px;
+ padding-left: 3px !important;
+ float: none !important;
+}
+
+/* wrapped fields and triggers */
+.x-form-field-wrap .x-form-trigger{
+ width:17px;
+ height:21px;
+ border:0;
+ background:transparent no-repeat 0 0;
+ cursor:pointer;
+ border-bottom: 1px solid;
+ position:absolute;
+ top:0;
+}
+
+.x-form-field-wrap .x-form-date-trigger, .x-form-field-wrap .x-form-clear-trigger, .x-form-field-wrap .x-form-search-trigger{
+ cursor:pointer;
+}
+
+.x-form-field-wrap .x-form-twin-triggers .x-form-trigger{
+ position:static;
+ top:auto;
+ vertical-align:top;
+}
+
+.x-form-field-wrap {
+ position:relative;
+ left:0;top:0;
+ text-align: left;
+ zoom:1;
+ white-space: nowrap;
+}
+
+.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-trigger {
+ right: 0; /* IE8 Strict mode trigger bug */
+}
+
+.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-trigger-wrap-focus .x-form-trigger{
+ background-position:-51px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger-over{
+ background-position:-68px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger-click{
+ background-position:-85px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger{
+ border-bottom: 1px solid;
+}
+
+.x-item-disabled .x-form-trigger-over{
+ background-position:0 0 !important;
+ border-bottom: 1px solid;
+}
+
+.x-item-disabled .x-form-trigger-click{
+ background-position:0 0 !important;
+ border-bottom: 1px solid;
+}
+
+.x-trigger-noedit{
+ cursor:pointer;
+}
+
+/* field focus style */
+.x-form-focus, textarea.x-form-focus{
+ border: 1px solid;
+}
+
+/* invalid fields */
+.x-form-invalid, textarea.x-form-invalid{
+ background:repeat-x bottom;
+ border: 1px solid;
+}
+
+.x-form-inner-invalid, textarea.x-form-inner-invalid{
+ background:repeat-x bottom;
+}
+
+/* editors */
+.x-editor {
+ visibility:hidden;
+ padding:0;
+ margin:0;
+}
+
+.x-form-grow-sizer {
+ 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-grow-sizer p {
+ margin:0 !important;
+ border:0 none !important;
+ padding:0 !important;
+}
+
+/* Form Items CSS */
+
+.x-form-item {
+ display:block;
+ margin-bottom:4px;
+ zoom:1;
+}
+
+.x-form-item label.x-form-item-label {
+ display:block;
+ float:left;
+ width:100px;
+ padding:3px;
+ padding-left:0;
+ clear:left;
+ z-index:2;
+ position:relative;
+}
+
+.x-form-element {
+ padding-left:105px;
+ position:relative;
+}
+
+.x-form-invalid-msg {
+ padding:2px;
+ padding-left:18px;
+ background: transparent no-repeat 0 2px;
+ line-height:16px;
+ width:200px;
+}
+
+.x-form-label-left label.x-form-item-label {
+ text-align:left;
+}
+
+.x-form-label-right label.x-form-item-label {
+ text-align:right;
+}
+
+.x-form-label-top .x-form-item label.x-form-item-label {
+ width:auto;
+ float:none;
+ clear:none;
+ display:inline;
+ margin-bottom:4px;
+ position:static;
+}
+
+.x-form-label-top .x-form-element {
+ padding-left:0;
+ padding-top:4px;
+}
+
+.x-form-label-top .x-form-item {
+ padding-bottom:4px;
+}
+
+/* Editor small font for grid, toolbar and tree */
+.x-small-editor .x-form-text {
+ height:20px;
+ line-height:16px;
+ vertical-align:middle;
+}
+
+.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .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-ie6 .x-small-editor .x-form-text, .ext-ie7 .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;
+}
+
+.ext-webkit .x-small-editor .x-form-text{padding-top:3px;font-size:100%;}
+
+.ext-strict .ext-webkit .x-small-editor .x-form-text{
+ height:14px !important;
+}
+
+.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;
+}
+
+.ext-ie6 .x-form-check-wrap input, .ext-border-box .x-form-check-wrap input{
+ margin-top: 3px;
+}
+
+.x-form-cb-label {
+ position: relative;
+ margin-left:4px;
+ top: 2px;
+}
+
+.ext-ie .x-form-cb-label{
+ top: 1px;
+}
+
+.ext-ie6 .x-form-cb-label, .ext-border-box .x-form-cb-label{
+ top: 3px;
+}
+
+.x-form-display-field{
+ padding-top: 2px;
+}
+
+.ext-gecko .x-form-display-field, .ext-strict .ext-ie7 .x-form-display-field{
+ padding-top: 1px;
+}
+
+.ext-ie .x-form-display-field{
+ padding-top: 3px;
+}
+
+.ext-strict .ext-ie8 .x-form-display-field{
+ padding-top: 0;
+}
+
+.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 .x-form-btns-ct .x-btn-focus .x-btn-left{
+ background-position:0 -147px;
+}
+
+.x-form .x-form-btns-ct .x-btn-focus .x-btn-right{
+ background-position:0 -168px;
+}
+
+.x-form .x-form-btns-ct .x-btn-focus .x-btn-center{
+ background-position:0 -189px;
+}
+
+.x-form .x-form-btns-ct .x-btn-click .x-btn-center{
+ background-position:0 -126px;
+}
+
+.x-form .x-form-btns-ct .x-btn-click .x-btn-right{
+ background-position:0 -84px;
+}
+
+.x-form .x-form-btns-ct .x-btn-click .x-btn-left{
+ background-position:0 -63px;
+}
+
+.x-form-invalid-icon {
+ width:16px;
+ height:18px;
+ visibility:hidden;
+ position:absolute;
+ left:0;
+ top:0;
+ display:block;
+ background:transparent no-repeat 0 2px;
+}
+
+/* fieldsets */
+.x-fieldset {
+ border:1px solid;
+ padding:10px;
+ margin-bottom:10px;
+ display:block; /* preserve margins in IE */
+}
+
+/* make top of checkbox/tools visible in webkit */
+.ext-webkit .x-fieldset-header {
+ padding-top: 1px;
+}
+
+.ext-ie .x-fieldset legend {
+ margin-bottom:10px;
+}
+
+.ext-strict .ext-ie9 .x-fieldset legend.x-fieldset-header {
+ padding-top: 1px;
+}
+
+.ext-ie .x-fieldset {
+ padding-top: 0;
+ padding-bottom:10px;
+}
+
+.x-fieldset legend .x-tool-toggle {
+ margin-right:3px;
+ margin-left:0;
+ float:left !important;
+}
+
+.x-fieldset legend input {
+ margin-right:3px;
+ float:left !important;
+ height:13px;
+ width:13px;
+}
+
+fieldset.x-panel-collapsed {
+ padding-bottom:0 !important;
+ border-width: 1px 1px 0 1px !important;
+ border-left-color: transparent;
+ border-right-color: transparent;
+}
+
+.ext-ie6 fieldset.x-panel-collapsed{
+ padding-bottom:0 !important;
+ border-width: 1px 0 0 0 !important;
+ margin-left: 1px;
+ margin-right: 1px;
+}
+
+fieldset.x-panel-collapsed .x-fieldset-bwrap {
+ visibility:hidden;
+ position:absolute;
+ left:-1000px;
+ top:-1000px;
+}
+
+.ext-ie .x-fieldset-bwrap {
+ zoom:1;
+}
+
+.x-fieldset-noborder {
+ border:0px none transparent;
+}
+
+.x-fieldset-noborder legend {
+ margin-left:-3px;
+}
+
+/* IE legend positioning bug */
+.ext-ie .x-fieldset-noborder legend {
+ position: relative;
+ margin-bottom:23px;
+}
+.ext-ie .x-fieldset-noborder legend span {
+ position: absolute;
+ left:16px;
+}
+
+.ext-gecko .x-window-body .x-form-item {
+ -moz-outline: none;
+ outline: none;
+ overflow: auto;
+}
+
+.ext-mac.ext-gecko .x-window-body .x-form-item {
+ overflow:hidden;
+}
+
+.ext-gecko .x-form-item {
+ -moz-outline: none;
+ outline: none;
+}
+
+.x-hide-label label.x-form-item-label {
+ display:none;
+}
+
+.x-hide-label .x-form-element {
+ padding-left: 0 !important;
+}
+
+.x-form-label-top .x-hide-label label.x-form-item-label{
+ display: none;
+}
+
+.x-fieldset {
+ overflow:hidden;
+}
+
+.x-fieldset-bwrap {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-fieldset-body {
+ overflow:hidden;
+}
+.x-btn{
+ cursor:pointer;
+ white-space: nowrap;
+}
+
+.x-btn button{
+ border:0 none;
+ background-color:transparent;
+ 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, .ext-webkit .x-btn button {
+ padding-left:0;
+ padding-right:0;
+}
+
+.ext-gecko .x-btn button::-moz-focus-inner {
+ padding:0;
+}
+
+.ext-ie .x-btn button {
+ padding-top:2px;
+}
+
+.x-btn td {
+ padding:0 !important;
+}
+
+.x-btn-text {
+ cursor:pointer;
+ white-space: nowrap;
+ padding:0;
+}
+
+/* icon placement and sizing styles */
+
+/* Only text */
+.x-btn-noicon .x-btn-small .x-btn-text{
+ height: 16px;
+}
+
+.x-btn-noicon .x-btn-medium .x-btn-text{
+ height: 24px;
+}
+
+.x-btn-noicon .x-btn-large .x-btn-text{
+ height: 32px;
+}
+
+/* Only icons */
+.x-btn-icon .x-btn-text{
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+.x-btn-icon .x-btn-small .x-btn-text{
+ height: 16px;
+ width: 16px;
+}
+
+.x-btn-icon .x-btn-medium .x-btn-text{
+ height: 24px;
+ width: 24px;
+}
+
+.x-btn-icon .x-btn-large .x-btn-text{
+ height: 32px;
+ width: 32px;
+}
+
+/* Icons and text */
+/* left */
+.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{
+ background-position: 0 center;
+ background-repeat: no-repeat;
+ padding-left:18px;
+ height:16px;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{
+ background-position: 0 center;
+ background-repeat: no-repeat;
+ padding-left:26px;
+ height:24px;
+}
+
+.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{
+ background-position: 0 center;
+ background-repeat: no-repeat;
+ padding-left:34px;
+ height:32px;
+}
+
+/* top */
+.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{
+ background-position: center 0;
+ background-repeat: no-repeat;
+ padding-top:18px;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{
+ background-position: center 0;
+ background-repeat: no-repeat;
+ padding-top:26px;
+}
+
+.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{
+ background-position: center 0;
+ background-repeat: no-repeat;
+ padding-top:34px;
+}
+
+/* right */
+.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{
+ background-position: right center;
+ background-repeat: no-repeat;
+ padding-right:18px;
+ height:16px;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{
+ background-position: right center;
+ background-repeat: no-repeat;
+ padding-right:26px;
+ height:24px;
+}
+
+.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{
+ background-position: right center;
+ background-repeat: no-repeat;
+ padding-right:34px;
+ height:32px;
+}
+
+/* bottom */
+.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{
+ background-position: center bottom;
+ background-repeat: no-repeat;
+ padding-bottom:18px;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{
+ background-position: center bottom;
+ background-repeat: no-repeat;
+ padding-bottom:26px;
+}
+
+.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{
+ background-position: center bottom;
+ background-repeat: no-repeat;
+ padding-bottom:34px;
+}
+
+/* background positioning */
+.x-btn-tr i, .x-btn-tl i, .x-btn-mr i, .x-btn-ml i, .x-btn-br i, .x-btn-bl i{
+ font-size:1px;
+ line-height:1px;
+ width:3px;
+ display:block;
+ overflow:hidden;
+}
+
+.x-btn-tr i, .x-btn-tl i, .x-btn-br i, .x-btn-bl i{
+ height:3px;
+}
+
+.x-btn-tl{
+ width:3px;
+ height:3px;
+ background:no-repeat 0 0;
+}
+.x-btn-tr{
+ width:3px;
+ height:3px;
+ background:no-repeat -3px 0;
+}
+.x-btn-tc{
+ height:3px;
+ background:repeat-x 0 -6px;
+}
+
+.x-btn-ml{
+ width:3px;
+ background:no-repeat 0 -24px;
+}
+.x-btn-mr{
+ width:3px;
+ background:no-repeat -3px -24px;
+}
+
+.x-btn-mc{
+ background:repeat-x 0 -1096px;
+ vertical-align: middle;
+ text-align:center;
+ padding:0 5px;
+ cursor:pointer;
+ white-space:nowrap;
+}
+
+/* Fixes an issue with the button height */
+.ext-strict .ext-ie6 .x-btn-mc, .ext-strict .ext-ie7 .x-btn-mc {
+ height: 100%;
+}
+
+.x-btn-bl{
+ width:3px;
+ height:3px;
+ background:no-repeat 0 -3px;
+}
+
+.x-btn-br{
+ width:3px;
+ height:3px;
+ background:no-repeat -3px -3px;
+}
+
+.x-btn-bc{
+ height:3px;
+ background:repeat-x 0 -15px;
+}
+
+.x-btn-over .x-btn-tl{
+ background-position: -6px 0;
+}
+
+.x-btn-over .x-btn-tr{
+ background-position: -9px 0;
+}
+
+.x-btn-over .x-btn-tc{
+ background-position: 0 -9px;
+}
+
+.x-btn-over .x-btn-ml{
+ background-position: -6px -24px;
+}
+
+.x-btn-over .x-btn-mr{
+ background-position: -9px -24px;
+}
+
+.x-btn-over .x-btn-mc{
+ background-position: 0 -2168px;
+}
+
+.x-btn-over .x-btn-bl{
+ background-position: -6px -3px;
+}
+
+.x-btn-over .x-btn-br{
+ background-position: -9px -3px;
+}
+
+.x-btn-over .x-btn-bc{
+ background-position: 0 -18px;
+}
+
+.x-btn-click .x-btn-tl, .x-btn-menu-active .x-btn-tl, .x-btn-pressed .x-btn-tl{
+ background-position: -12px 0;
+}
+
+.x-btn-click .x-btn-tr, .x-btn-menu-active .x-btn-tr, .x-btn-pressed .x-btn-tr{
+ background-position: -15px 0;
+}
+
+.x-btn-click .x-btn-tc, .x-btn-menu-active .x-btn-tc, .x-btn-pressed .x-btn-tc{
+ background-position: 0 -12px;
+}
+
+.x-btn-click .x-btn-ml, .x-btn-menu-active .x-btn-ml, .x-btn-pressed .x-btn-ml{
+ background-position: -12px -24px;
+}
+
+.x-btn-click .x-btn-mr, .x-btn-menu-active .x-btn-mr, .x-btn-pressed .x-btn-mr{
+ background-position: -15px -24px;
+}
+
+.x-btn-click .x-btn-mc, .x-btn-menu-active .x-btn-mc, .x-btn-pressed .x-btn-mc{
+ background-position: 0 -3240px;
+}
+
+.x-btn-click .x-btn-bl, .x-btn-menu-active .x-btn-bl, .x-btn-pressed .x-btn-bl{
+ background-position: -12px -3px;
+}
+
+.x-btn-click .x-btn-br, .x-btn-menu-active .x-btn-br, .x-btn-pressed .x-btn-br{
+ background-position: -15px -3px;
+}
+
+.x-btn-click .x-btn-bc, .x-btn-menu-active .x-btn-bc, .x-btn-pressed .x-btn-bc{
+ background-position: 0 -21px;
+}
+
+.x-btn-disabled *{
+ cursor:default !important;
+}
+
+
+/* With a menu arrow */
+/* right */
+.x-btn-mc em.x-btn-arrow {
+ display:block;
+ background:transparent no-repeat right center;
+ padding-right:10px;
+}
+
+.x-btn-mc em.x-btn-split {
+ display:block;
+ background:transparent no-repeat right center;
+ padding-right:14px;
+}
+
+/* bottom */
+.x-btn-mc em.x-btn-arrow-bottom {
+ display:block;
+ background:transparent no-repeat center bottom;
+ padding-bottom:14px;
+}
+
+.x-btn-mc em.x-btn-split-bottom {
+ display:block;
+ background:transparent no-repeat center bottom;
+ padding-bottom:14px;
+}
+
+/* height adjustment class */
+.x-btn-as-arrow .x-btn-mc em {
+ display:block;
+ background-color:transparent;
+ padding-bottom:14px;
+}
+
+/* groups */
+.x-btn-group {
+ padding:1px;
+}
+
+.x-btn-group-header {
+ padding:2px;
+ text-align:center;
+}
+
+.x-btn-group-tc {
+ background: transparent repeat-x 0 0;
+ overflow:hidden;
+}
+
+.x-btn-group-tl {
+ background: transparent no-repeat 0 0;
+ padding-left:3px;
+ zoom:1;
+}
+
+.x-btn-group-tr {
+ background: transparent no-repeat right 0;
+ zoom:1;
+ padding-right:3px;
+}
+
+.x-btn-group-bc {
+ background: transparent repeat-x 0 bottom;
+ zoom:1;
+}
+
+.x-btn-group-bc .x-panel-footer {
+ zoom:1;
+}
+
+.x-btn-group-bl {
+ background: transparent no-repeat 0 bottom;
+ padding-left:3px;
+ zoom:1;
+}
+
+.x-btn-group-br {
+ background: transparent no-repeat right bottom;
+ padding-right:3px;
+ zoom:1;
+}
+
+.x-btn-group-mc {
+ border:0 none;
+ padding:1px 0 0 0;
+ margin:0;
+}
+
+.x-btn-group-mc .x-btn-group-body {
+ background-color:transparent;
+ border: 0 none;
+}
+
+.x-btn-group-ml {
+ background: transparent repeat-y 0 0;
+ padding-left:3px;
+ zoom:1;
+}
+
+.x-btn-group-mr {
+ background: transparent repeat-y right 0;
+ padding-right:3px;
+ zoom:1;
+}
+
+.x-btn-group-bc .x-btn-group-footer {
+ padding-bottom:6px;
+}
+
+.x-panel-nofooter .x-btn-group-bc {
+ height:3px;
+ font-size:0;
+ line-height:0;
+}
+
+.x-btn-group-bwrap {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-btn-group-body {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-btn-group-notitle .x-btn-group-tc {
+ background: transparent repeat-x 0 0;
+ overflow:hidden;
+ height:2px;
+}.x-toolbar{
+ border-style:solid;
+ border-width:0 0 1px 0;
+ display: block;
+ padding:2px;
+ background:repeat-x top left;
+ position:relative;
+ left:0;
+ top:0;
+ zoom:1;
+ overflow:hidden;
+}
+
+.x-toolbar-left {
+ width: 100%;
+}
+
+.x-toolbar .x-item-disabled .x-btn-icon {
+ opacity: .35;
+ -moz-opacity: .35;
+ filter: alpha(opacity=35);
+}
+
+.x-toolbar td {
+ vertical-align:middle;
+}
+
+.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{
+ white-space: nowrap;
+}
+
+.x-toolbar .x-item-disabled {
+ cursor:default;
+ opacity:.6;
+ -moz-opacity:.6;
+ filter:alpha(opacity=60);
+}
+
+.x-toolbar .x-item-disabled * {
+ cursor:default;
+}
+
+.x-toolbar .x-toolbar-cell {
+ vertical-align:middle;
+}
+
+.x-toolbar .x-btn-tl, .x-toolbar .x-btn-tr, .x-toolbar .x-btn-tc, .x-toolbar .x-btn-ml, .x-toolbar .x-btn-mr,
+.x-toolbar .x-btn-mc, .x-toolbar .x-btn-bl, .x-toolbar .x-btn-br, .x-toolbar .x-btn-bc
+{
+ background-position: 500px 500px;
+}
+
+/* These rules are duplicated from button.css to give priority of x-toolbar rules above */
+.x-toolbar .x-btn-over .x-btn-tl{
+ background-position: -6px 0;
+}
+
+.x-toolbar .x-btn-over .x-btn-tr{
+ background-position: -9px 0;
+}
+
+.x-toolbar .x-btn-over .x-btn-tc{
+ background-position: 0 -9px;
+}
+
+.x-toolbar .x-btn-over .x-btn-ml{
+ background-position: -6px -24px;
+}
+
+.x-toolbar .x-btn-over .x-btn-mr{
+ background-position: -9px -24px;
+}
+
+.x-toolbar .x-btn-over .x-btn-mc{
+ background-position: 0 -2168px;
+}
+
+.x-toolbar .x-btn-over .x-btn-bl{
+ background-position: -6px -3px;
+}
+
+.x-toolbar .x-btn-over .x-btn-br{
+ background-position: -9px -3px;
+}
+
+.x-toolbar .x-btn-over .x-btn-bc{
+ background-position: 0 -18px;
+}
+
+.x-toolbar .x-btn-click .x-btn-tl, .x-toolbar .x-btn-menu-active .x-btn-tl, .x-toolbar .x-btn-pressed .x-btn-tl{
+ background-position: -12px 0;
+}
+
+.x-toolbar .x-btn-click .x-btn-tr, .x-toolbar .x-btn-menu-active .x-btn-tr, .x-toolbar .x-btn-pressed .x-btn-tr{
+ background-position: -15px 0;
+}
+
+.x-toolbar .x-btn-click .x-btn-tc, .x-toolbar .x-btn-menu-active .x-btn-tc, .x-toolbar .x-btn-pressed .x-btn-tc{
+ background-position: 0 -12px;
+}
+
+.x-toolbar .x-btn-click .x-btn-ml, .x-toolbar .x-btn-menu-active .x-btn-ml, .x-toolbar .x-btn-pressed .x-btn-ml{
+ background-position: -12px -24px;
+}
+
+.x-toolbar .x-btn-click .x-btn-mr, .x-toolbar .x-btn-menu-active .x-btn-mr, .x-toolbar .x-btn-pressed .x-btn-mr{
+ background-position: -15px -24px;
+}
+
+.x-toolbar .x-btn-click .x-btn-mc, .x-toolbar .x-btn-menu-active .x-btn-mc, .x-toolbar .x-btn-pressed .x-btn-mc{
+ background-position: 0 -3240px;
+}
+
+.x-toolbar .x-btn-click .x-btn-bl, .x-toolbar .x-btn-menu-active .x-btn-bl, .x-toolbar .x-btn-pressed .x-btn-bl{
+ background-position: -12px -3px;
+}
+
+.x-toolbar .x-btn-click .x-btn-br, .x-toolbar .x-btn-menu-active .x-btn-br, .x-toolbar .x-btn-pressed .x-btn-br{
+ background-position: -15px -3px;
+}
+
+.x-toolbar .x-btn-click .x-btn-bc, .x-toolbar .x-btn-menu-active .x-btn-bc, .x-toolbar .x-btn-pressed .x-btn-bc{
+ background-position: 0 -21px;
+}
+
+.x-toolbar div.xtb-text{
+ padding:2px 2px 0;
+ line-height:16px;
+ display:block;
+}
+
+.x-toolbar .xtb-sep {
+ 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 .xtb-spacer {
+ width:2px;
+}
+
+/* Paging Toolbar */
+.x-tbar-page-number{
+ width:30px;
+ height:14px;
+}
+
+.ext-ie .x-tbar-page-number{
+ margin-top: 2px;
+}
+
+.x-paging-info {
+ position:absolute;
+ top:5px;
+ right: 8px;
+}
+
+/* floating */
+.x-toolbar-ct {
+ width:100%;
+}
+
+.x-toolbar-right td {
+ text-align: center;
+}
+
+.x-panel-tbar, .x-panel-bbar, .x-window-tbar, .x-window-bbar, .x-tab-panel-tbar, .x-tab-panel-bbar, .x-plain-tbar, .x-plain-bbar {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-toolbar-more .x-btn-small .x-btn-text{
+ height: 16px;
+ width: 12px;
+}
+
+.x-toolbar-more em.x-btn-arrow {
+ display:inline;
+ background-color:transparent;
+ padding-right:0;
+}
+
+.x-toolbar-more .x-btn-mc em.x-btn-arrow {
+ background-image: none;
+}
+
+div.x-toolbar-no-items {
+ color:gray !important;
+ padding:5px 10px !important;
+}
+
+/* fix ie toolbar form items */
+.ext-border-box .x-toolbar-cell .x-form-text {
+ margin-bottom:-1px !important;
+}
+
+.ext-border-box .x-toolbar-cell .x-form-field-wrap .x-form-text {
+ margin:0 !important;
+}
+
+.ext-ie .x-toolbar-cell .x-form-field-wrap {
+ height:21px;
+}
+
+.ext-ie .x-toolbar-cell .x-form-text {
+ position:relative;
+ top:-1px;
+}
+
+.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-text, .ext-strict .ext-ie .x-toolbar-cell .x-form-text {
+ top: 0px;
+}
+
+.x-toolbar-right td .x-form-field-trigger-wrap{
+ text-align: left;
+}
+
+.x-toolbar-cell .x-form-checkbox, .x-toolbar-cell .x-form-radio{
+ margin-top: 5px;
+}
+
+.x-toolbar-cell .x-form-cb-label{
+ vertical-align: bottom;
+ top: 1px;
+}
+
+.ext-ie .x-toolbar-cell .x-form-checkbox, .ext-ie .x-toolbar-cell .x-form-radio{
+ margin-top: 4px;
+}
+
+.ext-ie .x-toolbar-cell .x-form-cb-label{
+ top: 0;
+}
+/* Grid3 styles */
+.x-grid3 {
+ position:relative;
+ overflow:hidden;
+}
+
+.x-grid-panel .x-panel-body {
+ overflow:hidden !important;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+ border:1px solid;
+}
+
+.x-grid3 table {
+ table-layout:fixed;
+}
+
+.x-grid3-viewport{
+ overflow:hidden;
+}
+
+.x-grid3-hd-row td, .x-grid3-row td, .x-grid3-summary-row td{
+ -moz-outline: none;
+ outline: none;
+ -moz-user-focus: normal;
+}
+
+.x-grid3-row td, .x-grid3-summary-row td {
+ line-height:13px;
+ vertical-align: top;
+ padding-left:1px;
+ padding-right:1px;
+ -moz-user-select: none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+}
+
+.x-grid3-cell{
+ -moz-user-select: none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+}
+
+.x-grid3-hd-row td {
+ line-height:15px;
+ vertical-align:middle;
+ border-left:1px solid;
+ border-right:1px solid;
+}
+
+.x-grid3-hd-row .x-grid3-marker-hd {
+ padding:3px;
+}
+
+.x-grid3-row .x-grid3-marker {
+ padding:3px;
+}
+
+.x-grid3-cell-inner, .x-grid3-hd-inner{
+ overflow:hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ padding:3px 3px 3px 5px;
+ white-space: nowrap;
+}
+
+/* ActionColumn, reduce padding to accommodate 16x16 icons in normal row height */
+.x-action-col-cell .x-grid3-cell-inner {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+.x-action-col-icon {
+ cursor: pointer;
+}
+
+.x-grid3-hd-inner {
+ position:relative;
+ cursor:inherit;
+ padding:4px 3px 4px 5px;
+}
+
+.x-grid3-row-body {
+ white-space:normal;
+}
+
+.x-grid3-body-cell {
+ -moz-outline:0 none;
+ outline:0 none;
+}
+
+/* IE Quirks to clip */
+.ext-ie .x-grid3-cell-inner, .ext-ie .x-grid3-hd-inner{
+ width:100%;
+}
+
+/* reverse above in strict mode */
+.ext-strict .x-grid3-cell-inner, .ext-strict .x-grid3-hd-inner{
+ width:auto;
+}
+
+.x-grid-row-loading {
+ background: no-repeat center center;
+}
+
+.x-grid-page {
+ overflow:hidden;
+}
+
+.x-grid3-row {
+ cursor: default;
+ border: 1px solid;
+ width:100%;
+}
+
+.x-grid3-row-over {
+ border:1px solid;
+ background: repeat-x left top;
+}
+
+.x-grid3-resize-proxy {
+ width:1px;
+ left:0;
+ cursor: e-resize;
+ cursor: col-resize;
+ position:absolute;
+ top:0;
+ height:100px;
+ overflow:hidden;
+ visibility:hidden;
+ border:0 none;
+ z-index:7;
+}
+
+.x-grid3-resize-marker {
+ width:1px;
+ left:0;
+ position:absolute;
+ top:0;
+ height:100px;
+ overflow:hidden;
+ visibility:hidden;
+ border:0 none;
+ z-index:7;
+}
+
+.x-grid3-focus {
+ position:absolute;
+ left:0;
+ top:0;
+ width:1px;
+ height:1px;
+ line-height:1px;
+ font-size:1px;
+ -moz-outline:0 none;
+ outline:0 none;
+ -moz-user-select: text;
+ -khtml-user-select: text;
+ -webkit-user-select:ignore;
+}
+
+/* header styles */
+.x-grid3-header{
+ background: repeat-x 0 bottom;
+ cursor:default;
+ zoom:1;
+ padding:1px 0 0 0;
+}
+
+.x-grid3-header-pop {
+ border-left:1px solid;
+ float:right;
+ clear:none;
+}
+
+.x-grid3-header-pop-inner {
+ border-left:1px solid;
+ width:14px;
+ height:19px;
+ background: transparent no-repeat center center;
+}
+
+.ext-ie .x-grid3-header-pop-inner {
+ width:15px;
+}
+
+.ext-strict .x-grid3-header-pop-inner {
+ width:14px;
+}
+
+.x-grid3-header-inner {
+ overflow:hidden;
+ zoom:1;
+ float:left;
+}
+
+.x-grid3-header-offset {
+ padding-left:1px;
+ text-align: left;
+}
+
+td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open {
+ border-left:1px solid;
+ border-right:1px solid;
+}
+
+td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner {
+ background: repeat-x left bottom;
+
+}
+
+.x-grid3-sort-icon{
+ background-repeat: no-repeat;
+ display: none;
+ height: 4px;
+ width: 13px;
+ margin-left:3px;
+ vertical-align: middle;
+}
+
+.sort-asc .x-grid3-sort-icon, .sort-desc .x-grid3-sort-icon {
+ display: inline;
+}
+
+/* Header position fixes for IE strict mode */
+.ext-strict .ext-ie .x-grid3-header-inner, .ext-strict .ext-ie6 .x-grid3-hd {
+ position:relative;
+}
+
+.ext-strict .ext-ie6 .x-grid3-hd-inner{
+ position:static;
+}
+
+/* Body Styles */
+.x-grid3-body {
+ zoom:1;
+}
+
+.x-grid3-scroller {
+ overflow:auto;
+ zoom:1;
+ position:relative;
+}
+
+.x-grid3-cell-text, .x-grid3-hd-text {
+ display: block;
+ padding: 3px 5px 3px 5px;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+ -webkit-user-select:ignore;
+}
+
+.x-grid3-split {
+ 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;
+}
+
+/* Column Reorder DD */
+.x-dd-drag-proxy .x-grid3-hd-inner{
+ background: repeat-x left bottom;
+ width:120px;
+ padding:3px;
+ border:1px solid;
+ overflow:hidden;
+}
+
+.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;
+ background:transparent no-repeat left top;
+}
+
+/* Selection Styles */
+.x-grid3-row-selected {
+ border:1px dotted;
+}
+
+.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{
+ background: repeat-x 0 bottom !important;
+ vertical-align:middle !important;
+ padding:0;
+ border-top:1px solid;
+ border-bottom:none !important;
+ border-right:1px solid !important;
+ text-align:center;
+}
+
+.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{
+ padding:0 4px;
+ text-align:center;
+}
+
+/* dirty cells */
+.x-grid3-dirty-cell {
+ background: transparent no-repeat 0 0;
+}
+
+/* Grid Toolbars */
+.x-grid3-topbar, .x-grid3-bottombar{
+ overflow:hidden;
+ display:none;
+ zoom:1;
+ position:relative;
+}
+
+.x-grid3-topbar .x-toolbar{
+ border-right:0 none;
+}
+
+.x-grid3-bottombar .x-toolbar{
+ border-right:0 none;
+ border-bottom:0 none;
+ border-top:1px solid;
+}
+
+/* Props Grid Styles */
+.x-props-grid .x-grid3-cell{
+ padding:1px;
+}
+
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{
+ background:transparent repeat-y -16px !important;
+ padding-left:12px;
+}
+
+.x-props-grid .x-grid3-body .x-grid3-td-name{
+ padding:1px;
+ padding-right:0;
+ border:0 none;
+ border-right:1px solid;
+}
+
+/* dd */
+.x-grid3-col-dd {
+ border:0 none;
+ padding:0;
+ background-color:transparent;
+}
+
+.x-dd-drag-ghost .x-grid3-dd-wrap {
+ padding:1px 3px 3px 1px;
+}
+
+.x-grid3-hd {
+ -moz-user-select:none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+}
+
+.x-grid3-hd-btn {
+ display:none;
+ position:absolute;
+ width:14px;
+ background:no-repeat left center;
+ right:0;
+ top:0;
+ z-index:2;
+ cursor:pointer;
+}
+
+.x-grid3-hd-over .x-grid3-hd-btn, .x-grid3-hd-menu-open .x-grid3-hd-btn {
+ display:block;
+}
+
+a.x-grid3-hd-btn:hover {
+ background-position:-14px center;
+}
+
+/* Expanders */
+.x-grid3-body .x-grid3-td-expander {
+ background:transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner {
+ padding:0 !important;
+ height:100%;
+}
+
+.x-grid3-row-expander {
+ width:100%;
+ height:18px;
+ background-position:4px 2px;
+ background-repeat:no-repeat;
+ background-color:transparent;
+}
+
+.x-grid3-row-collapsed .x-grid3-row-expander {
+ background-position:4px 2px;
+}
+
+.x-grid3-row-expanded .x-grid3-row-expander {
+ background-position:-21px 2px;
+}
+
+.x-grid3-row-collapsed .x-grid3-row-body {
+ display:none !important;
+}
+
+.x-grid3-row-expanded .x-grid3-row-body {
+ display:block !important;
+}
+
+/* Checkers */
+.x-grid3-body .x-grid3-td-checker {
+ background:transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner, .x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner {
+ padding:0 !important;
+ height:100%;
+}
+
+.x-grid3-row-checker, .x-grid3-hd-checker {
+ width:100%;
+ height:18px;
+ background-position:2px 2px;
+ background-repeat:no-repeat;
+ background-color:transparent;
+}
+
+.x-grid3-row .x-grid3-row-checker {
+ background-position:2px 2px;
+}
+
+.x-grid3-row-selected .x-grid3-row-checker, .x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker {
+ background-position:-23px 2px;
+}
+
+.x-grid3-hd-checker {
+ background-position:2px 1px;
+}
+
+.ext-border-box .x-grid3-hd-checker {
+ background-position:2px 3px;
+}
+
+.x-grid3-hd-checker-on .x-grid3-hd-checker {
+ background-position:-23px 1px;
+}
+
+.ext-border-box .x-grid3-hd-checker-on .x-grid3-hd-checker {
+ background-position:-23px 3px;
+}
+
+/* Numberer */
+.x-grid3-body .x-grid3-td-numberer {
+ background:transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+ padding:3px 5px 0 0 !important;
+ text-align:right;
+}
+
+/* Row Icon */
+
+.x-grid3-body .x-grid3-td-row-icon {
+ background:transparent repeat-y right;
+ vertical-align:top;
+ text-align:center;
+}
+
+.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner {
+ padding:0 !important;
+ background-position:center center;
+ background-repeat:no-repeat;
+ width:16px;
+ height:16px;
+ margin-left:2px;
+ margin-top:3px;
+}
+
+/* All specials */
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
+ background:transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner {
+ padding: 1px 0 0 0 !important;
+}
+
+.x-grid3-check-col {
+ width:100%;
+ height:16px;
+ background-position:center center;
+ background-repeat:no-repeat;
+ background-color:transparent;
+}
+
+.x-grid3-check-col-on {
+ width:100%;
+ height:16px;
+ background-position:center center;
+ background-repeat:no-repeat;
+ background-color:transparent;
+}
+
+/* Grouping classes */
+.x-grid-group, .x-grid-group-body, .x-grid-group-hd {
+ zoom:1;
+}
+
+.x-grid-group-hd {
+ border-bottom: 2px solid;
+ cursor:pointer;
+ padding-top:6px;
+}
+
+.x-grid-group-hd div.x-grid-group-title {
+ background:transparent no-repeat 3px 3px;
+ padding:4px 4px 4px 17px;
+}
+
+.x-grid-group-collapsed .x-grid-group-body {
+ display:none;
+}
+
+.ext-ie6 .x-grid3 .x-editor .x-form-text, .ext-ie7 .x-grid3 .x-editor .x-form-text {
+ position:relative;
+ top:-1px;
+}
+
+.x-grid-editor .x-form-check-wrap {
+ text-align: center;
+ margin-top: -4px;
+}
+
+.ext-ie .x-props-grid .x-editor .x-form-text {
+ position:static;
+ top:0;
+}
+
+.x-grid-empty {
+ padding:10px;
+}
+
+/* fix floating toolbar issue */
+.ext-ie7 .x-grid-panel .x-panel-bbar {
+ position:relative;
+}
+
+
+/* Reset position to static when Grid Panel has been framed */
+/* to resolve 'snapping' from top to bottom behavior. */
+/* @forumThread 86656 */
+.ext-ie7 .x-grid-panel .x-panel-mc .x-panel-bbar {
+ position: static;
+}
+
+.ext-ie6 .x-grid3-header {
+ position: relative;
+}
+
+/* Fix WebKit bug in Grids */
+.ext-webkit .x-grid-panel .x-panel-bwrap{
+ -webkit-user-select:none;
+}
+.ext-webkit .x-tbar-page-number{
+ -webkit-user-select:ignore;
+}
+/* end*/
+
+/* column lines */
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+ padding-right:0;
+ border-right:1px solid;
+}
+.x-pivotgrid .x-grid3-header-offset table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.x-pivotgrid .x-grid3-header-offset table td {
+ padding: 4px 3px 4px 5px;
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 11px;
+ line-height: 13px;
+ font-family: tahoma;
+}
+
+.x-pivotgrid .x-grid3-row-headers {
+ display: block;
+ float: left;
+}
+
+.x-pivotgrid .x-grid3-row-headers table {
+ height: 100%;
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.x-pivotgrid .x-grid3-row-headers table td {
+ height: 18px;
+ padding: 2px 7px 0 0;
+ text-align: right;
+ text-overflow: ellipsis;
+ font-size: 11px;
+ font-family: tahoma;
+}
+
+.ext-gecko .x-pivotgrid .x-grid3-row-headers table td {
+ height: 21px;
+}
+
+.x-grid3-header-title {
+ top: 0%;
+ left: 0%;
+ position: absolute;
+ text-align: center;
+ vertical-align: middle;
+ font-family: tahoma;
+ font-size: 11px;
+ padding: auto 1px;
+ display: table-cell;
+}
+
+.x-grid3-header-title span {
+ position: absolute;
+ top: 50%;
+ left: 0%;
+ width: 100%;
+ margin-top: -6px;
+}.x-dd-drag-proxy{
+ position:absolute;
+ left:0;
+ top:0;
+ visibility:hidden;
+ z-index:15000;
+}
+
+.x-dd-drag-ghost{
+ -moz-opacity: 0.85;
+ opacity:.85;
+ filter: alpha(opacity=85);
+ border: 1px solid;
+ padding:3px;
+ padding-left:20px;
+ 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-view-selector {
+ position:absolute;
+ left:0;
+ top:0;
+ width:0;
+ border:1px dotted;
+ opacity: .5;
+ -moz-opacity: .5;
+ filter:alpha(opacity=50);
+ zoom:1;
+}.ext-strict .ext-ie .x-tree .x-panel-bwrap{
+ position:relative;
+ overflow:hidden;
+}
+
+.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: top;
+ 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: top;
+ width: 16px;
+ background-position:center;
+ background-repeat: no-repeat;
+}
+
+.ext-ie .x-tree-node-indent img, .ext-ie .x-tree-node-icon, .ext-ie .x-tree-ec-icon {
+ vertical-align: middle !important;
+}
+
+.ext-strict .ext-ie8 .x-tree-node-indent img, .ext-strict .ext-ie8 .x-tree-node-icon, .ext-strict .ext-ie8 .x-tree-ec-icon {
+ vertical-align: top !important;
+}
+
+/* checkboxes */
+
+input.x-tree-node-cb {
+ margin-left:1px;
+ height: 19px;
+ vertical-align: bottom;
+}
+
+.ext-ie input.x-tree-node-cb {
+ margin-left:0;
+ margin-top: 1px;
+ width: 16px;
+ height: 16px;
+ vertical-align: middle;
+}
+
+.ext-strict .ext-ie8 input.x-tree-node-cb{
+ margin: 1px 1px;
+ height: 14px;
+ vertical-align: bottom;
+}
+
+.ext-strict .ext-ie8 input.x-tree-node-cb + a{
+ vertical-align: bottom;
+}
+
+.ext-opera input.x-tree-node-cb {
+ height: 14px;
+ vertical-align: middle;
+}
+
+.x-tree-noicon .x-tree-node-icon{
+ width:0; height:0;
+}
+
+/* No line styles */
+.x-tree-no-lines .x-tree-elbow{
+ background-color:transparent;
+}
+
+.x-tree-no-lines .x-tree-elbow-end{
+ background-color:transparent;
+}
+
+.x-tree-no-lines .x-tree-elbow-line{
+ background-color:transparent;
+}
+
+/* Arrows */
+.x-tree-arrows .x-tree-elbow{
+ background-color:transparent;
+}
+
+.x-tree-arrows .x-tree-elbow-plus{
+ background:transparent no-repeat 0 0;
+}
+
+.x-tree-arrows .x-tree-elbow-minus{
+ background:transparent no-repeat -16px 0;
+}
+
+.x-tree-arrows .x-tree-elbow-end{
+ background-color:transparent;
+}
+
+.x-tree-arrows .x-tree-elbow-end-plus{
+ background:transparent no-repeat 0 0;
+}
+
+.x-tree-arrows .x-tree-elbow-end-minus{
+ background:transparent no-repeat -16px 0;
+}
+
+.x-tree-arrows .x-tree-elbow-line{
+ background-color:transparent;
+}
+
+.x-tree-arrows .x-tree-ec-over .x-tree-elbow-plus{
+ background-position:-32px 0;
+}
+
+.x-tree-arrows .x-tree-ec-over .x-tree-elbow-minus{
+ background-position:-48px 0;
+}
+
+.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-plus{
+ background-position:-32px 0;
+}
+
+.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-minus{
+ background-position:-48px 0;
+}
+
+.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;
+ zoom:1;
+}
+
+.x-tree-node{
+ white-space: nowrap;
+}
+
+.x-tree-node-el {
+ line-height:18px;
+ cursor:pointer;
+}
+
+.x-tree-node a, .x-dd-drag-ghost a{
+ text-decoration:none;
+ -khtml-user-select:none;
+ -moz-user-select:none;
+ -webkit-user-select:ignore;
+ -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;
+ padding:1px 3px 1px 2px;
+}
+
+.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-color: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;
+}
+
+.x-tree-node div.x-tree-drag-insert-above{
+ border-top:1px dotted;
+}
+
+.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;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{
+ border-top:2px solid;
+}
+
+.x-tree-node .x-tree-drag-append a span{
+ border:1px dotted;
+}
+
+.x-dd-drag-ghost .x-tree-node-indent, .x-dd-drag-ghost .x-tree-ec-icon{
+ display:none !important;
+}
+
+/* Fix for ie rootVisible:false issue */
+.x-tree-root-ct {
+ zoom:1;
+}
+.x-date-picker {
+ border: 1px solid;
+ border-top:0 none;
+ position:relative;
+}
+
+.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: repeat-x 0 -83px;
+ overflow:hidden;
+}
+
+.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr,
+.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr,
+.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{
+ background:transparent !important;
+ vertical-align:middle;
+}
+
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+ background:transparent 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;
+ width:130px; /* FF3 */
+}
+
+.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-item-disabled .x-date-right a:hover, .x-item-disabled .x-date-left a:hover{
+ -moz-opacity: 0.6;
+ opacity:.6;
+ filter: alpha(opacity=60);
+}
+
+.x-date-right a {
+ margin-right:2px;
+ text-decoration:none !important;
+}
+
+.x-date-left a{
+ margin-left:2px;
+ text-decoration:none !important;
+}
+
+table.x-date-inner {
+ width: 100%;
+ table-layout:fixed;
+}
+
+.ext-webkit table.x-date-inner{
+ /* Fix for webkit browsers */
+ width: 175px;
+}
+
+
+.x-date-inner th {
+ width:25px;
+}
+
+.x-date-inner th {
+ background: repeat-x left top;
+ text-align:right !important;
+ border-bottom: 1px solid;
+ 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;
+ text-align:right;
+ padding:0;
+}
+
+.x-date-inner a {
+ padding:2px 5px;
+ display:block;
+ text-decoration:none;
+ text-align:right;
+ zoom:1;
+}
+
+.x-date-inner .x-date-active{
+ cursor:pointer;
+ color:black;
+}
+
+.x-date-inner .x-date-selected a{
+ background: repeat-x left top;
+ border:1px solid;
+ padding:1px 4px;
+}
+
+.x-date-inner .x-date-today a{
+ border: 1px solid;
+ padding:1px 4px;
+}
+
+.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a {
+ text-decoration:none !important;
+}
+
+.x-date-bottom {
+ padding:4px;
+ border-top: 1px solid;
+ background: repeat-x left top;
+}
+
+.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{
+ text-decoration:none !important;
+}
+
+.x-item-disabled .x-date-inner a:hover{
+ background: none;
+}
+
+.x-date-inner .x-date-disabled a {
+ cursor:default;
+}
+
+.x-date-menu .x-menu-item {
+ padding:1px 24px 1px 4px;
+ white-space: nowrap;
+}
+
+.x-date-menu .x-menu-item .x-menu-item-icon {
+ width:10px;
+ height:10px;
+ margin-right:5px;
+ background-position:center -4px !important;
+}
+
+.x-date-mp {
+ position:absolute;
+ left:0;
+ top:0;
+ display:none;
+}
+
+.x-date-mp td {
+ padding:2px;
+ font:normal 11px arial, helvetica,tahoma,sans-serif;
+}
+
+td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn {
+ border: 0 none;
+ text-align:center;
+ vertical-align: middle;
+ width:25%;
+}
+
+.x-date-mp-ok {
+ margin-right:3px;
+}
+
+.x-date-mp-btns button {
+ text-decoration:none;
+ text-align:center;
+ text-decoration:none !important;
+ border:1px solid;
+ padding:1px 3px 1px;
+ cursor:pointer;
+}
+
+.x-date-mp-btns {
+ background: repeat-x left top;
+}
+
+.x-date-mp-btns td {
+ border-top: 1px solid;
+ text-align:center;
+}
+
+td.x-date-mp-month a,td.x-date-mp-year a {
+ display:block;
+ padding:2px 4px;
+ text-decoration:none;
+ text-align:center;
+}
+
+td.x-date-mp-month a:hover,td.x-date-mp-year a:hover {
+ text-decoration:none;
+ cursor:pointer;
+}
+
+td.x-date-mp-sel a {
+ padding:1px 3px;
+ background: repeat-x left top;
+ border:1px solid;
+}
+
+.x-date-mp-ybtn a {
+ overflow:hidden;
+ width:15px;
+ height:15px;
+ cursor:pointer;
+ background:transparent no-repeat;
+ display:block;
+ margin:0 auto;
+}
+
+.x-date-mp-ybtn a.x-date-mp-next {
+ background-position:0 -120px;
+}
+
+.x-date-mp-ybtn a.x-date-mp-next:hover {
+ background-position:-15px -120px;
+}
+
+.x-date-mp-ybtn a.x-date-mp-prev {
+ background-position:0 -105px;
+}
+
+.x-date-mp-ybtn a.x-date-mp-prev:hover {
+ background-position:-15px -105px;
+}
+
+.x-date-mp-ybtn {
+ text-align:center;
+}
+
+td.x-date-mp-sep {
+ border-right:1px solid;
+}.x-tip{
+ position: absolute;
+ top: 0;
+ left:0;
+ visibility: hidden;
+ z-index: 20002;
+ border:0 none;
+}
+
+.x-tip .x-tip-close{
+ height: 15px;
+ float:right;
+ width: 15px;
+ margin:0 0 2px 2px;
+ cursor:pointer;
+ display:none;
+}
+
+.x-tip .x-tip-tc {
+ background: transparent no-repeat 0 -62px;
+ padding-top:3px;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-tip .x-tip-tl {
+ background: transparent no-repeat 0 0;
+ padding-left:6px;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-tip .x-tip-tr {
+ background: transparent no-repeat right 0;
+ padding-right:6px;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-tip .x-tip-bc {
+ background: transparent no-repeat 0 -121px;
+ height:3px;
+ overflow:hidden;
+}
+
+.x-tip .x-tip-bl {
+ background: transparent no-repeat 0 -59px;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-tip .x-tip-br {
+ background: transparent no-repeat right -59px;
+ padding-right:6px;
+ zoom:1;
+}
+
+.x-tip .x-tip-mc {
+ border:0 none;
+}
+
+.x-tip .x-tip-ml {
+ background: no-repeat 0 -124px;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-tip .x-tip-mr {
+ background: transparent no-repeat right -124px;
+ padding-right:6px;
+ zoom:1;
+}
+
+.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc {
+ font-size:0;
+ line-height:0;
+}
+
+.ext-border-box .x-tip .x-tip-header, .ext-border-box .x-tip .x-tip-tc{
+ line-height: 1px;
+}
+
+.x-tip .x-tip-header-text {
+ padding:0;
+ margin:0 0 2px 0;
+}
+
+.x-tip .x-tip-body {
+ margin:0 !important;
+ line-height:14px;
+ padding:0;
+}
+
+.x-tip .x-tip-body .loading-indicator {
+ margin:0;
+}
+
+.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text {
+ cursor:move;
+}
+
+.x-form-invalid-tip .x-tip-tc {
+ background: repeat-x 0 -12px;
+ padding-top:6px;
+}
+
+.x-form-invalid-tip .x-tip-bc {
+ background: repeat-x 0 -18px;
+ height:6px;
+}
+
+.x-form-invalid-tip .x-tip-bl {
+ background: no-repeat 0 -6px;
+}
+
+.x-form-invalid-tip .x-tip-br {
+ background: no-repeat right -6px;
+}
+
+.x-form-invalid-tip .x-tip-body {
+ padding:2px;
+}
+
+.x-form-invalid-tip .x-tip-body {
+ padding-left:24px;
+ background:transparent no-repeat 2px 2px;
+}
+
+.x-tip-anchor {
+ position: absolute;
+ width: 9px;
+ height: 10px;
+ overflow:hidden;
+ background: transparent no-repeat 0 0;
+ zoom:1;
+}
+.x-tip-anchor-bottom {
+ background-position: -9px 0;
+}
+.x-tip-anchor-right {
+ background-position: -18px 0;
+ width: 10px;
+}
+.x-tip-anchor-left {
+ background-position: -28px 0;
+ width: 10px;
+}.x-menu {
+ z-index: 15000;
+ zoom: 1;
+ background: repeat-y;
+}
+
+.x-menu-floating{
+ border: 1px solid;
+}
+
+.x-menu a {
+ text-decoration: none !important;
+}
+
+.ext-ie .x-menu {
+ zoom:1;
+ overflow:hidden;
+}
+
+.x-menu-list{
+ padding: 2px;
+ background-color:transparent;
+ border:0 none;
+ overflow:hidden;
+ overflow-y: hidden;
+}
+
+.ext-strict .ext-ie .x-menu-list{
+ position: relative;
+}
+
+.x-menu li{
+ line-height:100%;
+}
+
+.x-menu li.x-menu-sep-li{
+ font-size:1px;
+ line-height:1px;
+}
+
+.x-menu-list-item{
+ white-space: nowrap;
+ display:block;
+ padding:1px;
+}
+
+.x-menu-item{
+ -moz-user-select: none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+}
+
+.x-menu-item-arrow{
+ background:transparent no-repeat right;
+}
+
+.x-menu-sep {
+ display:block;
+ font-size:1px;
+ line-height:1px;
+ margin: 2px 3px;
+ border-bottom:1px solid;
+ overflow:hidden;
+}
+
+.x-menu-focus {
+ position:absolute;
+ left:-1px;
+ top:-1px;
+ width:1px;
+ height:1px;
+ line-height:1px;
+ font-size:1px;
+ -moz-outline:0 none;
+ outline:0 none;
+ -moz-user-select: none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+ overflow:hidden;
+ display:block;
+}
+
+a.x-menu-item {
+ cursor: pointer;
+ display: block;
+ line-height: 16px;
+ outline-color: -moz-use-text-color;
+ outline-style: none;
+ outline-width: 0;
+ padding: 3px 21px 3px 27px;
+ position: relative;
+ text-decoration: none;
+ white-space: nowrap;
+}
+
+.x-menu-item-active {
+ background-repeat: repeat-x;
+ background-position: left bottom;
+ border-style:solid;
+ border-width: 1px 0;
+ margin:0 1px;
+ padding: 0;
+}
+
+.x-menu-item-active a.x-menu-item {
+ border-style:solid;
+ border-width:0 1px;
+ margin:0 -1px;
+}
+
+.x-menu-item-icon {
+ border: 0 none;
+ height: 16px;
+ padding: 0;
+ vertical-align: top;
+ width: 16px;
+ position: absolute;
+ left: 3px;
+ top: 3px;
+ margin: 0;
+ background-position:center;
+}
+
+.ext-ie .x-menu-item-icon {
+ left: -24px;
+}
+.ext-strict .x-menu-item-icon {
+ left: 3px;
+}
+
+.ext-ie6 .x-menu-item-icon {
+ left: -24px;
+}
+
+.ext-ie .x-menu-item-icon {
+ vertical-align: middle;
+}
+
+.x-menu-check-item .x-menu-item-icon{
+ background: transparent no-repeat center;
+}
+
+.x-menu-group-item .x-menu-item-icon{
+ background-color: transparent;
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{
+ background: transparent no-repeat center;
+}
+
+.x-date-menu .x-menu-list{
+ padding: 0;
+}
+
+.x-menu-date-item{
+ padding:0;
+}
+
+.x-menu .x-color-palette, .x-menu .x-date-picker{
+ margin-left: 26px;
+ margin-right:4px;
+}
+
+.x-menu .x-date-picker{
+ border:1px solid;
+ margin-top:2px;
+ margin-bottom:2px;
+}
+
+.x-menu-plain .x-color-palette, .x-menu-plain .x-date-picker{
+ margin: 0;
+ border: 0 none;
+}
+
+.x-date-menu {
+ padding:0 !important;
+}
+
+/*
+ * fixes separator visibility problem in IE 6
+ */
+.ext-strict .ext-ie6 .x-menu-sep-li {
+ padding: 3px 4px;
+}
+.ext-strict .ext-ie6 .x-menu-sep {
+ margin: 0;
+ height: 1px;
+}
+
+/*
+ * Fixes an issue with "fat" separators in webkit
+ */
+.ext-webkit .x-menu-sep{
+ height: 1px;
+}
+
+/*
+ * Ugly mess to remove the white border under the picker
+ */
+.ext-ie .x-date-menu{
+ height: 199px;
+}
+
+.ext-strict .ext-ie .x-date-menu, .ext-border-box .ext-ie8 .x-date-menu{
+ height: 197px;
+}
+
+.ext-strict .ext-ie7 .x-date-menu{
+ height: 195px;
+}
+
+.ext-strict .ext-ie8 .x-date-menu{
+ height: auto;
+}
+
+.x-cycle-menu .x-menu-item-checked {
+ border:1px dotted !important;
+ padding:0;
+}
+
+.x-menu .x-menu-scroller {
+ width: 100%;
+ background-repeat:no-repeat;
+ background-position:center;
+ height:8px;
+ line-height: 8px;
+ cursor:pointer;
+ margin: 0;
+ padding: 0;
+}
+
+.x-menu .x-menu-scroller-active{
+ height: 6px;
+ line-height: 6px;
+}
+
+.x-menu-list-item-indent{
+ padding-left: 27px;
+}/*
+ 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 no-repeat 0 0;
+ zoom:1;
+}
+
+.x-box-tc {
+ height: 8px;
+ background: transparent repeat-x 0 0;
+ overflow: hidden;
+}
+
+.x-box-tr {
+ background: transparent no-repeat right -8px;
+}
+
+.x-box-ml {
+ background: transparent repeat-y 0;
+ padding-left: 4px;
+ overflow: hidden;
+ zoom:1;
+}
+
+.x-box-mc {
+ background: repeat-x 0 -16px;
+ padding: 4px 10px;
+}
+
+.x-box-mc h3 {
+ margin: 0 0 4px 0;
+ zoom:1;
+}
+
+.x-box-mr {
+ background: transparent repeat-y right;
+ padding-right: 4px;
+ overflow: hidden;
+}
+
+.x-box-bl {
+ background: transparent no-repeat 0 -16px;
+ zoom:1;
+}
+
+.x-box-bc {
+ background: transparent repeat-x 0 -8px;
+ height: 8px;
+ overflow: hidden;
+}
+
+.x-box-br {
+ background: transparent 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-combo-list {
+ border:1px solid;
+ zoom:1;
+ overflow:hidden;
+}
+
+.x-combo-list-inner {
+ overflow:auto;
+ position:relative; /* for calculating scroll offsets */
+ zoom:1;
+ overflow-x:hidden;
+}
+
+.x-combo-list-hd {
+ border-bottom:1px solid;
+ padding:3px;
+}
+
+.x-resizable-pinned .x-combo-list-inner {
+ border-bottom:1px solid;
+}
+
+.x-combo-list-item {
+ padding:2px;
+ border:1px solid;
+ white-space: nowrap;
+ overflow:hidden;
+ text-overflow: ellipsis;
+}
+
+.x-combo-list .x-combo-selected{
+ border:1px dotted !important;
+ cursor:pointer;
+}
+
+.x-combo-list .x-toolbar {
+ border-top:1px solid;
+ border-bottom:0 none;
+}.x-panel {
+ border-style: solid;
+ border-width:0;
+}
+
+.x-panel-header {
+ overflow:hidden;
+ zoom:1;
+ padding:5px 3px 4px 5px;
+ border:1px solid;
+ line-height: 15px;
+ background: transparent repeat-x 0 -1px;
+}
+
+.x-panel-body {
+ border:1px solid;
+ border-top:0 none;
+ overflow:hidden;
+ position: relative; /* added for item scroll positioning */
+}
+
+.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar {
+ border:1px solid;
+ border-top:0 none;
+ overflow:hidden;
+ padding:2px;
+}
+
+.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar {
+ border-top:1px solid;
+ border-bottom: 0 none;
+}
+
+.x-panel-body-noheader, .x-panel-mc .x-panel-body {
+ border-top:1px solid;
+}
+
+.x-panel-header {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-panel-tl .x-panel-header {
+ padding:5px 0 4px 0;
+ border:0 none;
+ background:transparent no-repeat;
+}
+
+.x-panel-tl .x-panel-icon, .x-window-tl .x-panel-icon {
+ padding-left:20px !important;
+ background-repeat:no-repeat;
+ background-position:0 4px;
+ zoom:1;
+}
+
+.x-panel-inline-icon {
+ width:16px;
+ height:16px;
+ background-repeat:no-repeat;
+ background-position:0 0;
+ vertical-align:middle;
+ margin-right:4px;
+ margin-top:-1px;
+ margin-bottom:-1px;
+}
+
+.x-panel-tc {
+ background: transparent repeat-x 0 0;
+ overflow:hidden;
+}
+
+/* fix ie7 strict mode bug */
+.ext-strict .ext-ie7 .x-panel-tc {
+ overflow: visible;
+}
+
+.x-panel-tl {
+ background: transparent no-repeat 0 0;
+ padding-left:6px;
+ zoom:1;
+ border-bottom:1px solid;
+}
+
+.x-panel-tr {
+ background: transparent no-repeat right 0;
+ zoom:1;
+ padding-right:6px;
+}
+
+.x-panel-bc {
+ background: transparent repeat-x 0 bottom;
+ zoom:1;
+}
+
+.x-panel-bc .x-panel-footer {
+ zoom:1;
+}
+
+.x-panel-bl {
+ background: transparent no-repeat 0 bottom;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-panel-br {
+ background: transparent no-repeat right bottom;
+ padding-right:6px;
+ zoom:1;
+}
+
+.x-panel-mc {
+ border:0 none;
+ padding:0;
+ margin:0;
+ padding-top:6px;
+}
+
+.x-panel-mc .x-panel-body {
+ background-color:transparent;
+ border: 0 none;
+}
+
+.x-panel-ml {
+ background: repeat-y 0 0;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-panel-mr {
+ background: transparent repeat-y right 0;
+ padding-right:6px;
+ zoom:1;
+}
+
+.x-panel-bc .x-panel-footer {
+ padding-bottom:6px;
+}
+
+.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc {
+ height:6px;
+ font-size:0;
+ line-height:0;
+}
+
+.x-panel-bwrap {
+ overflow:hidden;
+ zoom:1;
+ left:0;
+ top:0;
+}
+.x-panel-body {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-panel-collapsed .x-resizable-handle{
+ display:none;
+}
+
+.ext-gecko .x-panel-animated div {
+ overflow:hidden !important;
+}
+
+/* Plain */
+.x-plain-body {
+ overflow:hidden;
+}
+
+.x-plain-bbar .x-toolbar {
+ overflow:hidden;
+ padding:2px;
+}
+
+.x-plain-tbar .x-toolbar {
+ overflow:hidden;
+ padding:2px;
+}
+
+.x-plain-bwrap {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-plain {
+ overflow:hidden;
+}
+
+/* Tools */
+.x-tool {
+ overflow:hidden;
+ width:15px;
+ height:15px;
+ float:right;
+ cursor:pointer;
+ background:transparent no-repeat;
+ margin-left:2px;
+}
+
+/* expand / collapse tools */
+.x-tool-toggle {
+ background-position:0 -60px;
+}
+
+.x-tool-toggle-over {
+ background-position:-15px -60px;
+}
+
+.x-panel-collapsed .x-tool-toggle {
+ background-position:0 -75px;
+}
+
+.x-panel-collapsed .x-tool-toggle-over {
+ background-position:-15px -75px;
+}
+
+
+.x-tool-close {
+ background-position:0 -0;
+}
+
+.x-tool-close-over {
+ background-position:-15px 0;
+}
+
+.x-tool-minimize {
+ background-position:0 -15px;
+}
+
+.x-tool-minimize-over {
+ background-position:-15px -15px;
+}
+
+.x-tool-maximize {
+ background-position:0 -30px;
+}
+
+.x-tool-maximize-over {
+ background-position:-15px -30px;
+}
+
+.x-tool-restore {
+ background-position:0 -45px;
+}
+
+.x-tool-restore-over {
+ background-position:-15px -45px;
+}
+
+.x-tool-gear {
+ background-position:0 -90px;
+}
+
+.x-tool-gear-over {
+ background-position:-15px -90px;
+}
+
+.x-tool-prev {
+ background-position:0 -105px;
+}
+
+.x-tool-prev-over {
+ background-position:-15px -105px;
+}
+
+.x-tool-next {
+ background-position:0 -120px;
+}
+
+.x-tool-next-over {
+ background-position:-15px -120px;
+}
+
+.x-tool-pin {
+ background-position:0 -135px;
+}
+
+.x-tool-pin-over {
+ background-position:-15px -135px;
+}
+
+.x-tool-unpin {
+ background-position:0 -150px;
+}
+
+.x-tool-unpin-over {
+ background-position:-15px -150px;
+}
+
+.x-tool-right {
+ background-position:0 -165px;
+}
+
+.x-tool-right-over {
+ background-position:-15px -165px;
+}
+
+.x-tool-left {
+ background-position:0 -180px;
+}
+
+.x-tool-left-over {
+ background-position:-15px -180px;
+}
+
+.x-tool-down {
+ background-position:0 -195px;
+}
+
+.x-tool-down-over {
+ background-position:-15px -195px;
+}
+
+.x-tool-up {
+ background-position:0 -210px;
+}
+
+.x-tool-up-over {
+ background-position:-15px -210px;
+}
+
+.x-tool-refresh {
+ background-position:0 -225px;
+}
+
+.x-tool-refresh-over {
+ background-position:-15px -225px;
+}
+
+.x-tool-plus {
+ background-position:0 -240px;
+}
+
+.x-tool-plus-over {
+ background-position:-15px -240px;
+}
+
+.x-tool-minus {
+ background-position:0 -255px;
+}
+
+.x-tool-minus-over {
+ background-position:-15px -255px;
+}
+
+.x-tool-search {
+ background-position:0 -270px;
+}
+
+.x-tool-search-over {
+ background-position:-15px -270px;
+}
+
+.x-tool-save {
+ background-position:0 -285px;
+}
+
+.x-tool-save-over {
+ background-position:-15px -285px;
+}
+
+.x-tool-help {
+ background-position:0 -300px;
+}
+
+.x-tool-help-over {
+ background-position:-15px -300px;
+}
+
+.x-tool-print {
+ background-position:0 -315px;
+}
+
+.x-tool-print-over {
+ background-position:-15px -315px;
+}
+
+.x-tool-expand {
+ background-position:0 -330px;
+}
+
+.x-tool-expand-over {
+ background-position:-15px -330px;
+}
+
+.x-tool-collapse {
+ background-position:0 -345px;
+}
+
+.x-tool-collapse-over {
+ background-position:-15px -345px;
+}
+
+.x-tool-resize {
+ background-position:0 -360px;
+}
+
+.x-tool-resize-over {
+ background-position:-15px -360px;
+}
+
+.x-tool-move {
+ background-position:0 -375px;
+}
+
+.x-tool-move-over {
+ background-position:-15px -375px;
+}
+
+/* Ghosting */
+.x-panel-ghost {
+ z-index:12000;
+ overflow:hidden;
+ position:absolute;
+ left:0;top:0;
+ opacity:.65;
+ -moz-opacity:.65;
+ filter:alpha(opacity=65);
+}
+
+.x-panel-ghost ul {
+ margin:0;
+ padding:0;
+ overflow:hidden;
+ font-size:0;
+ line-height:0;
+ border:1px solid;
+ border-top:0 none;
+ display:block;
+}
+
+.x-panel-ghost * {
+ cursor:move !important;
+}
+
+.x-panel-dd-spacer {
+ border:2px dashed;
+}
+
+/* Buttons */
+.x-panel-btns {
+ padding:5px;
+ overflow:hidden;
+}
+
+.x-panel-btns td.x-toolbar-cell{
+ padding:3px;
+}
+
+.x-panel-btns .x-btn-focus .x-btn-left{
+ background-position:0 -147px;
+}
+
+.x-panel-btns .x-btn-focus .x-btn-right{
+ background-position:0 -168px;
+}
+
+.x-panel-btns .x-btn-focus .x-btn-center{
+ background-position:0 -189px;
+}
+
+.x-panel-btns .x-btn-over .x-btn-left{
+ background-position:0 -63px;
+}
+
+.x-panel-btns .x-btn-over .x-btn-right{
+ background-position:0 -84px;
+}
+
+.x-panel-btns .x-btn-over .x-btn-center{
+ background-position:0 -105px;
+}
+
+.x-panel-btns .x-btn-click .x-btn-center{
+ background-position:0 -126px;
+}
+
+.x-panel-btns .x-btn-click .x-btn-right{
+ background-position:0 -84px;
+}
+
+.x-panel-btns .x-btn-click .x-btn-left{
+ background-position:0 -63px;
+}
+
+.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{
+ white-space: nowrap;
+}
+/**
+ * W3C Suggested Default style sheet for HTML 4
+ * http://www.w3.org/TR/CSS21/sample.html
+ *
+ * Resets for Ext.Panel @cfg normal: true
+ */
+.x-panel-reset .x-panel-body html,
+.x-panel-reset .x-panel-body address,
+.x-panel-reset .x-panel-body blockquote,
+.x-panel-reset .x-panel-body body,
+.x-panel-reset .x-panel-body dd,
+.x-panel-reset .x-panel-body div,
+.x-panel-reset .x-panel-body dl,
+.x-panel-reset .x-panel-body dt,
+.x-panel-reset .x-panel-body fieldset,
+.x-panel-reset .x-panel-body form,
+.x-panel-reset .x-panel-body frame, frameset,
+.x-panel-reset .x-panel-body h1,
+.x-panel-reset .x-panel-body h2,
+.x-panel-reset .x-panel-body h3,
+.x-panel-reset .x-panel-body h4,
+.x-panel-reset .x-panel-body h5,
+.x-panel-reset .x-panel-body h6,
+.x-panel-reset .x-panel-body noframes,
+.x-panel-reset .x-panel-body ol,
+.x-panel-reset .x-panel-body p,
+.x-panel-reset .x-panel-body ul,
+.x-panel-reset .x-panel-body center,
+.x-panel-reset .x-panel-body dir,
+.x-panel-reset .x-panel-body hr,
+.x-panel-reset .x-panel-body menu,
+.x-panel-reset .x-panel-body pre { display: block }
+.x-panel-reset .x-panel-body li { display: list-item }
+.x-panel-reset .x-panel-body head { display: none }
+.x-panel-reset .x-panel-body table { display: table }
+.x-panel-reset .x-panel-body tr { display: table-row }
+.x-panel-reset .x-panel-body thead { display: table-header-group }
+.x-panel-reset .x-panel-body tbody { display: table-row-group }
+.x-panel-reset .x-panel-body tfoot { display: table-footer-group }
+.x-panel-reset .x-panel-body col { display: table-column }
+.x-panel-reset .x-panel-body colgroup { display: table-column-group }
+.x-panel-reset .x-panel-body td,
+.x-panel-reset .x-panel-body th { display: table-cell }
+.x-panel-reset .x-panel-body caption { display: table-caption }
+.x-panel-reset .x-panel-body th { font-weight: bolder; text-align: center }
+.x-panel-reset .x-panel-body caption { text-align: center }
+.x-panel-reset .x-panel-body body { margin: 8px }
+.x-panel-reset .x-panel-body h1 { font-size: 2em; margin: .67em 0 }
+.x-panel-reset .x-panel-body h2 { font-size: 1.5em; margin: .75em 0 }
+.x-panel-reset .x-panel-body h3 { font-size: 1.17em; margin: .83em 0 }
+.x-panel-reset .x-panel-body h4,
+.x-panel-reset .x-panel-body p,
+.x-panel-reset .x-panel-body blockquote,
+.x-panel-reset .x-panel-body ul,
+.x-panel-reset .x-panel-body fieldset,
+.x-panel-reset .x-panel-body form,
+.x-panel-reset .x-panel-body ol,
+.x-panel-reset .x-panel-body dl,
+.x-panel-reset .x-panel-body dir,
+.x-panel-reset .x-panel-body menu { margin: 1.12em 0 }
+.x-panel-reset .x-panel-body h5 { font-size: .83em; margin: 1.5em 0 }
+.x-panel-reset .x-panel-body h6 { font-size: .75em; margin: 1.67em 0 }
+.x-panel-reset .x-panel-body h1,
+.x-panel-reset .x-panel-body h2,
+.x-panel-reset .x-panel-body h3,
+.x-panel-reset .x-panel-body h4,
+.x-panel-reset .x-panel-body h5,
+.x-panel-reset .x-panel-body h6,
+.x-panel-reset .x-panel-body b,
+.x-panel-reset .x-panel-body strong { font-weight: bolder }
+.x-panel-reset .x-panel-body blockquote { margin-left: 40px; margin-right: 40px }
+.x-panel-reset .x-panel-body i,
+.x-panel-reset .x-panel-body cite,
+.x-panel-reset .x-panel-body em,
+.x-panel-reset .x-panel-body var,
+.x-panel-reset .x-panel-body address { font-style: italic }
+.x-panel-reset .x-panel-body pre,
+.x-panel-reset .x-panel-body tt,
+.x-panel-reset .x-panel-body code,
+.x-panel-reset .x-panel-body kbd,
+.x-panel-reset .x-panel-body samp { font-family: monospace }
+.x-panel-reset .x-panel-body pre { white-space: pre }
+.x-panel-reset .x-panel-body button,
+.x-panel-reset .x-panel-body textarea,
+.x-panel-reset .x-panel-body input,
+.x-panel-reset .x-panel-body select { display: inline-block }
+.x-panel-reset .x-panel-body big { font-size: 1.17em }
+.x-panel-reset .x-panel-body small,
+.x-panel-reset .x-panel-body sub,
+.x-panel-reset .x-panel-body sup { font-size: .83em }
+.x-panel-reset .x-panel-body sub { vertical-align: sub }
+.x-panel-reset .x-panel-body sup { vertical-align: super }
+.x-panel-reset .x-panel-body table { border-spacing: 2px; }
+.x-panel-reset .x-panel-body thead,
+.x-panel-reset .x-panel-body tbody,
+.x-panel-reset .x-panel-body tfoot { vertical-align: middle }
+.x-panel-reset .x-panel-body td,
+.x-panel-reset .x-panel-body th { vertical-align: inherit }
+.x-panel-reset .x-panel-body s,
+.x-panel-reset .x-panel-body strike,
+.x-panel-reset .x-panel-body del { text-decoration: line-through }
+.x-panel-reset .x-panel-body hr { border: 1px inset }
+.x-panel-reset .x-panel-body ol,
+.x-panel-reset .x-panel-body ul,
+.x-panel-reset .x-panel-body dir,
+.x-panel-reset .x-panel-body menu,
+.x-panel-reset .x-panel-body dd { margin-left: 40px }
+.x-panel-reset .x-panel-body ul, .x-panel-reset .x-panel-body menu, .x-panel-reset .x-panel-body dir { list-style-type: disc;}
+.x-panel-reset .x-panel-body ol { list-style-type: decimal }
+.x-panel-reset .x-panel-body ol ul,
+.x-panel-reset .x-panel-body ul ol,
+.x-panel-reset .x-panel-body ul ul,
+.x-panel-reset .x-panel-body ol ol { margin-top: 0; margin-bottom: 0 }
+.x-panel-reset .x-panel-body u,
+.x-panel-reset .x-panel-body ins { text-decoration: underline }
+.x-panel-reset .x-panel-body br:before { content: "\A" }
+.x-panel-reset .x-panel-body :before, .x-panel-reset .x-panel-body :after { white-space: pre-line }
+.x-panel-reset .x-panel-body center { text-align: center }
+.x-panel-reset .x-panel-body :link, .x-panel-reset .x-panel-body :visited { text-decoration: underline }
+.x-panel-reset .x-panel-body :focus { outline: invert dotted thin }
+
+/* Begin bidirectionality settings (do not change) */
+.x-panel-reset .x-panel-body BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override }
+.x-panel-reset .x-panel-body BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override }
+.x-window {
+ zoom:1;
+}
+
+.x-window .x-window-handle {
+ opacity:0;
+ -moz-opacity:0;
+ filter:alpha(opacity=0);
+}
+
+.x-window-proxy {
+ border:1px solid;
+ z-index:12000;
+ overflow:hidden;
+ position:absolute;
+ left:0;top:0;
+ display:none;
+ opacity:.5;
+ -moz-opacity:.5;
+ filter:alpha(opacity=50);
+}
+
+.x-window-header {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-window-bwrap {
+ z-index:1;
+ position:relative;
+ zoom:1;
+ left:0;top:0;
+}
+
+.x-window-tl .x-window-header {
+ padding:5px 0 4px 0;
+}
+
+.x-window-header-text {
+ cursor:pointer;
+}
+
+.x-window-tc {
+ background: transparent repeat-x 0 0;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-window-tl {
+ background: transparent no-repeat 0 0;
+ padding-left:6px;
+ zoom:1;
+ z-index:1;
+ position:relative;
+}
+
+.x-window-tr {
+ background: transparent no-repeat right 0;
+ padding-right:6px;
+}
+
+.x-window-bc {
+ background: transparent repeat-x 0 bottom;
+ zoom:1;
+}
+
+.x-window-bc .x-window-footer {
+ padding-bottom:6px;
+ zoom:1;
+ font-size:0;
+ line-height:0;
+}
+
+.x-window-bl {
+ background: transparent no-repeat 0 bottom;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-window-br {
+ background: transparent no-repeat right bottom;
+ padding-right:6px;
+ zoom:1;
+}
+
+.x-window-mc {
+ border:1px solid;
+ padding:0;
+ margin:0;
+}
+
+.x-window-ml {
+ background: transparent repeat-y 0 0;
+ padding-left:6px;
+ zoom:1;
+}
+
+.x-window-mr {
+ background: transparent repeat-y right 0;
+ padding-right:6px;
+ zoom:1;
+}
+
+.x-window-body {
+ overflow:hidden;
+}
+
+.x-window-bwrap {
+ overflow:hidden;
+}
+
+.x-window-maximized .x-window-bl, .x-window-maximized .x-window-br,
+ .x-window-maximized .x-window-ml, .x-window-maximized .x-window-mr,
+ .x-window-maximized .x-window-tl, .x-window-maximized .x-window-tr {
+ padding:0;
+}
+
+.x-window-maximized .x-window-footer {
+ padding-bottom:0;
+}
+
+.x-window-maximized .x-window-tc {
+ padding-left:3px;
+ padding-right:3px;
+}
+
+.x-window-maximized .x-window-mc {
+ border-left:0 none;
+ border-right:0 none;
+}
+
+.x-window-tbar .x-toolbar, .x-window-bbar .x-toolbar {
+ border-left:0 none;
+ border-right: 0 none;
+}
+
+.x-window-bbar .x-toolbar {
+ border-top:1px solid;
+ border-bottom:0 none;
+}
+
+.x-window-draggable, .x-window-draggable .x-window-header-text {
+ cursor:move;
+}
+
+.x-window-maximized .x-window-draggable, .x-window-maximized .x-window-draggable .x-window-header-text {
+ cursor:default;
+}
+
+.x-window-body {
+ background-color:transparent;
+}
+
+.x-panel-ghost .x-window-tl {
+ border-bottom:1px solid;
+}
+
+.x-panel-collapsed .x-window-tl {
+ border-bottom:1px solid;
+}
+
+.x-window-maximized-ct {
+ overflow:hidden;
+}
+
+.x-window-maximized .x-window-handle {
+ display:none;
+}
+
+.x-window-sizing-ghost ul {
+ border:0 none !important;
+}
+
+.x-dlg-focus{
+ -moz-outline:0 none;
+ outline:0 none;
+ width:0;
+ height:0;
+ overflow:hidden;
+ position:absolute;
+ top:0;
+ left:0;
+}
+
+.ext-webkit .x-dlg-focus{
+ width: 1px;
+ height: 1px;
+}
+
+.x-dlg-mask{
+ z-index:10000;
+ display:none;
+ position:absolute;
+ top:0;
+ left:0;
+ -moz-opacity: 0.5;
+ opacity:.50;
+ filter: alpha(opacity=50);
+}
+
+body.ext-ie6.x-body-masked select {
+ visibility:hidden;
+}
+
+body.ext-ie6.x-body-masked .x-window select {
+ visibility:visible;
+}
+
+.x-window-plain .x-window-mc {
+ border: 1px solid;
+}
+
+.x-window-plain .x-window-body {
+ border: 1px solid;
+ background:transparent !important;
+}.x-html-editor-wrap {
+ border:1px solid;
+}
+
+.x-html-editor-tb .x-btn-text {
+ background:transparent no-repeat;
+}
+
+.x-html-editor-tb .x-edit-bold, .x-menu-item img.x-edit-bold {
+ background-position:0 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-italic, .x-menu-item img.x-edit-italic {
+ background-position:-16px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-underline, .x-menu-item img.x-edit-underline {
+ background-position:-32px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-forecolor, .x-menu-item img.x-edit-forecolor {
+ background-position:-160px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-backcolor, .x-menu-item img.x-edit-backcolor {
+ background-position:-176px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifyleft, .x-menu-item img.x-edit-justifyleft {
+ background-position:-112px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifycenter, .x-menu-item img.x-edit-justifycenter {
+ background-position:-128px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifyright, .x-menu-item img.x-edit-justifyright {
+ background-position:-144px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-insertorderedlist, .x-menu-item img.x-edit-insertorderedlist {
+ background-position:-80px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-insertunorderedlist, .x-menu-item img.x-edit-insertunorderedlist {
+ background-position:-96px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-increasefontsize, .x-menu-item img.x-edit-increasefontsize {
+ background-position:-48px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-decreasefontsize, .x-menu-item img.x-edit-decreasefontsize {
+ background-position:-64px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-sourceedit, .x-menu-item img.x-edit-sourceedit {
+ background-position:-192px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-createlink, .x-menu-item img.x-edit-createlink {
+ background-position:-208px 0;
+ background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tip .x-tip-bd .x-tip-bd-inner {
+ padding:5px;
+ padding-bottom:1px;
+}
+
+.x-html-editor-tb .x-toolbar {
+ position:static !important;
+}.x-panel-noborder .x-panel-body-noborder {
+ border-width:0;
+}
+
+.x-panel-noborder .x-panel-header-noborder {
+ border-width:0 0 1px;
+ border-style:solid;
+}
+
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+ border-width:0 0 1px;
+ border-style:solid;
+}
+
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+ border-width:1px 0 0 0;
+ border-style:solid;
+}
+
+.x-window-noborder .x-window-mc {
+ border-width:0;
+}
+
+.x-window-plain .x-window-body-noborder {
+ border-width:0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-body-noborder {
+ border-width:0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-header-noborder {
+ border-width: 0 0 1px 0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-footer-noborder {
+ border-width: 1px 0 0 0;
+}
+
+.x-tab-panel-bbar-noborder .x-toolbar {
+ border-width: 1px 0 0 0;
+ border-style:solid;
+}
+
+.x-tab-panel-tbar-noborder .x-toolbar {
+ border-width:0 0 1px;
+ border-style:solid;
+}.x-border-layout-ct {
+ position: relative;
+}
+
+.x-border-panel {
+ position:absolute;
+ left:0;
+ top:0;
+}
+
+.x-tool-collapse-south {
+ background-position:0 -195px;
+}
+
+.x-tool-collapse-south-over {
+ background-position:-15px -195px;
+}
+
+.x-tool-collapse-north {
+ background-position:0 -210px;
+}
+
+.x-tool-collapse-north-over {
+ background-position:-15px -210px;
+}
+
+.x-tool-collapse-west {
+ background-position:0 -180px;
+}
+
+.x-tool-collapse-west-over {
+ background-position:-15px -180px;
+}
+
+.x-tool-collapse-east {
+ background-position:0 -165px;
+}
+
+.x-tool-collapse-east-over {
+ background-position:-15px -165px;
+}
+
+.x-tool-expand-south {
+ background-position:0 -210px;
+}
+
+.x-tool-expand-south-over {
+ background-position:-15px -210px;
+}
+
+.x-tool-expand-north {
+ background-position:0 -195px;
+}
+.x-tool-expand-north-over {
+ background-position:-15px -195px;
+}
+
+.x-tool-expand-west {
+ background-position:0 -165px;
+}
+
+.x-tool-expand-west-over {
+ background-position:-15px -165px;
+}
+
+.x-tool-expand-east {
+ background-position:0 -180px;
+}
+
+.x-tool-expand-east-over {
+ background-position:-15px -180px;
+}
+
+.x-tool-expand-north, .x-tool-expand-south {
+ float:right;
+ margin:3px;
+}
+
+.x-tool-expand-east, .x-tool-expand-west {
+ float:none;
+ margin:3px 2px;
+}
+
+.x-accordion-hd .x-tool-toggle {
+ background-position:0 -255px;
+}
+
+.x-accordion-hd .x-tool-toggle-over {
+ background-position:-15px -255px;
+}
+
+.x-panel-collapsed .x-accordion-hd .x-tool-toggle {
+ background-position:0 -240px;
+}
+
+.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over {
+ background-position:-15px -240px;
+}
+
+.x-accordion-hd {
+ padding-top:4px;
+ padding-bottom:3px;
+ border-top:0 none;
+ background: transparent repeat-x 0 -9px;
+}
+
+.x-layout-collapsed{
+ position:absolute;
+ left:-10000px;
+ top:-10000px;
+ visibility:hidden;
+ width:20px;
+ height:20px;
+ overflow:hidden;
+ border:1px solid;
+ z-index:20;
+}
+
+.ext-border-box .x-layout-collapsed{
+ width:22px;
+ height:22px;
+}
+
+.x-layout-collapsed-over{
+ cursor:pointer;
+}
+
+.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-split{
+ position:absolute;
+ height:5px;
+ width:5px;
+ line-height:1px;
+ font-size:1px;
+ z-index:3;
+ background-color:transparent;
+}
+
+/* IE6 strict won't drag w/out a color */
+.ext-strict .ext-ie6 .x-layout-split{
+ background-color: #fff !important;
+ filter: alpha(opacity=1);
+}
+
+.x-layout-split-h{
+ background-image:url(../images/default/s.gif);
+ background-position: left;
+}
+
+.x-layout-split-v{
+ background-image:url(../images/default/s.gif);
+ background-position: top;
+}
+
+.x-column-layout-ct {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-column {
+ float:left;
+ padding:0;
+ margin:0;
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-column-inner {
+ overflow:hidden;
+ zoom:1;
+}
+
+/* mini mode */
+.x-layout-mini {
+ position:absolute;
+ top:0;
+ left:0;
+ display:block;
+ width:5px;
+ height:35px;
+ cursor:pointer;
+ opacity:.5;
+ -moz-opacity:.5;
+ filter:alpha(opacity=50);
+}
+
+.x-layout-mini-over, .x-layout-collapsed-over .x-layout-mini{
+ opacity:1;
+ -moz-opacity:1;
+ filter:none;
+}
+
+.x-layout-split-west .x-layout-mini {
+ top:48%;
+}
+
+.x-layout-split-east .x-layout-mini {
+ top:48%;
+}
+
+.x-layout-split-north .x-layout-mini {
+ left:48%;
+ height:5px;
+ width:35px;
+}
+
+.x-layout-split-south .x-layout-mini {
+ left:48%;
+ height:5px;
+ width:35px;
+}
+
+.x-layout-cmini-west .x-layout-mini {
+ top:48%;
+}
+
+.x-layout-cmini-east .x-layout-mini {
+ top:48%;
+}
+
+.x-layout-cmini-north .x-layout-mini {
+ left:48%;
+ height:5px;
+ width:35px;
+}
+
+.x-layout-cmini-south .x-layout-mini {
+ left:48%;
+ height:5px;
+ width:35px;
+}
+
+.x-layout-cmini-west, .x-layout-cmini-east {
+ border:0 none;
+ width:5px !important;
+ padding:0;
+ background-color:transparent;
+}
+
+.x-layout-cmini-north, .x-layout-cmini-south {
+ border:0 none;
+ height:5px !important;
+ padding:0;
+ background-color:transparent;
+}
+
+.x-viewport, .x-viewport body {
+ margin: 0;
+ padding: 0;
+ border: 0 none;
+ overflow: hidden;
+ height: 100%;
+}
+
+.x-abs-layout-item {
+ position:absolute;
+ left:0;
+ top:0;
+}
+
+.ext-ie input.x-abs-layout-item, .ext-ie textarea.x-abs-layout-item {
+ margin:0;
+}
+
+.x-box-layout-ct {
+ overflow:hidden;
+ zoom:1;
+}
+
+.x-box-inner {
+ overflow:hidden;
+ zoom:1;
+ position:relative;
+ left:0;
+ top:0;
+}
+
+.x-box-item {
+ position:absolute;
+ left:0;
+ top:0;
+}.x-progress-wrap {
+ border:1px solid;
+ overflow:hidden;
+}
+
+.x-progress-inner {
+ height:18px;
+ background:repeat-x;
+ position:relative;
+}
+
+.x-progress-bar {
+ height:18px;
+ float:left;
+ width:0;
+ background: repeat-x left center;
+ border-top:1px solid;
+ border-bottom:1px solid;
+ border-right:1px solid;
+}
+
+.x-progress-text {
+ padding:1px 5px;
+ overflow:hidden;
+ position:absolute;
+ left:0;
+ text-align:center;
+}
+
+.x-progress-text-back {
+ line-height:16px;
+}
+
+.ext-ie .x-progress-text-back {
+ line-height:15px;
+}
+
+.ext-strict .ext-ie7 .x-progress-text-back{
+ width: 100%;
+}
+.x-list-header{
+ background: repeat-x 0 bottom;
+ cursor:default;
+ zoom:1;
+ height:22px;
+}
+
+.x-list-header-inner div {
+ display:block;
+ float:left;
+ overflow:hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.x-list-header-inner div em {
+ display:block;
+ border-left:1px solid;
+ padding:4px 4px;
+ overflow:hidden;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+ line-height:14px;
+}
+
+.x-list-body {
+ overflow:auto;
+ overflow-x:hidden;
+ overflow-y:auto;
+ zoom:1;
+ float: left;
+ width: 100%;
+}
+
+.x-list-body dl {
+ zoom:1;
+}
+
+.x-list-body dt {
+ display:block;
+ float:left;
+ overflow:hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ cursor:pointer;
+ zoom:1;
+}
+
+.x-list-body dt em {
+ display:block;
+ padding:3px 4px;
+ overflow:hidden;
+ -moz-user-select: none;
+ -khtml-user-select: none;
+}
+
+.x-list-resizer {
+ border-left:1px solid;
+ border-right:1px solid;
+ position:absolute;
+ left:0;
+ top:0;
+}
+
+.x-list-header-inner em.sort-asc {
+ background: transparent no-repeat center 0;
+ border-style:solid;
+ border-width: 0 1px 1px;
+ padding-bottom:3px;
+}
+
+.x-list-header-inner em.sort-desc {
+ background: transparent no-repeat center -23px;
+ border-style:solid;
+ border-width: 0 1px 1px;
+ padding-bottom:3px;
+}
+
+/* Shared styles */
+.x-slider {
+ zoom:1;
+}
+
+.x-slider-inner {
+ position:relative;
+ left:0;
+ top:0;
+ overflow:visible;
+ zoom:1;
+}
+
+.x-slider-focus {
+ position:absolute;
+ left:0;
+ top:0;
+ width:1px;
+ height:1px;
+ line-height:1px;
+ font-size:1px;
+ -moz-outline:0 none;
+ outline:0 none;
+ -moz-user-select: none;
+ -khtml-user-select:none;
+ -webkit-user-select:ignore;
+ display:block;
+ overflow:hidden;
+}
+
+/* Horizontal styles */
+.x-slider-horz {
+ padding-left:7px;
+ background:transparent no-repeat 0 -22px;
+}
+
+.x-slider-horz .x-slider-end {
+ padding-right:7px;
+ zoom:1;
+ background:transparent no-repeat right -44px;
+}
+
+.x-slider-horz .x-slider-inner {
+ background:transparent repeat-x 0 0;
+ height:22px;
+}
+
+.x-slider-horz .x-slider-thumb {
+ width:14px;
+ height:15px;
+ position:absolute;
+ left:0;
+ top:3px;
+ background:transparent no-repeat 0 0;
+}
+
+.x-slider-horz .x-slider-thumb-over {
+ background-position: -14px -15px;
+}
+
+.x-slider-horz .x-slider-thumb-drag {
+ background-position: -28px -30px;
+}
+
+/* Vertical styles */
+.x-slider-vert {
+ padding-top:7px;
+ background:transparent no-repeat -44px 0;
+ width:22px;
+}
+
+.x-slider-vert .x-slider-end {
+ padding-bottom:7px;
+ zoom:1;
+ background:transparent no-repeat -22px bottom;
+}
+
+.x-slider-vert .x-slider-inner {
+ background:transparent repeat-y 0 0;
+}
+
+.x-slider-vert .x-slider-thumb {
+ width:15px;
+ height:14px;
+ position:absolute;
+ left:3px;
+ bottom:0;
+ background:transparent no-repeat 0 0;
+}
+
+.x-slider-vert .x-slider-thumb-over {
+ background-position: -15px -14px;
+}
+
+.x-slider-vert .x-slider-thumb-drag {
+ background-position: -30px -28px;
+}.x-window-dlg .x-window-body {
+ border:0 none !important;
+ padding:5px 10px;
+ overflow:hidden !important;
+}
+
+.x-window-dlg .x-window-mc {
+ border:0 none !important;
+}
+
+.x-window-dlg .ext-mb-input {
+ margin-top:4px;
+ width:95%;
+}
+
+.x-window-dlg .ext-mb-textarea {
+ margin-top:4px;
+}
+
+.x-window-dlg .x-progress-wrap {
+ margin-top:4px;
+}
+
+.ext-ie .x-window-dlg .x-progress-wrap {
+ margin-top:6px;
+}
+
+.x-window-dlg .x-msg-box-wait {
+ background:transparent no-repeat left;
+ display:block;
+ width:300px;
+ padding-left:18px;
+ line-height:18px;
+}
+
+.x-window-dlg .ext-mb-icon {
+ float:left;
+ width:47px;
+ height:32px;
+}
+
+.x-window-dlg .x-dlg-icon .ext-mb-content{
+ zoom: 1;
+ margin-left: 47px;
+}
+
+.x-window-dlg .ext-mb-info, .x-window-dlg .ext-mb-warning, .x-window-dlg .ext-mb-question, .x-window-dlg .ext-mb-error {
+ background:transparent no-repeat top left;
+}
+
+.ext-gecko2 .ext-mb-fix-cursor {
+ overflow:auto;
+}
diff --git a/deluge/ui/web/css/ext-extensions-debug.css b/deluge/ui/web/css/ext-extensions-debug.css
new file mode 100644
index 0000000..89a41fd
--- /dev/null
+++ b/deluge/ui/web/css/ext-extensions-debug.css
@@ -0,0 +1,261 @@
+/*
+ * ColumnTree styles
+ */
+.x-column-tree .x-tree-node {
+ zoom:1;
+}
+.x-column-tree .x-tree-node-el {
+ /*border-bottom:1px solid #eee; borders? */
+ zoom:1;
+}
+.x-column-tree .x-tree-selected {
+ background: #d9e8fb;
+}
+.x-column-tree .x-tree-node a {
+ line-height:18px;
+ vertical-align:middle;
+}
+.x-column-tree .x-tree-node a span{
+
+}
+.x-column-tree .x-tree-node .x-tree-selected a span{
+ background:transparent;
+ color:#000;
+}
+.x-tree-col {
+ float:left;
+ overflow:hidden;
+ padding:0 1px;
+ zoom:1;
+}
+
+.x-tree-col-text, .x-tree-hd-text {
+ overflow:hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ padding:3px 3px 3px 5px;
+ white-space: nowrap;
+ font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-tree-headers {
+ background: #f9f9f9 url(../../resources/images/default/grid/grid3-hrow.gif) repeat-x 0 bottom;
+ cursor:default;
+ zoom:1;
+}
+
+.x-tree-hd {
+ float:left;
+ overflow:hidden;
+ border-left:1px solid #eee;
+ border-right:1px solid #d0d0d0;
+}
+
+/*
+ * FileUploadField component styles
+ */
+.x-form-file-wrap {
+ position: relative;
+ height: 22px;
+}
+.x-form-file-wrap .x-form-file {
+ position: absolute;
+ right: 0;
+ -moz-opacity: 0;
+ filter:alpha(opacity: 0);
+ opacity: 0;
+ z-index: 2;
+ height: 22px;
+ cursor: pointer;
+}
+.x-form-file-wrap .x-btn {
+ position: absolute;
+ right: 0;
+ z-index: 1;
+}
+.x-form-file-wrap .x-form-file-text {
+ position: absolute;
+ left: 0;
+ z-index: 3;
+ color: #777;
+}
+
+/*
+ * Spinner styles
+ */
+.x-form-spinner-proxy{
+ /*background-color:#ff00cc;*/
+}
+.x-form-field-wrap .x-form-spinner-trigger {
+ background: transparent url(../images/spinner.gif) no-repeat 0 0;
+}
+
+.x-form-field-wrap .x-form-spinner-overup{
+ background-position:-17px 0;
+}
+.x-form-field-wrap .x-form-spinner-clickup{
+ background-position:-34px 0;
+}
+.x-form-field-wrap .x-form-spinner-overdown{
+ background-position:-51px 0;
+}
+.x-form-field-wrap .x-form-spinner-clickdown{
+ background-position:-68px 0;
+}
+
+
+.x-trigger-wrap-focus .x-form-spinner-trigger{
+ background-position:-85px 0;
+}
+.x-trigger-wrap-focus .x-form-spinner-overup{
+ background-position:-102px 0;
+}
+.x-trigger-wrap-focus .x-form-spinner-clickup{
+ background-position:-119px 0;
+}
+.x-trigger-wrap-focus .x-form-spinner-overdown{
+ background-position:-136px 0;
+}
+.x-trigger-wrap-focus .x-form-spinner-clickdown{
+ background-position:-153px 0;
+}
+.x-trigger-wrap-focus .x-form-trigger{
+ border-bottom: 1px solid #7eadd9;
+}
+
+.x-form-field-wrap .x-form-spinner-splitter {
+ line-height:1px;
+ font-size:1px;
+ background:transparent url(../images/spinner-split.gif) no-repeat 0 0;
+ position:absolute;
+ cursor: n-resize;
+}
+.x-trigger-wrap-focus .x-form-spinner-splitter{
+ background-position:-14px 0;
+}
+
+.x-form-uxspinner .x-form-field-wrap {
+ height: 24px;
+}
+
+/*
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/* StatusBar - structure */
+.x-statusbar .x-status-text {
+ cursor: default;
+/*
+ height: 21px;
+ line-height: 21px;
+ padding: 0 4px;
+*/
+}
+.x-statusbar .x-status-busy {
+ padding-left: 25px !important;
+ background: transparent no-repeat 3px 2px;
+}
+
+.x-toolbar div.xtb-text
+
+.x-statusbar .x-status-text-panel {
+ border-top: 1px solid;
+ border-right: 1px solid;
+ border-bottom: 1px solid;
+ border-left: 1px solid;
+ padding: 2px 8px 2px 5px;
+}
+
+/* StatusBar word processor example styles */
+
+#word-status .x-status-text-panel .spacer {
+ width: 60px;
+ font-size:0;
+ line-height:0;
+}
+#word-status .x-status-busy {
+ padding-left: 25px !important;
+ background: transparent no-repeat 3px 2px;
+}
+#word-status .x-status-saved {
+ padding-left: 25px !important;
+ background: transparent no-repeat 3px 2px;
+}
+
+/* StatusBar form validation example styles */
+
+.x-statusbar .x-status-error {
+ cursor: pointer;
+ padding-left: 25px !important;
+ background: transparent no-repeat 3px 2px;
+}
+.x-statusbar .x-status-valid {
+ padding-left: 25px !important;
+ background: transparent no-repeat 3px 2px;
+}
+.x-status-error-list {
+ font: 11px tahoma,arial,verdana,sans-serif;
+ position: absolute;
+ z-index: 9999;
+ border-top: 1px solid;
+ border-right: 1px solid;
+ border-bottom: 1px solid;
+ border-left: 1px solid;
+ padding: 5px 10px;
+}
+.x-status-error-list li {
+ cursor: pointer;
+ list-style: disc;
+ margin-left: 10px;
+}
+.x-status-error-list li a {
+ text-decoration: none;
+}
+.x-status-error-list li a:hover {
+ text-decoration: underline;
+}
+
+
+/* *********************************************************** */
+/* *********************************************************** */
+/* *********************************************************** */
+
+
+/* StatusBar - visual */
+
+.x-statusbar .x-status-busy {
+ background-image: url(../images/loading.gif);
+}
+.x-statusbar .x-status-text-panel {
+ border-color: #99bbe8 #fff #fff #99bbe8;
+}
+
+/* StatusBar word processor example styles */
+
+#word-status .x-status-text {
+ color: #777;
+}
+#word-status .x-status-busy {
+ background-image: url(../images/saving.gif);
+}
+#word-status .x-status-saved {
+ background-image: url(../images/saved.png);
+}
+
+/* StatusBar form validation example styles */
+
+.x-statusbar .x-status-error {
+ color: #C33;
+ background-image: url(../images/exclamation.gif);
+}
+.x-statusbar .x-status-valid {
+ background-image: url(../images/accept.png);
+}
+.x-status-error-list {
+ border-color: #C33;
+}
+.x-status-error-list li a {
+ color: #15428B;
+}
diff --git a/deluge/ui/web/css/ext-extensions.css b/deluge/ui/web/css/ext-extensions.css
new file mode 100644
index 0000000..63df411
--- /dev/null
+++ b/deluge/ui/web/css/ext-extensions.css
@@ -0,0 +1 @@
+ .x-column-tree .x-tree-node{zoom:1}.x-column-tree .x-tree-node-el{zoom:1}.x-column-tree .x-tree-selected{background:#d9e8fb}.x-column-tree .x-tree-node a{line-height:18px;vertical-align:middle}.x-column-tree .x-tree-node .x-tree-selected a span{background:transparent;color:#000}.x-tree-col{float:left;overflow:hidden;padding:0 1px;zoom:1}.x-tree-col-text,.x-tree-hd-text{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;padding:3px 3px 3px 5px;white-space:nowrap;font:normal 11px arial,tahoma,helvetica,sans-serif}.x-tree-headers{background:#f9f9f9 url(../../resources/images/default/grid/grid3-hrow.gif) repeat-x 0 bottom;cursor:default;zoom:1}.x-tree-hd{float:left;overflow:hidden;border-left:1px solid #eee;border-right:1px solid #d0d0d0}.x-form-file-wrap{position:relative;height:22px}.x-form-file-wrap .x-form-file{position:absolute;right:0;-moz-opacity:0;filter:alpha(opacity:0);opacity:0;z-index:2;height:22px;cursor:pointer}.x-form-file-wrap .x-btn{position:absolute;right:0;z-index:1}.x-form-file-wrap .x-form-file-text{position:absolute;left:0;z-index:3;color:#777}.x-form-field-wrap .x-form-spinner-trigger{background:transparent url(../images/spinner.gif) no-repeat 0 0}.x-form-field-wrap .x-form-spinner-overup{background-position:-17px 0}.x-form-field-wrap .x-form-spinner-clickup{background-position:-34px 0}.x-form-field-wrap .x-form-spinner-overdown{background-position:-51px 0}.x-form-field-wrap .x-form-spinner-clickdown{background-position:-68px 0}.x-trigger-wrap-focus .x-form-spinner-trigger{background-position:-85px 0}.x-trigger-wrap-focus .x-form-spinner-overup{background-position:-102px 0}.x-trigger-wrap-focus .x-form-spinner-clickup{background-position:-119px 0}.x-trigger-wrap-focus .x-form-spinner-overdown{background-position:-136px 0}.x-trigger-wrap-focus .x-form-spinner-clickdown{background-position:-153px 0}.x-trigger-wrap-focus .x-form-trigger{border-bottom:1px solid #7eadd9}.x-form-field-wrap .x-form-spinner-splitter{line-height:1px;font-size:1px;background:transparent url(../images/spinner-split.gif) no-repeat 0 0;position:absolute;cursor:n-resize}.x-trigger-wrap-focus .x-form-spinner-splitter{background-position:-14px 0}.x-form-uxspinner .x-form-field-wrap{height:24px}.x-statusbar .x-status-text{cursor:default}.x-statusbar .x-status-busy{padding-left:25px!important;background:transparent no-repeat 3px 2px}.x-toolbar div.xtb-text .x-statusbar .x-status-text-panel{border-top:1px solid;border-right:1px solid;border-bottom:1px solid;border-left:1px solid;padding:2px 8px 2px 5px}#word-status .x-status-text-panel .spacer{width:60px;font-size:0;line-height:0}#word-status .x-status-busy{padding-left:25px!important;background:transparent no-repeat 3px 2px}#word-status .x-status-saved{padding-left:25px!important;background:transparent no-repeat 3px 2px}.x-statusbar .x-status-error{cursor:pointer;padding-left:25px!important;background:transparent no-repeat 3px 2px}.x-statusbar .x-status-valid{padding-left:25px!important;background:transparent no-repeat 3px 2px}.x-status-error-list{font:11px tahoma,arial,verdana,sans-serif;position:absolute;z-index:9999;border-top:1px solid;border-right:1px solid;border-bottom:1px solid;border-left:1px solid;padding:5px 10px}.x-status-error-list li{cursor:pointer;list-style:disc;margin-left:10px}.x-status-error-list li a{text-decoration:none}.x-status-error-list li a:hover{text-decoration:underline}.x-statusbar .x-status-busy{background-image:url(../images/loading.gif)}.x-statusbar .x-status-text-panel{border-color:#99bbe8 #fff #fff #99bbe8}#word-status .x-status-text{color:#777}#word-status .x-status-busy{background-image:url(../images/saving.gif)}#word-status .x-status-saved{background-image:url(../images/saved.png)}.x-statusbar .x-status-error{color:#C33;background-image:url(../images/exclamation.gif)}.x-statusbar .x-status-valid{background-image:url(../images/accept.png)}.x-status-error-list{border-color:#C33}.x-status-error-list li a{color:#15428b} \ No newline at end of file
diff --git a/deluge/ui/web/icons/active.png b/deluge/ui/web/icons/active.png
new file mode 100644
index 0000000..daa4f64
--- /dev/null
+++ b/deluge/ui/web/icons/active.png
Binary files differ
diff --git a/deluge/ui/web/icons/add.png b/deluge/ui/web/icons/add.png
new file mode 100644
index 0000000..3bc06ca
--- /dev/null
+++ b/deluge/ui/web/icons/add.png
Binary files differ
diff --git a/deluge/ui/web/icons/add_file.png b/deluge/ui/web/icons/add_file.png
new file mode 100644
index 0000000..6a05745
--- /dev/null
+++ b/deluge/ui/web/icons/add_file.png
Binary files differ
diff --git a/deluge/ui/web/icons/add_magnet.png b/deluge/ui/web/icons/add_magnet.png
new file mode 100644
index 0000000..c015b18
--- /dev/null
+++ b/deluge/ui/web/icons/add_magnet.png
Binary files differ
diff --git a/deluge/ui/web/icons/add_url.png b/deluge/ui/web/icons/add_url.png
new file mode 100644
index 0000000..74dc99f
--- /dev/null
+++ b/deluge/ui/web/icons/add_url.png
Binary files differ
diff --git a/deluge/ui/web/icons/alert.png b/deluge/ui/web/icons/alert.png
new file mode 100644
index 0000000..7036638
--- /dev/null
+++ b/deluge/ui/web/icons/alert.png
Binary files differ
diff --git a/deluge/ui/web/icons/all.png b/deluge/ui/web/icons/all.png
new file mode 100644
index 0000000..c63f8df
--- /dev/null
+++ b/deluge/ui/web/icons/all.png
Binary files differ
diff --git a/deluge/ui/web/icons/back.png b/deluge/ui/web/icons/back.png
new file mode 100644
index 0000000..fdcf9f0
--- /dev/null
+++ b/deluge/ui/web/icons/back.png
Binary files differ
diff --git a/deluge/ui/web/icons/bottom.png b/deluge/ui/web/icons/bottom.png
new file mode 100644
index 0000000..ca32c1f
--- /dev/null
+++ b/deluge/ui/web/icons/bottom.png
Binary files differ
diff --git a/deluge/ui/web/icons/checking.png b/deluge/ui/web/icons/checking.png
new file mode 100644
index 0000000..7487352
--- /dev/null
+++ b/deluge/ui/web/icons/checking.png
Binary files differ
diff --git a/deluge/ui/web/icons/connection_manager.png b/deluge/ui/web/icons/connection_manager.png
new file mode 100644
index 0000000..a033306
--- /dev/null
+++ b/deluge/ui/web/icons/connection_manager.png
Binary files differ
diff --git a/deluge/ui/web/icons/connections.png b/deluge/ui/web/icons/connections.png
new file mode 100644
index 0000000..f0b660b
--- /dev/null
+++ b/deluge/ui/web/icons/connections.png
Binary files differ
diff --git a/deluge/ui/web/icons/create.png b/deluge/ui/web/icons/create.png
new file mode 100644
index 0000000..9008c98
--- /dev/null
+++ b/deluge/ui/web/icons/create.png
Binary files differ
diff --git a/deluge/ui/web/icons/deluge-192.png b/deluge/ui/web/icons/deluge-192.png
new file mode 100644
index 0000000..b49a318
--- /dev/null
+++ b/deluge/ui/web/icons/deluge-192.png
Binary files differ
diff --git a/deluge/ui/web/icons/deluge-32.png b/deluge/ui/web/icons/deluge-32.png
new file mode 100644
index 0000000..6787fa3
--- /dev/null
+++ b/deluge/ui/web/icons/deluge-32.png
Binary files differ
diff --git a/deluge/ui/web/icons/deluge-512.png b/deluge/ui/web/icons/deluge-512.png
new file mode 100644
index 0000000..866f6b9
--- /dev/null
+++ b/deluge/ui/web/icons/deluge-512.png
Binary files differ
diff --git a/deluge/ui/web/icons/deluge-apple-180.png b/deluge/ui/web/icons/deluge-apple-180.png
new file mode 100644
index 0000000..82f7be2
--- /dev/null
+++ b/deluge/ui/web/icons/deluge-apple-180.png
Binary files differ
diff --git a/deluge/ui/web/icons/deluge.png b/deluge/ui/web/icons/deluge.png
new file mode 100644
index 0000000..2f4ae4c
--- /dev/null
+++ b/deluge/ui/web/icons/deluge.png
Binary files differ
diff --git a/deluge/ui/web/icons/dht.png b/deluge/ui/web/icons/dht.png
new file mode 100644
index 0000000..363ee0c
--- /dev/null
+++ b/deluge/ui/web/icons/dht.png
Binary files differ
diff --git a/deluge/ui/web/icons/document.png b/deluge/ui/web/icons/document.png
new file mode 100644
index 0000000..5ee0018
--- /dev/null
+++ b/deluge/ui/web/icons/document.png
Binary files differ
diff --git a/deluge/ui/web/icons/down.png b/deluge/ui/web/icons/down.png
new file mode 100644
index 0000000..68be2b3
--- /dev/null
+++ b/deluge/ui/web/icons/down.png
Binary files differ
diff --git a/deluge/ui/web/icons/downloading.png b/deluge/ui/web/icons/downloading.png
new file mode 100644
index 0000000..ec58cb5
--- /dev/null
+++ b/deluge/ui/web/icons/downloading.png
Binary files differ
diff --git a/deluge/ui/web/icons/drive.png b/deluge/ui/web/icons/drive.png
new file mode 100644
index 0000000..6fd688e
--- /dev/null
+++ b/deluge/ui/web/icons/drive.png
Binary files differ
diff --git a/deluge/ui/web/icons/edit_trackers.png b/deluge/ui/web/icons/edit_trackers.png
new file mode 100644
index 0000000..80455ec
--- /dev/null
+++ b/deluge/ui/web/icons/edit_trackers.png
Binary files differ
diff --git a/deluge/ui/web/icons/error.png b/deluge/ui/web/icons/error.png
new file mode 100644
index 0000000..20ad66a
--- /dev/null
+++ b/deluge/ui/web/icons/error.png
Binary files differ
diff --git a/deluge/ui/web/icons/expand_all.png b/deluge/ui/web/icons/expand_all.png
new file mode 100644
index 0000000..050419f
--- /dev/null
+++ b/deluge/ui/web/icons/expand_all.png
Binary files differ
diff --git a/deluge/ui/web/icons/favicon.ico b/deluge/ui/web/icons/favicon.ico
new file mode 100644
index 0000000..4e6f124
--- /dev/null
+++ b/deluge/ui/web/icons/favicon.ico
Binary files differ
diff --git a/deluge/ui/web/icons/find_more.png b/deluge/ui/web/icons/find_more.png
new file mode 100644
index 0000000..199d73e
--- /dev/null
+++ b/deluge/ui/web/icons/find_more.png
Binary files differ
diff --git a/deluge/ui/web/icons/forward.png b/deluge/ui/web/icons/forward.png
new file mode 100644
index 0000000..2e55489
--- /dev/null
+++ b/deluge/ui/web/icons/forward.png
Binary files differ
diff --git a/deluge/ui/web/icons/help.png b/deluge/ui/web/icons/help.png
new file mode 100644
index 0000000..0566ae0
--- /dev/null
+++ b/deluge/ui/web/icons/help.png
Binary files differ
diff --git a/deluge/ui/web/icons/high.png b/deluge/ui/web/icons/high.png
new file mode 100644
index 0000000..4b2b1ff
--- /dev/null
+++ b/deluge/ui/web/icons/high.png
Binary files differ
diff --git a/deluge/ui/web/icons/home.png b/deluge/ui/web/icons/home.png
new file mode 100644
index 0000000..a319df6
--- /dev/null
+++ b/deluge/ui/web/icons/home.png
Binary files differ
diff --git a/deluge/ui/web/icons/inactive.png b/deluge/ui/web/icons/inactive.png
new file mode 100644
index 0000000..b56213e
--- /dev/null
+++ b/deluge/ui/web/icons/inactive.png
Binary files differ
diff --git a/deluge/ui/web/icons/install_plugin.png b/deluge/ui/web/icons/install_plugin.png
new file mode 100644
index 0000000..aff31e7
--- /dev/null
+++ b/deluge/ui/web/icons/install_plugin.png
Binary files differ
diff --git a/deluge/ui/web/icons/login.png b/deluge/ui/web/icons/login.png
new file mode 100644
index 0000000..c06d0d1
--- /dev/null
+++ b/deluge/ui/web/icons/login.png
Binary files differ
diff --git a/deluge/ui/web/icons/logout.png b/deluge/ui/web/icons/logout.png
new file mode 100644
index 0000000..2f53a65
--- /dev/null
+++ b/deluge/ui/web/icons/logout.png
Binary files differ
diff --git a/deluge/ui/web/icons/low.png b/deluge/ui/web/icons/low.png
new file mode 100644
index 0000000..ff669db
--- /dev/null
+++ b/deluge/ui/web/icons/low.png
Binary files differ
diff --git a/deluge/ui/web/icons/move.png b/deluge/ui/web/icons/move.png
new file mode 100644
index 0000000..ea83832
--- /dev/null
+++ b/deluge/ui/web/icons/move.png
Binary files differ
diff --git a/deluge/ui/web/icons/no_download.png b/deluge/ui/web/icons/no_download.png
new file mode 100644
index 0000000..206d436
--- /dev/null
+++ b/deluge/ui/web/icons/no_download.png
Binary files differ
diff --git a/deluge/ui/web/icons/normal.png b/deluge/ui/web/icons/normal.png
new file mode 100644
index 0000000..2e55489
--- /dev/null
+++ b/deluge/ui/web/icons/normal.png
Binary files differ
diff --git a/deluge/ui/web/icons/ok.png b/deluge/ui/web/icons/ok.png
new file mode 100644
index 0000000..33eb7db
--- /dev/null
+++ b/deluge/ui/web/icons/ok.png
Binary files differ
diff --git a/deluge/ui/web/icons/pause.png b/deluge/ui/web/icons/pause.png
new file mode 100644
index 0000000..8fdd6bc
--- /dev/null
+++ b/deluge/ui/web/icons/pause.png
Binary files differ
diff --git a/deluge/ui/web/icons/preferences.png b/deluge/ui/web/icons/preferences.png
new file mode 100644
index 0000000..7d6deb2
--- /dev/null
+++ b/deluge/ui/web/icons/preferences.png
Binary files differ
diff --git a/deluge/ui/web/icons/queue.png b/deluge/ui/web/icons/queue.png
new file mode 100644
index 0000000..3e4b4be
--- /dev/null
+++ b/deluge/ui/web/icons/queue.png
Binary files differ
diff --git a/deluge/ui/web/icons/queued.png b/deluge/ui/web/icons/queued.png
new file mode 100644
index 0000000..f9f7454
--- /dev/null
+++ b/deluge/ui/web/icons/queued.png
Binary files differ
diff --git a/deluge/ui/web/icons/recheck.png b/deluge/ui/web/icons/recheck.png
new file mode 100644
index 0000000..199d73e
--- /dev/null
+++ b/deluge/ui/web/icons/recheck.png
Binary files differ
diff --git a/deluge/ui/web/icons/remove.png b/deluge/ui/web/icons/remove.png
new file mode 100644
index 0000000..3f91191
--- /dev/null
+++ b/deluge/ui/web/icons/remove.png
Binary files differ
diff --git a/deluge/ui/web/icons/seeding.png b/deluge/ui/web/icons/seeding.png
new file mode 100644
index 0000000..fce70a8
--- /dev/null
+++ b/deluge/ui/web/icons/seeding.png
Binary files differ
diff --git a/deluge/ui/web/icons/start.png b/deluge/ui/web/icons/start.png
new file mode 100644
index 0000000..ff669db
--- /dev/null
+++ b/deluge/ui/web/icons/start.png
Binary files differ
diff --git a/deluge/ui/web/icons/top.png b/deluge/ui/web/icons/top.png
new file mode 100644
index 0000000..850656f
--- /dev/null
+++ b/deluge/ui/web/icons/top.png
Binary files differ
diff --git a/deluge/ui/web/icons/traffic.png b/deluge/ui/web/icons/traffic.png
new file mode 100644
index 0000000..ecd8720
--- /dev/null
+++ b/deluge/ui/web/icons/traffic.png
Binary files differ
diff --git a/deluge/ui/web/icons/up.png b/deluge/ui/web/icons/up.png
new file mode 100644
index 0000000..223e733
--- /dev/null
+++ b/deluge/ui/web/icons/up.png
Binary files differ
diff --git a/deluge/ui/web/icons/update.png b/deluge/ui/web/icons/update.png
new file mode 100644
index 0000000..0ff6d45
--- /dev/null
+++ b/deluge/ui/web/icons/update.png
Binary files differ
diff --git a/deluge/ui/web/icons/upload_slots.png b/deluge/ui/web/icons/upload_slots.png
new file mode 100644
index 0000000..0e7000d
--- /dev/null
+++ b/deluge/ui/web/icons/upload_slots.png
Binary files differ
diff --git a/deluge/ui/web/icons/warning.png b/deluge/ui/web/icons/warning.png
new file mode 100644
index 0000000..f66feda
--- /dev/null
+++ b/deluge/ui/web/icons/warning.png
Binary files differ
diff --git a/deluge/ui/web/images/s.gif b/deluge/ui/web/images/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/deluge/ui/web/images/s.gif
Binary files differ
diff --git a/deluge/ui/web/images/spinner-split.gif b/deluge/ui/web/images/spinner-split.gif
new file mode 100644
index 0000000..7281146
--- /dev/null
+++ b/deluge/ui/web/images/spinner-split.gif
Binary files differ
diff --git a/deluge/ui/web/images/spinner.gif b/deluge/ui/web/images/spinner.gif
new file mode 100644
index 0000000..4e72f53
--- /dev/null
+++ b/deluge/ui/web/images/spinner.gif
Binary files differ
diff --git a/deluge/ui/web/index.html b/deluge/ui/web/index.html
new file mode 100644
index 0000000..08c6d8b
--- /dev/null
+++ b/deluge/ui/web/index.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Deluge WebUI ${version}</title>
+
+ <link rel="icon" sizes="16x16" type="image/png"
+ href="${base}icons/deluge.png"/>
+ <link rel="icon" sizes="32x32" type="image/png"
+ href="${base}icons/deluge-32.png"/>
+ <!-- For Chrome, Android, iOS and Windows touch shortcuts: -->
+ <link rel="icon" sizes="192x192" type="image/png"
+ href="${base}icons/deluge-192.png"/>
+ <link rel="icon" sizes="512x512" type="image/png"
+ href="${base}icons/deluge-512.png"/>
+ <link rel="apple-touch-icon-precomposed"
+ href="${base}icons/deluge-apple-180.png"/>
+ <meta name="msapplication-TileColor" content="#599eee">
+ <meta name="theme-color" content="#599eee">
+
+ <!-- Stylesheets -->
+ % for stylesheet in stylesheets:
+ <link rel="stylesheet" type="text/css" href="${base}${stylesheet}"/>
+ % endfor
+
+ <script type="text/javascript">
+ deluge = {
+ author: 'Deluge Team',
+ version: '${version}',
+ config: ${js_config}
+ }
+ </script>
+
+ <!-- Javascript -->
+ % for script in scripts:
+ <script type="text/javascript" src="${base}${script}"></script>
+ % endfor
+ <script type="text/javascript">
+ Deluge.debug = ${debug};
+ </script>
+ </head>
+ <body>
+ <div style="background-image: url('${base}themes/images/default/tree/loading.gif');"></div>
+
+ <!-- Preload icon classes -->
+ <div class="ext-mb-error"></div>
+ <div class="icon-ok"></div>
+ </body>
+</html>
diff --git a/deluge/ui/web/js/deluge-all-debug.js b/deluge/ui/web/js/deluge-all-debug.js
new file mode 100644
index 0000000..afbbabe
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all-debug.js
@@ -0,0 +1,9868 @@
+/**
+ * Deluge.add.Window.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.Window
+ * @extends Ext.Window
+ * Base class for an add Window
+ */
+Deluge.add.Window = Ext.extend(Ext.Window, {
+ initComponent: function() {
+ Deluge.add.Window.superclass.initComponent.call(this);
+ this.addEvents('beforeadd', 'add');
+ },
+
+ /**
+ * Create an id for the torrent before we have any info about it.
+ */
+ createTorrentId: function() {
+ return new Date().getTime().toString();
+ },
+});
+/**
+ * Deluge.add.AddWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.add');
+
+// This override allows file upload buttons to contain icons
+Ext.override(Ext.ux.form.FileUploadField, {
+ onRender: function(ct, position) {
+ Ext.ux.form.FileUploadField.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+
+ this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
+ this.el.addClass('x-form-file-text');
+ this.el.dom.removeAttribute('name');
+ this.createFileInput();
+
+ var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
+ text: this.buttonText,
+ });
+ this.button = new Ext.Button(
+ Ext.apply(btnCfg, {
+ renderTo: this.wrap,
+ cls:
+ 'x-form-file-btn' +
+ (btnCfg.iconCls ? ' x-btn-text-icon' : ''),
+ })
+ );
+
+ if (this.buttonOnly) {
+ this.el.hide();
+ this.wrap.setWidth(this.button.getEl().getWidth());
+ }
+
+ this.bindListeners();
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+});
+
+Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, {
+ title: _('Add Torrents'),
+ layout: 'border',
+ width: 470,
+ height: 450,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ plain: true,
+ iconCls: 'x-deluge-add-window-icon',
+
+ initComponent: function() {
+ Deluge.add.AddWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ function torrentRenderer(value, p, r) {
+ if (r.data['info_hash']) {
+ return String.format(
+ '<div class="x-deluge-add-torrent-name">{0}</div>',
+ value
+ );
+ } else {
+ return String.format(
+ '<div class="x-deluge-add-torrent-name-loading">{0}</div>',
+ value
+ );
+ }
+ }
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.SimpleStore({
+ fields: [
+ { name: 'info_hash', mapping: 1 },
+ { name: 'text', mapping: 2 },
+ ],
+ id: 0,
+ }),
+ columns: [
+ {
+ id: 'torrent',
+ width: 150,
+ sortable: true,
+ renderer: torrentRenderer,
+ dataIndex: 'text',
+ },
+ ],
+ stripeRows: true,
+ singleSelect: true,
+ listeners: {
+ selectionchange: {
+ fn: this.onSelect,
+ scope: this,
+ },
+ },
+ hideHeaders: true,
+ autoExpandColumn: 'torrent',
+ height: '100%',
+ autoScroll: true,
+ });
+
+ this.add({
+ region: 'center',
+ items: [this.list],
+ border: false,
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ id: 'fileUploadForm',
+ xtype: 'form',
+ layout: 'fit',
+ baseCls: 'x-plain',
+ fileUpload: true,
+ items: [
+ {
+ buttonOnly: true,
+ xtype: 'fileuploadfield',
+ id: 'torrentFile',
+ name: 'file',
+ multiple: true,
+ buttonCfg: {
+ iconCls: 'x-deluge-add-file',
+ text: _('File'),
+ },
+ listeners: {
+ scope: this,
+ fileselected: this.onFileSelected,
+ },
+ },
+ ],
+ },
+ {
+ text: _('Url'),
+ iconCls: 'icon-add-url',
+ handler: this.onUrl,
+ scope: this,
+ },
+ {
+ text: _('Infohash'),
+ iconCls: 'icon-add-magnet',
+ hidden: true,
+ disabled: true,
+ },
+ '->',
+ {
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemove,
+ scope: this,
+ },
+ ],
+ }),
+ });
+
+ this.fileUploadForm = Ext.getCmp('fileUploadForm').getForm();
+ this.optionsPanel = this.add(new Deluge.add.OptionsPanel());
+ this.on('hide', this.onHide, this);
+ this.on('show', this.onShow, this);
+ },
+
+ clear: function() {
+ this.list.getStore().removeAll();
+ this.optionsPanel.clear();
+ // Reset upload form so handler fires when a canceled file is reselected
+ this.fileUploadForm.reset();
+ },
+
+ onAddClick: function() {
+ var torrents = [];
+ if (!this.list) return;
+ this.list.getStore().each(function(r) {
+ var id = r.get('info_hash');
+ torrents.push({
+ path: this.optionsPanel.getFilename(id),
+ options: this.optionsPanel.getOptions(id),
+ });
+ }, this);
+
+ deluge.client.web.add_torrents(torrents, {
+ success: function(result) {},
+ });
+ this.clear();
+ this.hide();
+ },
+
+ onCancelClick: function() {
+ this.clear();
+ this.hide();
+ },
+
+ onFile: function() {
+ if (!this.file) this.file = new Deluge.add.FileWindow();
+ this.file.show();
+ },
+
+ onHide: function() {
+ this.optionsPanel.setActiveTab(0);
+ this.optionsPanel.files.setDisabled(true);
+ this.optionsPanel.form.setDisabled(true);
+ },
+
+ onRemove: function() {
+ if (!this.list.getSelectionCount()) return;
+ var torrent = this.list.getSelectedRecords()[0];
+ if (!torrent) return;
+ this.list.getStore().remove(torrent);
+ this.optionsPanel.clear();
+
+ if (this.torrents && this.torrents[torrent.id])
+ delete this.torrents[torrent.id];
+ },
+
+ onSelect: function(list, selections) {
+ if (selections.length) {
+ var record = this.list.getRecord(selections[0]);
+ this.optionsPanel.setTorrent(record.get('info_hash'));
+ } else {
+ this.optionsPanel.files.setDisabled(true);
+ this.optionsPanel.form.setDisabled(true);
+ }
+ },
+
+ onShow: function() {
+ if (!this.url) {
+ this.url = new Deluge.add.UrlWindow();
+ this.url.on('beforeadd', this.onTorrentBeforeAdd, this);
+ this.url.on('add', this.onTorrentAdd, this);
+ }
+
+ this.optionsPanel.form.getDefaults();
+ },
+
+ onFileSelected: function() {
+ if (this.fileUploadForm.isValid()) {
+ var torrentIds = [];
+ var files = this.fileUploadForm.findField('torrentFile').value;
+ var randomId = this.createTorrentId();
+ Array.prototype.forEach.call(
+ files,
+ function(file, i) {
+ // Append index for batch of unique torrentIds.
+ var torrentId = randomId + i.toString();
+ torrentIds.push(torrentId);
+ this.onTorrentBeforeAdd(torrentId, file.name);
+ }.bind(this)
+ );
+ this.fileUploadForm.submit({
+ url: deluge.config.base + 'upload',
+ waitMsg: _('Uploading your torrent...'),
+ success: this.onUploadSuccess,
+ scope: this,
+ torrentIds: torrentIds,
+ });
+ }
+ },
+
+ onUploadSuccess: function(fp, upload) {
+ if (!upload.result.success) {
+ this.clear();
+ return;
+ }
+
+ upload.result.files.forEach(
+ function(filename, i) {
+ deluge.client.web.get_torrent_info(filename, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: filename,
+ torrentId: upload.options.torrentIds[i],
+ });
+ }.bind(this)
+ );
+ this.fileUploadForm.reset();
+ },
+
+ onGotInfo: function(info, obj, response, request) {
+ info.filename = request.options.filename;
+ torrentId = request.options.torrentId;
+ this.onTorrentAdd(torrentId, info);
+ },
+
+ onTorrentBeforeAdd: function(torrentId, text) {
+ var store = this.list.getStore();
+ store.loadData([[torrentId, null, text]], true);
+ },
+
+ onTorrentAdd: function(torrentId, info) {
+ var r = this.list.getStore().getById(torrentId);
+ if (!info) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: _('Not a valid torrent'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ this.list.getStore().remove(r);
+ } else {
+ r.set('info_hash', info['info_hash']);
+ r.set('text', info['name']);
+ this.list.getStore().commitChanges();
+ this.optionsPanel.addTorrent(info);
+ this.list.select(r);
+ }
+ },
+
+ onUrl: function(button, event) {
+ this.url.show();
+ },
+});
+/**
+ * Deluge.add.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.FilesTab
+ * @extends Ext.ux.tree.TreeGrid
+ */
+Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
+ layout: 'fit',
+ title: _('Files'),
+
+ autoScroll: false,
+ animate: false,
+ border: false,
+ disabled: true,
+ rootVisible: false,
+
+ columns: [
+ {
+ header: _('Filename'),
+ width: 295,
+ dataIndex: 'filename',
+ },
+ {
+ header: _('Size'),
+ width: 60,
+ dataIndex: 'size',
+ tpl: new Ext.XTemplate('{size:this.fsize}', {
+ fsize: function(v) {
+ return fsize(v);
+ },
+ }),
+ },
+ {
+ header: _('Download'),
+ width: 65,
+ dataIndex: 'download',
+ tpl: new Ext.XTemplate('{download:this.format}', {
+ format: function(v) {
+ return (
+ '<div rel="chkbox" class="x-grid3-check-col' +
+ (v ? '-on' : '') +
+ '"> </div>'
+ );
+ },
+ }),
+ },
+ ],
+
+ initComponent: function() {
+ Deluge.add.FilesTab.superclass.initComponent.call(this);
+ this.on('click', this.onNodeClick, this);
+ },
+
+ clearFiles: function() {
+ var root = this.getRootNode();
+ if (!root.hasChildNodes()) return;
+ root.cascade(function(node) {
+ if (!node.parentNode || !node.getOwnerTree()) return;
+ node.remove();
+ });
+ },
+
+ setDownload: function(node, value, suppress) {
+ node.attributes.download = value;
+ node.ui.updateColumns();
+
+ if (node.isLeaf()) {
+ if (!suppress) {
+ return this.fireEvent('fileschecked', [node], value, !value);
+ }
+ } else {
+ var nodes = [node];
+ node.cascade(function(n) {
+ n.attributes.download = value;
+ n.ui.updateColumns();
+ nodes.push(n);
+ }, this);
+ if (!suppress) {
+ return this.fireEvent('fileschecked', nodes, value, !value);
+ }
+ }
+ },
+
+ onNodeClick: function(node, e) {
+ var el = new Ext.Element(e.target);
+ if (el.getAttribute('rel') == 'chkbox') {
+ this.setDownload(node, !node.attributes.download);
+ }
+ },
+});
+/**
+ * Deluge.add.Infohash.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.deluge.add');
+/**
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
+ torrents: {},
+
+ // layout options
+ region: 'south',
+ border: false,
+ activeTab: 0,
+ height: 265,
+
+ initComponent: function() {
+ Deluge.add.OptionsPanel.superclass.initComponent.call(this);
+ this.files = this.add(new Deluge.add.FilesTab());
+ this.form = this.add(new Deluge.add.OptionsTab());
+
+ this.files.on('fileschecked', this.onFilesChecked, this);
+ },
+
+ addTorrent: function(torrent) {
+ this.torrents[torrent['info_hash']] = torrent;
+ var fileIndexes = {};
+ this.walkFileTree(
+ torrent['files_tree'],
+ function(filename, type, entry, parent) {
+ if (type != 'file') return;
+ fileIndexes[entry.index] = entry.download;
+ },
+ this
+ );
+
+ var priorities = [];
+ Ext.each(Ext.keys(fileIndexes), function(index) {
+ priorities[index] = fileIndexes[index];
+ });
+
+ var oldId = this.form.optionsManager.changeId(
+ torrent['info_hash'],
+ true
+ );
+ this.form.optionsManager.setDefault('file_priorities', priorities);
+ this.form.optionsManager.changeId(oldId, true);
+ },
+
+ clear: function() {
+ this.files.clearFiles();
+ this.form.optionsManager.resetAll();
+ },
+
+ getFilename: function(torrentId) {
+ return this.torrents[torrentId]['filename'];
+ },
+
+ getOptions: function(torrentId) {
+ var oldId = this.form.optionsManager.changeId(torrentId, true);
+ var options = this.form.optionsManager.get();
+ this.form.optionsManager.changeId(oldId, true);
+ Ext.each(options['file_priorities'], function(priority, index) {
+ options['file_priorities'][index] = priority ? 1 : 0;
+ });
+ return options;
+ },
+
+ setTorrent: function(torrentId) {
+ if (!torrentId) return;
+
+ this.torrentId = torrentId;
+ this.form.optionsManager.changeId(torrentId);
+
+ this.files.clearFiles();
+ var root = this.files.getRootNode();
+ var priorities = this.form.optionsManager.get('file_priorities');
+
+ this.form.setDisabled(false);
+
+ if (this.torrents[torrentId]['files_tree']) {
+ this.walkFileTree(
+ this.torrents[torrentId]['files_tree'],
+ function(filename, type, entry, parentNode) {
+ var node = new Ext.tree.TreeNode({
+ download: entry.index ? priorities[entry.index] : true,
+ filename: filename,
+ fileindex: entry.index,
+ leaf: type != 'dir',
+ size: entry.length,
+ });
+ parentNode.appendChild(node);
+ if (type == 'dir') return node;
+ },
+ this,
+ root
+ );
+ root.firstChild.expand();
+ this.files.setDisabled(false);
+ this.files.show();
+ } else {
+ // Files tab is empty so show options tab
+ this.form.show();
+ this.files.setDisabled(true);
+ }
+ },
+
+ walkFileTree: function(files, callback, scope, parentNode) {
+ for (var filename in files.contents) {
+ var entry = files.contents[filename];
+ var type = entry.type;
+
+ if (scope) {
+ var ret = callback.apply(scope, [
+ filename,
+ type,
+ entry,
+ parentNode,
+ ]);
+ } else {
+ var ret = callback(filename, type, entry, parentNode);
+ }
+
+ if (type == 'dir') this.walkFileTree(entry, callback, scope, ret);
+ }
+ },
+
+ onFilesChecked: function(nodes, newValue, oldValue) {
+ Ext.each(
+ nodes,
+ function(node) {
+ if (node.attributes.fileindex < 0) return;
+ var priorities = this.form.optionsManager.get(
+ 'file_priorities'
+ );
+ priorities[node.attributes.fileindex] = newValue;
+ this.form.optionsManager.update('file_priorities', priorities);
+ },
+ this
+ );
+ },
+});
+/**
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.OptionsTab
+ * @extends Ext.form.FormPanel
+ */
+Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
+ title: _('Options'),
+ height: 170,
+ border: false,
+ bodyStyle: 'padding: 5px',
+ disabled: true,
+ labelWidth: 1,
+
+ initComponent: function() {
+ Deluge.add.OptionsTab.superclass.initComponent.call(this);
+
+ this.optionsManager = new Deluge.MultiOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Download Folder'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'textfield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding: 5px 0; margin-bottom: 0;',
+ });
+ this.optionsManager.bind(
+ 'download_location',
+ fieldset.add({
+ fieldLabel: '',
+ name: 'download_location',
+ anchor: '95%',
+ labelSeparator: '',
+ })
+ );
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Move Completed Folder'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'togglefield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding: 5px 0; margin-bottom: 0;',
+ });
+ var field = fieldset.add({
+ fieldLabel: '',
+ name: 'move_completed_path',
+ anchor: '98%',
+ });
+ this.optionsManager.bind('move_completed', field.toggle);
+ this.optionsManager.bind('move_completed_path', field.input);
+
+ var panel = this.add({
+ border: false,
+ layout: 'column',
+ defaultType: 'fieldset',
+ });
+
+ fieldset = panel.add({
+ title: _('Bandwidth'),
+ border: false,
+ autoHeight: true,
+ bodyStyle: 'padding: 2px 5px',
+ labelWidth: 105,
+ width: 200,
+ defaultType: 'spinnerfield',
+ style: 'padding-right: 10px;',
+ });
+ this.optionsManager.bind(
+ 'max_download_speed',
+ fieldset.add({
+ fieldLabel: _('Max Down Speed'),
+ name: 'max_download_speed',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_upload_speed',
+ fieldset.add({
+ fieldLabel: _('Max Up Speed'),
+ name: 'max_upload_speed',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_connections',
+ fieldset.add({
+ fieldLabel: _('Max Connections'),
+ name: 'max_connections',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_upload_slots',
+ fieldset.add({
+ fieldLabel: _('Max Upload Slots'),
+ name: 'max_upload_slots',
+ width: 60,
+ })
+ );
+
+ fieldset = panel.add({
+ // title: _('General'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'checkbox',
+ });
+ this.optionsManager.bind(
+ 'add_paused',
+ fieldset.add({
+ name: 'add_paused',
+ boxLabel: _('Add In Paused State'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'prioritize_first_last_pieces',
+ fieldset.add({
+ name: 'prioritize_first_last_pieces',
+ boxLabel: _('Prioritize First/Last Pieces'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'sequential_download',
+ fieldset.add({
+ name: 'sequential_download',
+ boxLabel: _('Sequential Download'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'seed_mode',
+ fieldset.add({
+ name: 'seed_mode',
+ boxLabel: _('Skip File Hash Check'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'super_seeding',
+ fieldset.add({
+ name: 'super_seeding',
+ boxLabel: _('Super Seed'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'pre_allocate_storage',
+ fieldset.add({
+ name: 'pre_allocate_storage',
+ boxLabel: _('Preallocate Disk Space'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ },
+
+ getDefaults: function() {
+ var keys = [
+ 'add_paused',
+ 'pre_allocate_storage',
+ 'download_location',
+ 'max_connections_per_torrent',
+ 'max_download_speed_per_torrent',
+ 'move_completed',
+ 'move_completed_path',
+ 'max_upload_slots_per_torrent',
+ 'max_upload_speed_per_torrent',
+ 'prioritize_first_last_pieces',
+ 'sequential_download',
+ ];
+
+ deluge.client.core.get_config_values(keys, {
+ success: function(config) {
+ var options = {
+ file_priorities: [],
+ add_paused: config.add_paused,
+ sequential_download: config.sequential_download,
+ pre_allocate_storage: config.pre_allocate_storage,
+ download_location: config.download_location,
+ move_completed: config.move_completed,
+ move_completed_path: config.move_completed_path,
+ max_connections: config.max_connections_per_torrent,
+ max_download_speed: config.max_download_speed_per_torrent,
+ max_upload_slots: config.max_upload_slots_per_torrent,
+ max_upload_speed: config.max_upload_speed_per_torrent,
+ prioritize_first_last_pieces:
+ config.prioritize_first_last_pieces,
+ seed_mode: false,
+ super_seeding: false,
+ };
+ this.optionsManager.options = options;
+ this.optionsManager.resetAll();
+ },
+ scope: this,
+ });
+ },
+});
+/**
+ * Deluge.add.UrlWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.add');
+Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, {
+ title: _('Add from Url'),
+ modal: true,
+ plain: true,
+ layout: 'fit',
+ width: 350,
+ height: 155,
+
+ buttonAlign: 'center',
+ closeAction: 'hide',
+ bodyStyle: 'padding: 10px 5px;',
+ iconCls: 'x-deluge-add-url-window-icon',
+
+ initComponent: function() {
+ Deluge.add.UrlWindow.superclass.initComponent.call(this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ var form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ });
+
+ this.urlField = form.add({
+ fieldLabel: _('Url'),
+ id: 'url',
+ name: 'url',
+ width: '97%',
+ });
+ this.urlField.on('specialkey', this.onAdd, this);
+
+ this.cookieField = form.add({
+ fieldLabel: _('Cookies'),
+ id: 'cookies',
+ name: 'cookies',
+ width: '97%',
+ });
+ this.cookieField.on('specialkey', this.onAdd, this);
+ },
+
+ onAddClick: function(field, e) {
+ if (
+ (field.id == 'url' || field.id == 'cookies') &&
+ e.getKey() != e.ENTER
+ )
+ return;
+
+ var field = this.urlField;
+ var url = field.getValue();
+ var cookies = this.cookieField.getValue();
+ var torrentId = this.createTorrentId();
+
+ if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) {
+ deluge.client.web.get_magnet_info(url, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: url,
+ torrentId: torrentId,
+ });
+ } else {
+ deluge.client.web.download_torrent_from_url(url, cookies, {
+ success: this.onDownload,
+ scope: this,
+ torrentId: torrentId,
+ });
+ }
+
+ this.hide();
+ this.urlField.setValue('');
+ this.fireEvent('beforeadd', torrentId, url);
+ },
+
+ onDownload: function(filename, obj, resp, req) {
+ deluge.client.web.get_torrent_info(filename, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: filename,
+ torrentId: req.options.torrentId,
+ });
+ },
+
+ onGotInfo: function(info, obj, response, request) {
+ info['filename'] = request.options.filename;
+ this.fireEvent('add', request.options.torrentId, info);
+ },
+});
+/**
+ * Deluge.data.SortTypes.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Common sort functions that can be used for data Stores.
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.SortTypes
+ * @singleton
+ */
+Deluge.data.SortTypes = {
+ // prettier-ignore
+ asIPAddress: function(value) {
+ var d = value.match(
+ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/
+ );
+ return ((+d[1] * 256 + (+d[2])) * 256 + (+d[3])) * 256 + (+d[4]);
+ },
+
+ asQueuePosition: function(value) {
+ return value > -1 ? value : Number.MAX_VALUE;
+ },
+
+ asName: function(value) {
+ return String(value).toLowerCase();
+ },
+};
+/**
+ * Deluge.data.PeerRecord.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Deluge.data.Peer record
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.Peer
+ * @extends Ext.data.Record
+ * @constructor
+ * @param {Object} data The peer data
+ */
+Deluge.data.Peer = Ext.data.Record.create([
+ {
+ name: 'country',
+ type: 'string',
+ },
+ {
+ name: 'ip',
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asIPAddress,
+ },
+ {
+ name: 'client',
+ type: 'string',
+ },
+ {
+ name: 'progress',
+ type: 'float',
+ },
+ {
+ name: 'down_speed',
+ type: 'int',
+ },
+ {
+ name: 'up_speed',
+ type: 'int',
+ },
+ {
+ name: 'seed',
+ type: 'int',
+ },
+]);
+/**
+ * Deluge.data.TorrentRecord.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Deluge.data.Torrent record
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.Torrent
+ * @extends Ext.data.Record
+ * @constructor
+ * @param {Object} data The torrents data
+ */
+Deluge.data.Torrent = Ext.data.Record.create([
+ {
+ name: 'queue',
+ type: 'int',
+ },
+ {
+ name: 'name',
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asName,
+ },
+ {
+ name: 'total_wanted',
+ type: 'int',
+ },
+ {
+ name: 'state',
+ type: 'string',
+ },
+ {
+ name: 'progress',
+ type: 'int',
+ },
+ {
+ name: 'num_seeds',
+ type: 'int',
+ },
+ {
+ name: 'total_seeds',
+ type: 'int',
+ },
+ {
+ name: 'num_peers',
+ type: 'int',
+ },
+ {
+ name: 'total_peers',
+ type: 'int',
+ },
+ {
+ name: 'download_payload_rate',
+ type: 'int',
+ },
+ {
+ name: 'upload_payload_rate',
+ type: 'int',
+ },
+ {
+ name: 'eta',
+ type: 'int',
+ },
+ {
+ name: 'ratio',
+ type: 'float',
+ },
+ {
+ name: 'distributed_copies',
+ type: 'float',
+ },
+ {
+ name: 'time_added',
+ type: 'int',
+ },
+ {
+ name: 'tracker_host',
+ type: 'string',
+ },
+ {
+ name: 'save_path',
+ type: 'string',
+ },
+ {
+ name: 'total_done',
+ type: 'int',
+ },
+ {
+ name: 'total_uploaded',
+ type: 'int',
+ },
+ {
+ name: 'total_remaining',
+ type: 'int',
+ },
+ {
+ name: 'max_download_speed',
+ type: 'int',
+ },
+ {
+ name: 'max_upload_speed',
+ type: 'int',
+ },
+ {
+ name: 'seeds_peers_ratio',
+ type: 'float',
+ },
+ {
+ name: 'time_since_transfer',
+ type: 'int',
+ },
+]);
+/**
+ * Deluge.details.DetailsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.details');
+
+/**
+ * @class Deluge.details.DetailsPanel
+ */
+Deluge.details.DetailsPanel = Ext.extend(Ext.TabPanel, {
+ id: 'torrentDetails',
+ activeTab: 0,
+
+ initComponent: function() {
+ Deluge.details.DetailsPanel.superclass.initComponent.call(this);
+ this.add(new Deluge.details.StatusTab());
+ this.add(new Deluge.details.DetailsTab());
+ this.add(new Deluge.details.FilesTab());
+ this.add(new Deluge.details.PeersTab());
+ this.add(new Deluge.details.OptionsTab());
+ },
+
+ clear: function() {
+ this.items.each(function(panel) {
+ if (panel.clear) {
+ panel.clear.defer(100, panel);
+ panel.disable();
+ }
+ });
+ },
+
+ update: function(tab) {
+ var torrent = deluge.torrents.getSelected();
+ if (!torrent) {
+ this.clear();
+ return;
+ }
+
+ this.items.each(function(tab) {
+ if (tab.disabled) tab.enable();
+ });
+
+ tab = tab || this.getActiveTab();
+ if (tab.update) tab.update(torrent.id);
+ },
+
+ /* Event Handlers */
+
+ // We need to add the events in onRender since Deluge.Torrents has not been created yet.
+ onRender: function(ct, position) {
+ Deluge.details.DetailsPanel.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+ deluge.events.on('disconnect', this.clear, this);
+ deluge.torrents.on('rowclick', this.onTorrentsClick, this);
+ this.on('tabchange', this.onTabChange, this);
+
+ deluge.torrents.getSelectionModel().on(
+ 'selectionchange',
+ function(selModel) {
+ if (!selModel.hasSelection()) this.clear();
+ },
+ this
+ );
+ },
+
+ onTabChange: function(panel, tab) {
+ this.update(tab);
+ },
+
+ onTorrentsClick: function(grid, rowIndex, e) {
+ this.update();
+ },
+});
+/**
+ * Deluge.Details.Details.js
+ * The details tab displayed in the details panel.
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
+ title: _('Details'),
+
+ fields: {},
+ autoScroll: true,
+ queuedItems: {},
+
+ oldData: {},
+
+ initComponent: function() {
+ Deluge.details.DetailsTab.superclass.initComponent.call(this);
+ this.addItem('torrent_name', _('Name:'));
+ this.addItem('hash', _('Hash:'));
+ this.addItem('path', _('Download Folder:'));
+ this.addItem('size', _('Total Size:'));
+ this.addItem('files', _('Total Files:'));
+ this.addItem('comment', _('Comment:'));
+ this.addItem('status', _('Status:'));
+ this.addItem('tracker', _('Tracker:'));
+ this.addItem('creator', _('Created By:'));
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.DetailsTab.superclass.onRender.call(this, ct, position);
+ this.body.setStyle('padding', '10px');
+ this.dl = Ext.DomHelper.append(this.body, { tag: 'dl' }, true);
+
+ for (var id in this.queuedItems) {
+ this.doAddItem(id, this.queuedItems[id]);
+ }
+ },
+
+ addItem: function(id, label) {
+ if (!this.rendered) {
+ this.queuedItems[id] = label;
+ } else {
+ this.doAddItem(id, label);
+ }
+ },
+
+ // private
+ doAddItem: function(id, label) {
+ Ext.DomHelper.append(this.dl, { tag: 'dt', cls: id, html: label });
+ this.fields[id] = Ext.DomHelper.append(
+ this.dl,
+ { tag: 'dd', cls: id, html: '' },
+ true
+ );
+ },
+
+ clear: function() {
+ if (!this.fields) return;
+ for (var k in this.fields) {
+ this.fields[k].dom.innerHTML = '';
+ }
+ this.oldData = {};
+ },
+
+ update: function(torrentId) {
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Details, {
+ success: this.onRequestComplete,
+ scope: this,
+ torrentId: torrentId,
+ });
+ },
+
+ onRequestComplete: function(torrent, request, response, options) {
+ var data = {
+ torrent_name: torrent.name,
+ hash: options.options.torrentId,
+ path: torrent.download_location,
+ size: fsize(torrent.total_size),
+ files: torrent.num_files,
+ status: torrent.message,
+ tracker: torrent.tracker_host,
+ comment: torrent.comment,
+ creator: torrent.creator,
+ };
+
+ for (var field in this.fields) {
+ if (!Ext.isDefined(data[field])) continue; // This is a field we are not responsible for.
+ if (data[field] == this.oldData[field]) continue;
+ this.fields[field].dom.innerHTML = Ext.escapeHTML(data[field]);
+ }
+ this.oldData = data;
+ },
+});
+/**
+ * Deluge.details.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
+ title: _('Files'),
+
+ rootVisible: false,
+
+ columns: [
+ {
+ header: _('Filename'),
+ width: 330,
+ dataIndex: 'filename',
+ },
+ {
+ header: _('Size'),
+ width: 150,
+ dataIndex: 'size',
+ tpl: new Ext.XTemplate('{size:this.fsize}', {
+ fsize: function(v) {
+ return fsize(v);
+ },
+ }),
+ },
+ {
+ xtype: 'tgrendercolumn',
+ header: _('Progress'),
+ width: 150,
+ dataIndex: 'progress',
+ renderer: function(v) {
+ var progress = v * 100;
+ return Deluge.progressBar(
+ progress,
+ this.col.width,
+ progress.toFixed(2) + '%',
+ 0
+ );
+ },
+ },
+ {
+ header: _('Priority'),
+ width: 150,
+ dataIndex: 'priority',
+ tpl: new Ext.XTemplate(
+ '<tpl if="!isNaN(priority)">' +
+ '<div class="{priority:this.getClass}">' +
+ '{priority:this.getName}' +
+ '</div></tpl>',
+ {
+ getClass: function(v) {
+ return FILE_PRIORITY_CSS[v];
+ },
+
+ getName: function(v) {
+ return _(FILE_PRIORITY[v]);
+ },
+ }
+ ),
+ },
+ ],
+
+ selModel: new Ext.tree.MultiSelectionModel(),
+
+ initComponent: function() {
+ Deluge.details.FilesTab.superclass.initComponent.call(this);
+ this.setRootNode(new Ext.tree.TreeNode({ text: _('Files') }));
+ },
+
+ clear: function() {
+ var root = this.getRootNode();
+ if (!root.hasChildNodes()) return;
+ root.cascade(function(node) {
+ var parentNode = node.parentNode;
+ if (!parentNode) return;
+ if (!parentNode.ownerTree) return;
+ parentNode.removeChild(node);
+ });
+ },
+
+ createFileTree: function(files) {
+ function walk(files, parentNode) {
+ for (var file in files.contents) {
+ var item = files.contents[file];
+ if (item.type == 'dir') {
+ walk(
+ item,
+ parentNode.appendChild(
+ new Ext.tree.TreeNode({
+ text: file,
+ filename: file,
+ size: item.size,
+ progress: item.progress,
+ priority: item.priority,
+ })
+ )
+ );
+ } else {
+ parentNode.appendChild(
+ new Ext.tree.TreeNode({
+ text: file,
+ filename: file,
+ fileIndex: item.index,
+ size: item.size,
+ progress: item.progress,
+ priority: item.priority,
+ leaf: true,
+ iconCls: 'x-deluge-file',
+ uiProvider: Ext.ux.tree.TreeGridNodeUI,
+ })
+ );
+ }
+ }
+ }
+ var root = this.getRootNode();
+ walk(files, root);
+ root.firstChild.expand();
+ },
+
+ update: function(torrentId) {
+ if (this.torrentId != torrentId) {
+ this.clear();
+ this.torrentId = torrentId;
+ }
+
+ deluge.client.web.get_torrent_files(torrentId, {
+ success: this.onRequestComplete,
+ scope: this,
+ torrentId: torrentId,
+ });
+ },
+
+ updateFileTree: function(files) {
+ function walk(files, parentNode) {
+ for (var file in files.contents) {
+ var item = files.contents[file];
+ var node = parentNode.findChild('filename', file);
+ node.attributes.size = item.size;
+ node.attributes.progress = item.progress;
+ node.attributes.priority = item.priority;
+ node.ui.updateColumns();
+ if (item.type == 'dir') {
+ walk(item, node);
+ }
+ }
+ }
+ walk(files, this.getRootNode());
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.FilesTab.superclass.onRender.call(this, ct, position);
+ deluge.menus.filePriorities.on('itemclick', this.onItemClick, this);
+ this.on('contextmenu', this.onContextMenu, this);
+ this.sorter = new Ext.tree.TreeSorter(this, {
+ folderSort: true,
+ });
+ },
+
+ onContextMenu: function(node, e) {
+ e.stopEvent();
+ var selModel = this.getSelectionModel();
+ if (selModel.getSelectedNodes().length < 2) {
+ selModel.clearSelections();
+ node.select();
+ }
+ deluge.menus.filePriorities.showAt(e.getPoint());
+ },
+
+ onItemClick: function(baseItem, e) {
+ switch (baseItem.id) {
+ case 'expandAll':
+ this.expandAll();
+ break;
+ default:
+ var indexes = {};
+ var walk = function(node) {
+ if (Ext.isEmpty(node.attributes.fileIndex)) return;
+ indexes[node.attributes.fileIndex] =
+ node.attributes.priority;
+ };
+ this.getRootNode().cascade(walk);
+
+ var nodes = this.getSelectionModel().getSelectedNodes();
+ Ext.each(nodes, function(node) {
+ if (!node.isLeaf()) {
+ var setPriorities = function(node) {
+ if (Ext.isEmpty(node.attributes.fileIndex)) return;
+ indexes[node.attributes.fileIndex] =
+ baseItem.filePriority;
+ };
+ node.cascade(setPriorities);
+ } else if (!Ext.isEmpty(node.attributes.fileIndex)) {
+ indexes[node.attributes.fileIndex] =
+ baseItem.filePriority;
+ return;
+ }
+ });
+
+ var priorities = new Array(Ext.keys(indexes).length);
+ for (var index in indexes) {
+ priorities[index] = indexes[index];
+ }
+
+ deluge.client.core.set_torrent_options(
+ [this.torrentId],
+ { file_priorities: priorities },
+ {
+ success: function() {
+ Ext.each(nodes, function(node) {
+ node.setColumnValue(3, baseItem.filePriority);
+ });
+ },
+ scope: this,
+ }
+ );
+ break;
+ }
+ },
+
+ onRequestComplete: function(files, options) {
+ if (!this.getRootNode().hasChildNodes()) {
+ this.createFileTree(files);
+ } else {
+ this.updateFileTree(files);
+ }
+ },
+});
+/**
+ * Deluge.details.OptionsTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ autoScroll: true,
+ bodyStyle: 'padding: 5px;',
+ border: false,
+ cls: 'x-deluge-options',
+ defaults: {
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ },
+ deferredRender: false,
+ layout: 'column',
+ title: _('Options'),
+ },
+ config
+ );
+ Deluge.details.OptionsTab.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.details.OptionsTab.superclass.initComponent.call(this);
+
+ (this.fieldsets = {}), (this.fields = {});
+ this.optionsManager = new Deluge.MultiOptionsManager({
+ options: {
+ max_download_speed: -1,
+ max_upload_speed: -1,
+ max_connections: -1,
+ max_upload_slots: -1,
+ auto_managed: false,
+ stop_at_ratio: false,
+ stop_ratio: 2.0,
+ remove_at_ratio: false,
+ move_completed: false,
+ move_completed_path: '',
+ private: false,
+ prioritize_first_last: false,
+ super_seeding: false,
+ },
+ });
+
+ /*
+ * Bandwidth Options
+ */
+ this.fieldsets.bandwidth = this.add({
+ xtype: 'fieldset',
+ defaultType: 'spinnerfield',
+ bodyStyle: 'padding: 5px',
+
+ layout: 'table',
+ layoutConfig: { columns: 3 },
+ labelWidth: 150,
+
+ style: 'margin-left: 10px; margin-right: 5px; padding: 5px',
+ title: _('Bandwidth'),
+ width: 250,
+ });
+
+ /*
+ * Max Download Speed
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Download Speed:'),
+ forId: 'max_download_speed',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_download_speed = this.fieldsets.bandwidth.add({
+ id: 'max_download_speed',
+ name: 'max_download_speed',
+ width: 70,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 1,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ });
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('KiB/s'),
+ style: 'margin-left: 10px',
+ });
+
+ /*
+ * Max Upload Speed
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Upload Speed:'),
+ forId: 'max_upload_speed',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_upload_speed = this.fieldsets.bandwidth.add({
+ id: 'max_upload_speed',
+ name: 'max_upload_speed',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 1,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ });
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('KiB/s'),
+ style: 'margin-left: 10px',
+ });
+
+ /*
+ * Max Connections
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Connections:'),
+ forId: 'max_connections',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_connections = this.fieldsets.bandwidth.add({
+ id: 'max_connections',
+ name: 'max_connections',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ colspan: 2,
+ });
+
+ /*
+ * Max Upload Slots
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Upload Slots:'),
+ forId: 'max_upload_slots',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_upload_slots = this.fieldsets.bandwidth.add({
+ id: 'max_upload_slots',
+ name: 'max_upload_slots',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ colspan: 2,
+ });
+
+ /*
+ * Queue Options
+ */
+ this.fieldsets.queue = this.add({
+ xtype: 'fieldset',
+ title: _('Queue'),
+ style: 'margin-left: 5px; margin-right: 5px; padding: 5px',
+ width: 210,
+
+ layout: 'table',
+ layoutConfig: { columns: 2 },
+ labelWidth: 0,
+
+ defaults: {
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+
+ this.fields.auto_managed = this.fieldsets.queue.add({
+ xtype: 'checkbox',
+ fieldLabel: '',
+ labelSeparator: '',
+ name: 'is_auto_managed',
+ boxLabel: _('Auto Managed'),
+ width: 200,
+ colspan: 2,
+ });
+
+ this.fields.stop_at_ratio = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'stop_at_ratio',
+ width: 120,
+ boxLabel: _('Stop seed at ratio:'),
+ handler: this.onStopRatioChecked,
+ scope: this,
+ });
+
+ this.fields.stop_ratio = this.fieldsets.queue.add({
+ xtype: 'spinnerfield',
+ id: 'stop_ratio',
+ name: 'stop_ratio',
+ disabled: true,
+ width: 50,
+ value: 2.0,
+ strategy: {
+ xtype: 'number',
+ minValue: -1,
+ maxValue: 99999,
+ incrementValue: 0.1,
+ alternateIncrementValue: 1,
+ decimalPrecision: 1,
+ },
+ });
+
+ this.fields.remove_at_ratio = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'remove_at_ratio',
+ ctCls: 'x-deluge-indent-checkbox',
+ bodyStyle: 'padding-left: 10px',
+ boxLabel: _('Remove at ratio'),
+ disabled: true,
+ colspan: 2,
+ });
+
+ this.fields.move_completed = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'move_completed',
+ boxLabel: _('Move Completed:'),
+ colspan: 2,
+ handler: this.onMoveCompletedChecked,
+ scope: this,
+ });
+
+ this.fields.move_completed_path = this.fieldsets.queue.add({
+ xtype: 'textfield',
+ fieldLabel: '',
+ id: 'move_completed_path',
+ colspan: 3,
+ bodyStyle: 'margin-left: 20px',
+ width: 180,
+ disabled: true,
+ });
+
+ /*
+ * General Options
+ */
+ this.rightColumn = this.add({
+ border: false,
+ autoHeight: true,
+ style: 'margin-left: 5px',
+ width: 210,
+ });
+
+ this.fieldsets.general = this.rightColumn.add({
+ xtype: 'fieldset',
+ autoHeight: true,
+ defaultType: 'checkbox',
+ title: _('General'),
+ layout: 'form',
+ });
+
+ this.fields['private'] = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Private'),
+ id: 'private',
+ disabled: true,
+ });
+
+ this.fields.prioritize_first_last = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Prioritize First/Last'),
+ id: 'prioritize_first_last',
+ });
+
+ this.fields.super_seeding = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Super Seeding'),
+ id: 'super_seeding',
+ });
+
+ // Bind the fields so the options manager can manage them.
+ for (var id in this.fields) {
+ this.optionsManager.bind(id, this.fields[id]);
+ }
+
+ /*
+ * Buttons
+ */
+ this.buttonPanel = this.rightColumn.add({
+ layout: 'hbox',
+ xtype: 'panel',
+ border: false,
+ });
+
+ /*
+ * Edit Trackers button
+ */
+ this.buttonPanel.add({
+ id: 'edit_trackers',
+ xtype: 'button',
+ text: _('Edit Trackers'),
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-edit-trackers',
+ border: false,
+ width: 100,
+ handler: this.onEditTrackers,
+ scope: this,
+ });
+
+ /*
+ * Apply button
+ */
+ this.buttonPanel.add({
+ id: 'apply',
+ xtype: 'button',
+ text: _('Apply'),
+ style: 'margin-left: 10px;',
+ border: false,
+ width: 100,
+ handler: this.onApply,
+ scope: this,
+ });
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position);
+
+ // This is another hack I think, so keep an eye out here when upgrading.
+ this.layout = new Ext.layout.ColumnLayout();
+ this.layout.setContainer(this);
+ this.doLayout();
+ },
+
+ clear: function() {
+ if (this.torrentId == null) return;
+ this.torrentId = null;
+ this.optionsManager.changeId(null);
+ },
+
+ reset: function() {
+ if (this.torrentId) this.optionsManager.reset();
+ },
+
+ update: function(torrentId) {
+ if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds
+
+ if (!torrentId) return; // We do not care about null torrentIds.
+
+ if (this.torrentId != torrentId) {
+ this.torrentId = torrentId;
+ this.optionsManager.changeId(torrentId);
+ }
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Options, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onApply: function() {
+ var changed = this.optionsManager.getDirty();
+ deluge.client.core.set_torrent_options([this.torrentId], changed, {
+ success: function() {
+ this.optionsManager.commit();
+ },
+ scope: this,
+ });
+ },
+
+ onEditTrackers: function() {
+ deluge.editTrackers.show();
+ },
+
+ onMoveCompletedChecked: function(checkbox, checked) {
+ this.fields.move_completed_path.setDisabled(!checked);
+
+ if (!checked) return;
+ this.fields.move_completed_path.focus();
+ },
+
+ onStopRatioChecked: function(checkbox, checked) {
+ this.fields.remove_at_ratio.setDisabled(!checked);
+ this.fields.stop_ratio.setDisabled(!checked);
+ },
+
+ onRequestComplete: function(torrent, options) {
+ this.fields['private'].setValue(torrent['private']);
+ this.fields['private'].setDisabled(true);
+ delete torrent['private'];
+ torrent['auto_managed'] = torrent['is_auto_managed'];
+ torrent['prioritize_first_last_pieces'] =
+ torrent['prioritize_first_last'];
+ this.optionsManager.setDefault(torrent);
+ var stop_at_ratio = this.optionsManager.get('stop_at_ratio');
+ this.fields.remove_at_ratio.setDisabled(!stop_at_ratio);
+ this.fields.stop_ratio.setDisabled(!stop_at_ratio);
+ this.fields.move_completed_path.setDisabled(
+ !this.optionsManager.get('move_completed')
+ );
+ },
+});
+/**
+ * Deluge.details.PeersTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+(function() {
+ function flagRenderer(value) {
+ if (!value.replace(' ', '').replace(' ', '')) {
+ return '';
+ }
+ return String.format(
+ '<img src="{0}flag/{1}" />',
+ deluge.config.base,
+ value
+ );
+ }
+ function peerAddressRenderer(value, p, record) {
+ var seed =
+ record.data['seed'] == 1024 ? 'x-deluge-seed' : 'x-deluge-peer';
+ // Modify display of IPv6 to include brackets
+ var peer_ip = value.split(':');
+ if (peer_ip.length > 2) {
+ var port = peer_ip.pop();
+ var ip = peer_ip.join(':');
+ value = '[' + ip + ']:' + port;
+ }
+ return String.format('<div class="{0}">{1}</div>', seed, value);
+ }
+ function peerProgressRenderer(value) {
+ var progress = (value * 100).toFixed(0);
+ return Deluge.progressBar(progress, this.width - 8, progress + '%');
+ }
+
+ Deluge.details.PeersTab = Ext.extend(Ext.grid.GridPanel, {
+ // fast way to figure out if we have a peer already.
+ peers: {},
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ title: _('Peers'),
+ cls: 'x-deluge-peers',
+ store: new Ext.data.Store({
+ reader: new Ext.data.JsonReader(
+ {
+ idProperty: 'ip',
+ root: 'peers',
+ },
+ Deluge.data.Peer
+ ),
+ }),
+ columns: [
+ {
+ header: '&nbsp;',
+ width: 30,
+ sortable: true,
+ renderer: flagRenderer,
+ dataIndex: 'country',
+ },
+ {
+ header: _('Address'),
+ width: 125,
+ sortable: true,
+ renderer: peerAddressRenderer,
+ dataIndex: 'ip',
+ },
+ {
+ header: _('Client'),
+ width: 125,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'client',
+ },
+ {
+ header: _('Progress'),
+ width: 150,
+ sortable: true,
+ renderer: peerProgressRenderer,
+ dataIndex: 'progress',
+ },
+ {
+ header: _('Down Speed'),
+ width: 100,
+ sortable: true,
+ renderer: fspeed,
+ dataIndex: 'down_speed',
+ },
+ {
+ header: _('Up Speed'),
+ width: 100,
+ sortable: true,
+ renderer: fspeed,
+ dataIndex: 'up_speed',
+ },
+ ],
+ stripeRows: true,
+ deferredRender: false,
+ autoScroll: true,
+ },
+ config
+ );
+ Deluge.details.PeersTab.superclass.constructor.call(this, config);
+ },
+
+ clear: function() {
+ this.getStore().removeAll();
+ this.peers = {};
+ },
+
+ update: function(torrentId) {
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onRequestComplete: function(torrent, options) {
+ if (!torrent) return;
+
+ var store = this.getStore();
+ var newPeers = [];
+ var addresses = {};
+
+ // Go through the peers updating and creating peer records
+ Ext.each(
+ torrent.peers,
+ function(peer) {
+ if (this.peers[peer.ip]) {
+ var record = store.getById(peer.ip);
+ record.beginEdit();
+ for (var k in peer) {
+ if (record.get(k) != peer[k]) {
+ record.set(k, peer[k]);
+ }
+ }
+ record.endEdit();
+ } else {
+ this.peers[peer.ip] = 1;
+ newPeers.push(new Deluge.data.Peer(peer, peer.ip));
+ }
+ addresses[peer.ip] = 1;
+ },
+ this
+ );
+ store.add(newPeers);
+
+ // Remove any peers that should not be left in the store.
+ store.each(function(record) {
+ if (!addresses[record.id]) {
+ store.remove(record);
+ delete this.peers[record.id];
+ }
+ }, this);
+ store.commitChanges();
+
+ var sortState = store.getSortState();
+ if (!sortState) return;
+ store.sort(sortState.field, sortState.direction);
+ },
+ });
+})();
+/**
+ * Deluge.details.StatusTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.details');
+
+/**
+ * @class Deluge.details.StatusTab
+ * @extends Ext.Panel
+ */
+Deluge.details.StatusTab = Ext.extend(Ext.Panel, {
+ title: _('Status'),
+ autoScroll: true,
+
+ onRender: function(ct, position) {
+ Deluge.details.StatusTab.superclass.onRender.call(this, ct, position);
+
+ this.progressBar = this.add({
+ xtype: 'progress',
+ cls: 'x-deluge-status-progressbar',
+ });
+
+ this.status = this.add({
+ cls: 'x-deluge-status',
+ id: 'deluge-details-status',
+
+ border: false,
+ width: 1000,
+ listeners: {
+ render: {
+ fn: function(panel) {
+ panel.load({
+ url: deluge.config.base + 'render/tab_status.html',
+ text: _('Loading') + '...',
+ });
+ panel
+ .getUpdater()
+ .on('update', this.onPanelUpdate, this);
+ },
+ scope: this,
+ },
+ },
+ });
+ },
+
+ clear: function() {
+ this.progressBar.updateProgress(0, ' ');
+ for (var k in this.fields) {
+ this.fields[k].innerHTML = '';
+ }
+ },
+
+ update: function(torrentId) {
+ if (!this.fields) this.getFields();
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Status, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onPanelUpdate: function(el, response) {
+ this.fields = {};
+ Ext.each(
+ Ext.query('dd', this.status.body.dom),
+ function(field) {
+ this.fields[field.className] = field;
+ },
+ this
+ );
+ },
+
+ onRequestComplete: function(status) {
+ seeds =
+ status.total_seeds > -1
+ ? status.num_seeds + ' (' + status.total_seeds + ')'
+ : status.num_seeds;
+ peers =
+ status.total_peers > -1
+ ? status.num_peers + ' (' + status.total_peers + ')'
+ : status.num_peers;
+ last_seen_complete =
+ status.last_seen_complete > 0.0
+ ? fdate(status.last_seen_complete)
+ : 'Never';
+ completed_time =
+ status.completed_time > 0.0 ? fdate(status.completed_time) : '';
+
+ var data = {
+ downloaded: fsize(status.total_done, true),
+ uploaded: fsize(status.total_uploaded, true),
+ share: status.ratio == -1 ? '&infin;' : status.ratio.toFixed(3),
+ announce: ftime(status.next_announce),
+ tracker_status: status.tracker_status,
+ downspeed: status.download_payload_rate
+ ? fspeed(status.download_payload_rate)
+ : '0.0 KiB/s',
+ upspeed: status.upload_payload_rate
+ ? fspeed(status.upload_payload_rate)
+ : '0.0 KiB/s',
+ eta: status.eta < 0 ? '&infin;' : ftime(status.eta),
+ pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
+ seeds: seeds,
+ peers: peers,
+ avail: status.distributed_copies.toFixed(3),
+ active_time: ftime(status.active_time),
+ seeding_time: ftime(status.seeding_time),
+ seed_rank: status.seed_rank,
+ time_added: fdate(status.time_added),
+ last_seen_complete: last_seen_complete,
+ completed_time: completed_time,
+ time_since_transfer: ftime(status.time_since_transfer),
+ };
+ data.auto_managed = _(status.is_auto_managed ? 'True' : 'False');
+
+ var translate_tracker_status = {
+ Error: _('Error'),
+ Warning: _('Warning'),
+ 'Announce OK': _('Announce OK'),
+ 'Announce Sent': _('Announce Sent'),
+ };
+ for (var key in translate_tracker_status) {
+ if (data.tracker_status.indexOf(key) != -1) {
+ data.tracker_status = data.tracker_status.replace(
+ key,
+ translate_tracker_status[key]
+ );
+ break;
+ }
+ }
+
+ data.downloaded +=
+ ' (' +
+ (status.total_payload_download
+ ? fsize(status.total_payload_download)
+ : '0.0 KiB') +
+ ')';
+ data.uploaded +=
+ ' (' +
+ (status.total_payload_upload
+ ? fsize(status.total_payload_upload)
+ : '0.0 KiB') +
+ ')';
+
+ for (var field in this.fields) {
+ this.fields[field].innerHTML = data[field];
+ }
+ var text = status.state + ' ' + status.progress.toFixed(2) + '%';
+ this.progressBar.updateProgress(status.progress / 100.0, text);
+ },
+});
+/**
+ * Deluge.preferences.BandwidthPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Bandwidth
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Bandwidth'),
+ header: false,
+ layout: 'form',
+ labelWidth: 10,
+ },
+ config
+ );
+ Deluge.preferences.Bandwidth.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Bandwidth.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Global Bandwidth Usage'),
+ labelWidth: 200,
+ defaultType: 'spinnerfield',
+ defaults: {
+ minValue: -1,
+ maxValue: 99999,
+ },
+ style: 'margin-bottom: 0px; padding-bottom: 0px;',
+ autoHeight: true,
+ });
+ om.bind(
+ 'max_connections_global',
+ fieldset.add({
+ name: 'max_connections_global',
+ fieldLabel: _('Maximum Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_slots_global',
+ fieldset.add({
+ name: 'max_upload_slots_global',
+ fieldLabel: _('Maximum Upload Slots'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_download_speed',
+ fieldset.add({
+ name: 'max_download_speed',
+ fieldLabel: _('Maximum Download Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1.0,
+ decimalPrecision: 1,
+ })
+ );
+ om.bind(
+ 'max_upload_speed',
+ fieldset.add({
+ name: 'max_upload_speed',
+ fieldLabel: _('Maximum Upload Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1.0,
+ decimalPrecision: 1,
+ })
+ );
+ om.bind(
+ 'max_half_open_connections',
+ fieldset.add({
+ name: 'max_half_open_connections',
+ fieldLabel: _('Maximum Half-Open Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_connections_per_second',
+ fieldset.add({
+ name: 'max_connections_per_second',
+ fieldLabel: _('Maximum Connection Attempts per Second:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: '',
+ defaultType: 'checkbox',
+ style:
+ 'padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;',
+ autoHeight: true,
+ });
+ om.bind(
+ 'ignore_limits_on_local_network',
+ fieldset.add({
+ name: 'ignore_limits_on_local_network',
+ height: 22,
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Ignore limits on local network'),
+ })
+ );
+ om.bind(
+ 'rate_limit_ip_overhead',
+ fieldset.add({
+ name: 'rate_limit_ip_overhead',
+ height: 22,
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Rate limit IP overhead'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Per Torrent Bandwidth Usage'),
+ style: 'margin-bottom: 0px; padding-bottom: 0px;',
+ defaultType: 'spinnerfield',
+ labelWidth: 200,
+ defaults: {
+ minValue: -1,
+ maxValue: 99999,
+ },
+ autoHeight: true,
+ });
+ om.bind(
+ 'max_connections_per_torrent',
+ fieldset.add({
+ name: 'max_connections_per_torrent',
+ fieldLabel: _('Maximum Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_slots_per_torrent',
+ fieldset.add({
+ name: 'max_upload_slots_per_torrent',
+ fieldLabel: _('Maximum Upload Slots:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_download_speed_per_torrent',
+ fieldset.add({
+ name: 'max_download_speed_per_torrent',
+ fieldLabel: _('Maximum Download Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_speed_per_torrent',
+ fieldset.add({
+ name: 'max_upload_speed_per_torrent',
+ fieldLabel: _('Maximum Upload Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.CachePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Cache
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Cache = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Cache'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Cache.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Settings'),
+ autoHeight: true,
+ labelWidth: 180,
+ defaultType: 'spinnerfield',
+ defaults: {
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 999999,
+ },
+ });
+ om.bind(
+ 'cache_size',
+ fieldset.add({
+ fieldLabel: _('Cache Size (16 KiB Blocks):'),
+ labelSeparator: '',
+ name: 'cache_size',
+ width: 60,
+ value: 512,
+ })
+ );
+ om.bind(
+ 'cache_expiry',
+ fieldset.add({
+ fieldLabel: _('Cache Expiry (seconds):'),
+ labelSeparator: '',
+ name: 'cache_expiry',
+ width: 60,
+ value: 60,
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.DaemonPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Daemon
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Daemon'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Daemon.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Port'),
+ autoHeight: true,
+ defaultType: 'spinnerfield',
+ });
+ om.bind(
+ 'daemon_port',
+ fieldset.add({
+ fieldLabel: _('Daemon port:'),
+ labelSeparator: '',
+ name: 'daemon_port',
+ value: 58846,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Connections'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'allow_remote',
+ fieldset.add({
+ fieldLabel: '',
+ height: 22,
+ labelSeparator: '',
+ boxLabel: _('Allow Remote Connections'),
+ name: 'allow_remote',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Other'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'new_release_check',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 40,
+ boxLabel: _('Periodically check the website for new releases'),
+ id: 'new_release_check',
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.DownloadsPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Downloads
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Downloads = Ext.extend(Ext.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Downloads'),
+ header: false,
+ layout: 'form',
+ autoHeight: true,
+ width: 320,
+ },
+ config
+ );
+ Deluge.preferences.Downloads.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Downloads.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Folders'),
+ labelWidth: 150,
+ defaultType: 'togglefield',
+ autoHeight: true,
+ labelAlign: 'top',
+ width: 300,
+ style: 'margin-bottom: 5px; padding-bottom: 5px;',
+ });
+
+ optMan.bind(
+ 'download_location',
+ fieldset.add({
+ xtype: 'textfield',
+ name: 'download_location',
+ fieldLabel: _('Download to:'),
+ labelSeparator: '',
+ width: 280,
+ })
+ );
+
+ var field = fieldset.add({
+ name: 'move_completed_path',
+ fieldLabel: _('Move completed to:'),
+ labelSeparator: '',
+ width: 280,
+ });
+ optMan.bind('move_completed', field.toggle);
+ optMan.bind('move_completed_path', field.input);
+
+ field = fieldset.add({
+ name: 'torrentfiles_location',
+ fieldLabel: _('Copy of .torrent files to:'),
+ labelSeparator: '',
+ width: 280,
+ });
+ optMan.bind('copy_torrent_file', field.toggle);
+ optMan.bind('torrentfiles_location', field.input);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Options'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ style: 'margin-bottom: 0; padding-bottom: 0;',
+ width: 280,
+ });
+ optMan.bind(
+ 'prioritize_first_last_pieces',
+ fieldset.add({
+ name: 'prioritize_first_last_pieces',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Prioritize first and last pieces of torrent'),
+ })
+ );
+ optMan.bind(
+ 'sequential_download',
+ fieldset.add({
+ name: 'sequential_download',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Sequential download'),
+ })
+ );
+ optMan.bind(
+ 'add_paused',
+ fieldset.add({
+ name: 'add_paused',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Add torrents in Paused state'),
+ })
+ );
+ optMan.bind(
+ 'pre_allocate_storage',
+ fieldset.add({
+ name: 'pre_allocate_storage',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Pre-allocate disk space'),
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.EncryptionPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Encryption
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Encryption = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Encryption'),
+ header: false,
+
+ initComponent: function() {
+ Deluge.preferences.Encryption.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Settings'),
+ header: false,
+ autoHeight: true,
+ defaultType: 'combo',
+ width: 300,
+ });
+ optMan.bind(
+ 'enc_in_policy',
+ fieldset.add({
+ fieldLabel: _('Incoming:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Forced')],
+ [1, _('Enabled')],
+ [2, _('Disabled')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ optMan.bind(
+ 'enc_out_policy',
+ fieldset.add({
+ fieldLabel: _('Outgoing:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.SimpleStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Forced')],
+ [1, _('Enabled')],
+ [2, _('Disabled')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ optMan.bind(
+ 'enc_level',
+ fieldset.add({
+ fieldLabel: _('Level:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.SimpleStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Handshake')],
+ [1, _('Full Stream')],
+ [2, _('Either')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.InstallPluginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.InstallPluginWindow
+ * @extends Ext.Window
+ */
+Deluge.preferences.InstallPluginWindow = Ext.extend(Ext.Window, {
+ title: _('Install Plugin'),
+ layout: 'fit',
+ height: 115,
+ width: 350,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'center',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-install-plugin',
+ modal: true,
+ plain: true,
+
+ initComponent: function() {
+ Deluge.preferences.InstallPluginWindow.superclass.initComponent.call(
+ this
+ );
+ this.addButton(_('Install'), this.onInstall, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ labelWidth: 70,
+ autoHeight: true,
+ fileUpload: true,
+ items: [
+ {
+ xtype: 'fileuploadfield',
+ width: 240,
+ emptyText: _('Select an egg'),
+ fieldLabel: _('Plugin Egg'),
+ name: 'file',
+ buttonCfg: {
+ text: _('Browse...'),
+ },
+ },
+ ],
+ });
+ },
+
+ onInstall: function(field, e) {
+ this.form.getForm().submit({
+ url: deluge.config.base + 'upload',
+ waitMsg: _('Uploading your plugin...'),
+ success: this.onUploadSuccess,
+ scope: this,
+ });
+ },
+
+ onUploadPlugin: function(info, obj, response, request) {
+ this.fireEvent('pluginadded');
+ },
+
+ onUploadSuccess: function(fp, upload) {
+ this.hide();
+ if (upload.result.success) {
+ var filename = this.form.getForm().getFieldValues().file;
+ filename = filename.split('\\').slice(-1)[0];
+ var path = upload.result.files[0];
+ this.form.getForm().setValues({ file: '' });
+ deluge.client.web.upload_plugin(filename, path, {
+ success: this.onUploadPlugin,
+ scope: this,
+ filename: filename,
+ });
+ }
+ },
+});
+/**
+ * Deluge.preferences.InterfacePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Interface
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Interface'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Interface.superclass.initComponent.call(this);
+
+ var om = (this.optionsManager = new Deluge.OptionsManager());
+ this.on('show', this.onPageShow, this);
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Interface'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ defaults: {
+ height: 17,
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+ om.bind(
+ 'show_session_speed',
+ fieldset.add({
+ name: 'show_session_speed',
+ boxLabel: _('Show session speed in titlebar'),
+ })
+ );
+ om.bind(
+ 'sidebar_show_zero',
+ fieldset.add({
+ name: 'sidebar_show_zero',
+ boxLabel: _('Show filters with zero torrents'),
+ })
+ );
+ om.bind(
+ 'sidebar_multiple_filters',
+ fieldset.add({
+ name: 'sidebar_multiple_filters',
+ boxLabel: _('Allow the use of multiple filters at once'),
+ })
+ );
+
+ var languagePanel = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Language'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ this.language = om.bind(
+ 'language',
+ languagePanel.add({
+ xtype: 'combo',
+ labelSeparator: '',
+ name: 'language',
+ mode: 'local',
+ width: 200,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('WebUI Password'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 100,
+ defaultType: 'textfield',
+ defaults: {
+ width: 100,
+ inputType: 'password',
+ labelStyle: 'padding-left: 5px',
+ height: 20,
+ labelSeparator: '',
+ },
+ });
+
+ this.oldPassword = fieldset.add({
+ name: 'old_password',
+ fieldLabel: _('Old:'),
+ });
+ this.newPassword = fieldset.add({
+ name: 'new_password',
+ fieldLabel: _('New:'),
+ });
+ this.confirmPassword = fieldset.add({
+ name: 'confirm_password',
+ fieldLabel: _('Confirm:'),
+ });
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Server'),
+ style: 'padding-top: 5px; margin-bottom: 0px; padding-bottom: 5px',
+ autoHeight: true,
+ labelWidth: 100,
+ defaultType: 'spinnerfield',
+ defaults: {
+ labelSeparator: '',
+ labelStyle: 'padding-left: 5px',
+ height: 20,
+ width: 80,
+ },
+ });
+ om.bind(
+ 'session_timeout',
+ fieldset.add({
+ name: 'session_timeout',
+ fieldLabel: _('Session Timeout:'),
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'port',
+ fieldset.add({
+ name: 'port',
+ fieldLabel: _('Port:'),
+ decimalPrecision: 0,
+ minValue: 1,
+ maxValue: 65535,
+ })
+ );
+ this.httpsField = om.bind(
+ 'https',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'https',
+ hideLabel: true,
+ width: 300,
+ style: 'margin-left: 5px',
+ boxLabel: _(
+ 'Enable SSL (paths relative to Deluge config folder)'
+ ),
+ })
+ );
+ this.httpsField.on('check', this.onSSLCheck, this);
+ this.pkeyField = om.bind(
+ 'pkey',
+ fieldset.add({
+ xtype: 'textfield',
+ disabled: true,
+ name: 'pkey',
+ width: 180,
+ fieldLabel: _('Private Key:'),
+ })
+ );
+ this.certField = om.bind(
+ 'cert',
+ fieldset.add({
+ xtype: 'textfield',
+ disabled: true,
+ name: 'cert',
+ width: 180,
+ fieldLabel: _('Certificate:'),
+ })
+ );
+ },
+
+ onApply: function() {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ deluge.client.web.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+
+ for (var key in deluge.config) {
+ deluge.config[key] = this.optionsManager.get(key);
+ }
+ if ('language' in changed) {
+ Ext.Msg.show({
+ title: _('WebUI Language Changed'),
+ msg: _(
+ 'Do you want to refresh the page now to use the new language?'
+ ),
+ buttons: {
+ yes: _('Refresh'),
+ no: _('Close'),
+ },
+ multiline: false,
+ fn: function(btnText) {
+ if (btnText === 'yes') location.reload();
+ },
+ icon: Ext.MessageBox.QUESTION,
+ });
+ }
+ }
+ if (this.oldPassword.getValue() || this.newPassword.getValue()) {
+ this.onPasswordChange();
+ }
+ },
+
+ onOk: function() {
+ this.onApply();
+ },
+
+ onGotConfig: function(config) {
+ this.optionsManager.set(config);
+ },
+
+ onGotLanguages: function(info, obj, response, request) {
+ info.unshift(['', _('System Default')]);
+ this.language.store.loadData(info);
+ this.language.setValue(this.optionsManager.get('language'));
+ },
+
+ onPasswordChange: function() {
+ var newPassword = this.newPassword.getValue();
+ if (newPassword != this.confirmPassword.getValue()) {
+ Ext.MessageBox.show({
+ title: _('Invalid Password'),
+ msg: _("Your passwords don't match!"),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ return;
+ }
+
+ var oldPassword = this.oldPassword.getValue();
+ deluge.client.auth.change_password(oldPassword, newPassword, {
+ success: function(result) {
+ if (!result) {
+ Ext.MessageBox.show({
+ title: _('Password'),
+ msg: _('Your old password was incorrect!'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ this.oldPassword.setValue('');
+ } else {
+ Ext.MessageBox.show({
+ title: _('Change Successful'),
+ msg: _('Your password was successfully changed!'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.INFO,
+ iconCls: 'x-deluge-icon-info',
+ });
+ this.oldPassword.setValue('');
+ this.newPassword.setValue('');
+ this.confirmPassword.setValue('');
+ }
+ },
+ scope: this,
+ });
+ },
+
+ onSetConfig: function() {
+ this.optionsManager.commit();
+ },
+
+ onPageShow: function() {
+ deluge.client.web.get_config({
+ success: this.onGotConfig,
+ scope: this,
+ });
+ deluge.client.webutils.get_languages({
+ success: this.onGotLanguages,
+ scope: this,
+ });
+ },
+
+ onSSLCheck: function(e, checked) {
+ this.pkeyField.setDisabled(!checked);
+ this.certField.setDisabled(!checked);
+ },
+});
+/**
+ * Deluge.preferences.NetworkPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+// custom Vtype for vtype:'IPAddress'
+Ext.apply(Ext.form.VTypes, {
+ IPAddress: function(v) {
+ return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v);
+ },
+ IPAddressText: 'Must be a numeric IP address',
+ IPAddressMask: /[\d\.]/i,
+});
+
+/**
+ * @class Deluge.preferences.Network
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ layout: 'form',
+ title: _('Network'),
+ header: false,
+
+ initComponent: function() {
+ Deluge.preferences.Network.superclass.initComponent.call(this);
+ var optMan = deluge.preferences.getOptionsManager();
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Incoming Address'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'listen_interface',
+ fieldset.add({
+ name: 'listen_interface',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 200,
+ vtype: 'IPAddress',
+ })
+ );
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Incoming Port'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'random_port',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Use Random Port'),
+ name: 'random_port',
+ height: 22,
+ listeners: {
+ check: {
+ fn: function(e, checked) {
+ this.listenPort.setDisabled(checked);
+ },
+ scope: this,
+ },
+ },
+ })
+ );
+
+ this.listenPort = fieldset.add({
+ xtype: 'spinnerfield',
+ name: 'listen_port',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 75,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ });
+ optMan.bind('listen_ports', this.listenPort);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Outgoing Interface'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'outgoing_interface',
+ fieldset.add({
+ name: 'outgoing_interface',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 40,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Outgoing Ports'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'random_outgoing_ports',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Use Random Ports'),
+ name: 'random_outgoing_ports',
+ height: 22,
+ listeners: {
+ check: {
+ fn: function(e, checked) {
+ this.outgoingPorts.setDisabled(checked);
+ },
+ scope: this,
+ },
+ },
+ })
+ );
+ this.outgoingPorts = fieldset.add({
+ xtype: 'spinnergroup',
+ name: 'outgoing_ports',
+ fieldLabel: '',
+ labelSeparator: '',
+ colCfg: {
+ labelWidth: 40,
+ style: 'margin-right: 10px;',
+ },
+ items: [
+ {
+ fieldLabel: _('From:'),
+ labelSeparator: '',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ },
+ {
+ fieldLabel: _('To:'),
+ labelSeparator: '',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ },
+ ],
+ });
+ optMan.bind('outgoing_ports', this.outgoingPorts);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Network Extras'),
+ autoHeight: true,
+ layout: 'table',
+ layoutConfig: {
+ columns: 3,
+ },
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'upnp',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('UPnP'),
+ name: 'upnp',
+ })
+ );
+ optMan.bind(
+ 'natpmp',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('NAT-PMP'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'natpmp',
+ })
+ );
+ optMan.bind(
+ 'utpex',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Peer Exchange'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'utpex',
+ })
+ );
+ optMan.bind(
+ 'lsd',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('LSD'),
+ name: 'lsd',
+ })
+ );
+ optMan.bind(
+ 'dht',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('DHT'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'dht',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Type Of Service'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ bodyStyle: 'margin: 0px; padding: 0px',
+ autoHeight: true,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'peer_tos',
+ fieldset.add({
+ name: 'peer_tos',
+ fieldLabel: _('Peer TOS Byte:'),
+ labelSeparator: '',
+ width: 40,
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.OtherPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Other
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Other'),
+ header: false,
+ layout: 'form',
+ },
+ config
+ );
+ Deluge.preferences.Other.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Other.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Updates'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'new_release_check',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ name: 'new_release_check',
+ boxLabel: _('Be alerted about new releases'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('System Information'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ fieldset.add({
+ xtype: 'panel',
+ border: false,
+ bodyCfg: {
+ html: _(
+ 'Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.'
+ ),
+ },
+ });
+ optMan.bind(
+ 'send_info',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Yes, please send anonymous statistics'),
+ name: 'send_info',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('GeoIP Database'),
+ autoHeight: true,
+ labelWidth: 80,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'geoip_db_location',
+ fieldset.add({
+ name: 'geoip_db_location',
+ fieldLabel: _('Path:'),
+ labelSeparator: '',
+ width: 200,
+ })
+ );
+ },
+});
+/**
+ * Deluge.preferences.PluginsPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Plugins
+ * @extends Ext.Panel
+ */
+Deluge.preferences.Plugins = Ext.extend(Ext.Panel, {
+ layout: 'border',
+ title: _('Plugins'),
+ header: false,
+ border: false,
+ cls: 'x-deluge-plugins',
+
+ pluginTemplate: new Ext.Template(
+ '<dl class="singleline">' +
+ '<dt>' +
+ _('Author:') +
+ '</dt><dd>{author}</dd>' +
+ '<dt>' +
+ _('Version:') +
+ '</dt><dd>{version}</dd>' +
+ '<dt>' +
+ _('Author Email:') +
+ '</dt><dd>{email}</dd>' +
+ '<dt>' +
+ _('Homepage:') +
+ '</dt><dd>{homepage}</dd>' +
+ '<dt>' +
+ _('Details:') +
+ '</dt><dd style="white-space:normal">{details}</dd>' +
+ '</dl>'
+ ),
+
+ initComponent: function() {
+ Deluge.preferences.Plugins.superclass.initComponent.call(this);
+ this.defaultValues = {
+ version: '',
+ email: '',
+ homepage: '',
+ details: '',
+ };
+ this.pluginTemplate.compile();
+
+ var checkboxRenderer = function(v, p, record) {
+ p.css += ' x-grid3-check-col-td';
+ return (
+ '<div class="x-grid3-check-col' + (v ? '-on' : '') + '"> </div>'
+ );
+ };
+
+ this.list = this.add({
+ xtype: 'listview',
+ store: new Ext.data.ArrayStore({
+ fields: [
+ { name: 'enabled', mapping: 0 },
+ { name: 'plugin', mapping: 1, sortType: 'asUCString' },
+ ],
+ }),
+ columns: [
+ {
+ id: 'enabled',
+ header: _('Enabled'),
+ width: 0.2,
+ sortable: true,
+ tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', {
+ getCheckbox: function(v) {
+ return (
+ '<div class="x-grid3-check-col' +
+ (v ? '-on' : '') +
+ '" rel="chkbox"> </div>'
+ );
+ },
+ }),
+ dataIndex: 'enabled',
+ },
+ {
+ id: 'plugin',
+ header: _('Plugin'),
+ width: 0.8,
+ sortable: true,
+ dataIndex: 'plugin',
+ },
+ ],
+ singleSelect: true,
+ autoExpandColumn: 'plugin',
+ listeners: {
+ selectionchange: { fn: this.onPluginSelect, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ region: 'center',
+ autoScroll: true,
+ items: [this.list],
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-install-plugin',
+ text: _('Install'),
+ handler: this.onInstallPluginWindow,
+ scope: this,
+ },
+ '->',
+ {
+ cls: 'x-btn-text-icon',
+ text: _('Find More'),
+ iconCls: 'x-deluge-find-more',
+ handler: this.onFindMorePlugins,
+ scope: this,
+ },
+ ],
+ }),
+ });
+
+ var pp = (this.pluginInfo = this.add({
+ xtype: 'panel',
+ border: false,
+ height: 100,
+ region: 'south',
+ padding: '5',
+ autoScroll: true,
+ bodyCfg: {
+ style: 'white-space: nowrap',
+ },
+ }));
+
+ this.pluginInfo.on('render', this.onPluginInfoRender, this);
+ this.list.on('click', this.onNodeClick, this);
+ deluge.preferences.on('show', this.onPreferencesShow, this);
+ deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
+ deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
+ },
+
+ disablePlugin: function(plugin) {
+ deluge.client.core.disable_plugin(plugin);
+ },
+
+ enablePlugin: function(plugin) {
+ deluge.client.core.enable_plugin(plugin);
+ },
+
+ setInfo: function(plugin) {
+ if (!this.pluginInfo.rendered) return;
+ var values = plugin || this.defaultValues;
+ this.pluginInfo.body.dom.innerHTML = this.pluginTemplate.apply(values);
+ },
+
+ updatePlugins: function() {
+ var onGotAvailablePlugins = function(plugins) {
+ this.availablePlugins = plugins.sort(function(a, b) {
+ return a.toLowerCase().localeCompare(b.toLowerCase());
+ });
+
+ deluge.client.core.get_enabled_plugins({
+ success: onGotEnabledPlugins,
+ scope: this,
+ });
+ };
+
+ var onGotEnabledPlugins = function(plugins) {
+ this.enabledPlugins = plugins;
+ this.onGotPlugins();
+ };
+
+ deluge.client.core.get_available_plugins({
+ success: onGotAvailablePlugins,
+ scope: this,
+ });
+ },
+
+ updatePluginsGrid: function() {
+ var plugins = [];
+ Ext.each(
+ this.availablePlugins,
+ function(plugin) {
+ if (this.enabledPlugins.indexOf(plugin) > -1) {
+ plugins.push([true, plugin]);
+ } else {
+ plugins.push([false, plugin]);
+ }
+ },
+ this
+ );
+ this.list.getStore().loadData(plugins);
+ },
+
+ onNodeClick: function(dv, index, node, e) {
+ var el = new Ext.Element(e.target);
+ if (el.getAttribute('rel') != 'chkbox') return;
+
+ var r = dv.getStore().getAt(index);
+ if (r.get('plugin') == 'WebUi') return;
+ r.set('enabled', !r.get('enabled'));
+ r.commit();
+ if (r.get('enabled')) {
+ this.enablePlugin(r.get('plugin'));
+ } else {
+ this.disablePlugin(r.get('plugin'));
+ }
+ },
+
+ onFindMorePlugins: function() {
+ window.open('http://dev.deluge-torrent.org/wiki/Plugins');
+ },
+
+ onGotPlugins: function() {
+ this.setInfo();
+ this.updatePluginsGrid();
+ },
+
+ onGotPluginInfo: function(info) {
+ var values = {
+ author: info['Author'],
+ version: info['Version'],
+ email: info['Author-email'],
+ homepage: info['Home-page'],
+ details: info['Description'],
+ };
+ this.setInfo(values);
+ delete info;
+ },
+
+ onInstallPluginWindow: function() {
+ if (!this.installWindow) {
+ this.installWindow = new Deluge.preferences.InstallPluginWindow();
+ this.installWindow.on('pluginadded', this.onPluginInstall, this);
+ }
+ this.installWindow.show();
+ },
+
+ onPluginEnabled: function(pluginName) {
+ var index = this.list.getStore().find('plugin', pluginName);
+ if (index == -1) return;
+ var plugin = this.list.getStore().getAt(index);
+ plugin.set('enabled', true);
+ plugin.commit();
+ },
+
+ onPluginDisabled: function(pluginName) {
+ var index = this.list.getStore().find('plugin', pluginName);
+ if (index == -1) return;
+ var plugin = this.list.getStore().getAt(index);
+ plugin.set('enabled', false);
+ plugin.commit();
+ },
+
+ onPluginInstall: function() {
+ this.updatePlugins();
+ },
+
+ onPluginSelect: function(dv, selections) {
+ if (selections.length == 0) return;
+ var r = dv.getRecords(selections)[0];
+ deluge.client.web.get_plugin_info(r.get('plugin'), {
+ success: this.onGotPluginInfo,
+ scope: this,
+ });
+ },
+
+ onPreferencesShow: function() {
+ this.updatePlugins();
+ },
+
+ onPluginInfoRender: function(ct, position) {
+ this.setInfo();
+ },
+});
+/**
+ * Deluge.preferences.PreferencesWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+PreferencesRecord = Ext.data.Record.create([{ name: 'name', type: 'string' }]);
+
+/**
+ * @class Deluge.preferences.PreferencesWindow
+ * @extends Ext.Window
+ */
+Deluge.preferences.PreferencesWindow = Ext.extend(Ext.Window, {
+ /**
+ * @property {String} currentPage The currently selected page.
+ */
+ currentPage: null,
+
+ title: _('Preferences'),
+ layout: 'border',
+ width: 485,
+ height: 500,
+ border: false,
+ constrainHeader: true,
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-preferences',
+ plain: true,
+ resizable: false,
+
+ pages: {},
+
+ initComponent: function() {
+ Deluge.preferences.PreferencesWindow.superclass.initComponent.call(
+ this
+ );
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.Store(),
+ columns: [
+ {
+ id: 'name',
+ renderer: fplain,
+ dataIndex: 'name',
+ },
+ ],
+ singleSelect: true,
+ listeners: {
+ selectionchange: {
+ fn: this.onPageSelect,
+ scope: this,
+ },
+ },
+ hideHeaders: true,
+ autoExpandColumn: 'name',
+ deferredRender: false,
+ autoScroll: true,
+ collapsible: true,
+ });
+ this.add({
+ region: 'west',
+ items: [this.list],
+ width: 120,
+ margins: '0 5 0 0',
+ cmargins: '0 5 0 0',
+ });
+
+ this.configPanel = this.add({
+ type: 'container',
+ autoDestroy: false,
+ region: 'center',
+ layout: 'card',
+ layoutConfig: {
+ deferredRender: true,
+ },
+ autoScroll: true,
+ width: 300,
+ });
+
+ this.addButton(_('Close'), this.onClose, this);
+ this.addButton(_('Apply'), this.onApply, this);
+ this.addButton(_('OK'), this.onOk, this);
+
+ this.optionsManager = new Deluge.OptionsManager();
+ this.on('afterrender', this.onAfterRender, this);
+ this.on('show', this.onShow, this);
+
+ this.initPages();
+ },
+
+ initPages: function() {
+ deluge.preferences = this;
+ this.addPage(new Deluge.preferences.Downloads());
+ this.addPage(new Deluge.preferences.Network());
+ this.addPage(new Deluge.preferences.Encryption());
+ this.addPage(new Deluge.preferences.Bandwidth());
+ this.addPage(new Deluge.preferences.Interface());
+ this.addPage(new Deluge.preferences.Other());
+ this.addPage(new Deluge.preferences.Daemon());
+ this.addPage(new Deluge.preferences.Queue());
+ this.addPage(new Deluge.preferences.Proxy());
+ this.addPage(new Deluge.preferences.Cache());
+ this.addPage(new Deluge.preferences.Plugins());
+ },
+
+ onApply: function(e) {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ // Workaround for only displaying single listen port but still pass array to core.
+ if ('listen_ports' in changed) {
+ changed.listen_ports = [
+ changed.listen_ports,
+ changed.listen_ports,
+ ];
+ }
+ deluge.client.core.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+ }
+
+ for (var page in this.pages) {
+ if (this.pages[page].onApply) this.pages[page].onApply();
+ }
+ },
+
+ /**
+ * Return the options manager for the preferences window.
+ * @returns {Deluge.OptionsManager} the options manager
+ */
+ getOptionsManager: function() {
+ return this.optionsManager;
+ },
+
+ /**
+ * Adds a page to the preferences window.
+ * @param {Mixed} page
+ */
+ addPage: function(page) {
+ var store = this.list.getStore();
+ var name = page.title;
+ store.add([new PreferencesRecord({ name: name })]);
+ page['bodyStyle'] = 'padding: 5px';
+ page.preferences = this;
+ this.pages[name] = this.configPanel.add(page);
+ this.pages[name].index = -1;
+ return this.pages[name];
+ },
+
+ /**
+ * Removes a preferences page from the window.
+ * @param {mixed} name
+ */
+ removePage: function(page) {
+ var name = page.title;
+ var store = this.list.getStore();
+ store.removeAt(store.find('name', name));
+ this.configPanel.remove(page);
+ delete this.pages[page.title];
+ },
+
+ /**
+ * Select which preferences page is displayed.
+ * @param {String} page The page name to change to
+ */
+ selectPage: function(page) {
+ if (this.pages[page].index < 0) {
+ this.pages[page].index = this.configPanel.items.indexOf(
+ this.pages[page]
+ );
+ }
+ this.list.select(this.pages[page].index);
+ },
+
+ // private
+ doSelectPage: function(page) {
+ if (this.pages[page].index < 0) {
+ this.pages[page].index = this.configPanel.items.indexOf(
+ this.pages[page]
+ );
+ }
+ this.configPanel.getLayout().setActiveItem(this.pages[page].index);
+ this.currentPage = page;
+ },
+
+ // private
+ onGotConfig: function(config) {
+ this.getOptionsManager().set(config);
+ },
+
+ // private
+ onPageSelect: function(list, selections) {
+ var r = list.getRecord(selections[0]);
+ this.doSelectPage(r.get('name'));
+ },
+
+ // private
+ onSetConfig: function() {
+ this.getOptionsManager().commit();
+ },
+
+ // private
+ onAfterRender: function() {
+ if (!this.list.getSelectionCount()) {
+ this.list.select(0);
+ }
+ this.configPanel.getLayout().setActiveItem(0);
+ },
+
+ // private
+ onShow: function() {
+ if (!deluge.client.core) return;
+ deluge.client.core.get_config({
+ success: this.onGotConfig,
+ scope: this,
+ });
+ },
+
+ // private
+ onClose: function() {
+ this.hide();
+ },
+
+ // private
+ onOk: function() {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ deluge.client.core.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+ }
+
+ for (var page in this.pages) {
+ if (this.pages[page].onOk) this.pages[page].onOk();
+ }
+
+ this.hide();
+ },
+});
+/**
+ * Deluge.preferences.ProxyField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.ProxyField
+ * @extends Ext.form.FieldSet
+ */
+Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
+ border: false,
+ autoHeight: true,
+ labelWidth: 70,
+
+ initComponent: function() {
+ Deluge.preferences.ProxyField.superclass.initComponent.call(this);
+ this.proxyType = this.add({
+ xtype: 'combo',
+ fieldLabel: _('Type:'),
+ labelSeparator: '',
+ name: 'proxytype',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('None')],
+ [1, _('Socks4')],
+ [2, _('Socks5')],
+ [3, _('Socks5 Auth')],
+ [4, _('HTTP')],
+ [5, _('HTTP Auth')],
+ [6, _('I2P')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ });
+ this.proxyType.on('change', this.onFieldChange, this);
+ this.proxyType.on('select', this.onTypeSelect, this);
+
+ this.hostname = this.add({
+ xtype: 'textfield',
+ name: 'hostname',
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ width: 220,
+ });
+ this.hostname.on('change', this.onFieldChange, this);
+
+ this.port = this.add({
+ xtype: 'spinnerfield',
+ name: 'port',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ width: 80,
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ });
+ this.port.on('change', this.onFieldChange, this);
+
+ this.username = this.add({
+ xtype: 'textfield',
+ name: 'username',
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ width: 220,
+ });
+ this.username.on('change', this.onFieldChange, this);
+
+ this.password = this.add({
+ xtype: 'textfield',
+ name: 'password',
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ inputType: 'password',
+ width: 220,
+ });
+ this.password.on('change', this.onFieldChange, this);
+
+ this.proxy_host_resolve = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_host_resolve',
+ fieldLabel: '',
+ boxLabel: _('Proxy Hostnames'),
+ width: 220,
+ });
+ this.proxy_host_resolve.on('change', this.onFieldChange, this);
+
+ this.proxy_peer_conn = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_peer_conn',
+ fieldLabel: '',
+ boxLabel: _('Proxy Peers'),
+ width: 220,
+ });
+ this.proxy_peer_conn.on('change', this.onFieldChange, this);
+
+ this.proxy_tracker_conn = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_tracker_conn',
+ fieldLabel: '',
+ boxLabel: _('Proxy Trackers'),
+ width: 220,
+ });
+ this.proxy_tracker_conn.on('change', this.onFieldChange, this);
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Force Proxy'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ style: 'padding-left: 0px; margin-top: 10px',
+ });
+
+ this.force_proxy = fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 20,
+ name: 'force_proxy',
+ boxLabel: _('Force Use of Proxy'),
+ });
+ this.force_proxy.on('change', this.onFieldChange, this);
+
+ this.anonymous_mode = fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 20,
+ name: 'anonymous_mode',
+ boxLabel: _('Hide Client Identity'),
+ });
+ this.anonymous_mode.on('change', this.onFieldChange, this);
+
+ this.setting = false;
+ },
+
+ getName: function() {
+ return this.initialConfig.name;
+ },
+
+ getValue: function() {
+ return {
+ type: this.proxyType.getValue(),
+ hostname: this.hostname.getValue(),
+ port: Number(this.port.getValue()),
+ username: this.username.getValue(),
+ password: this.password.getValue(),
+ proxy_hostnames: this.proxy_host_resolve.getValue(),
+ proxy_peer_connections: this.proxy_peer_conn.getValue(),
+ proxy_tracker_connections: this.proxy_tracker_conn.getValue(),
+ force_proxy: this.force_proxy.getValue(),
+ anonymous_mode: this.anonymous_mode.getValue(),
+ };
+ },
+
+ // Set the values of the proxies
+ setValue: function(value) {
+ this.setting = true;
+ this.proxyType.setValue(value['type']);
+ var index = this.proxyType.getStore().find('id', value['type']);
+ var record = this.proxyType.getStore().getAt(index);
+
+ this.hostname.setValue(value['hostname']);
+ this.port.setValue(value['port']);
+ this.username.setValue(value['username']);
+ this.password.setValue(value['password']);
+ this.proxy_host_resolve.setValue(value['proxy_hostnames']);
+ this.proxy_peer_conn.setValue(value['proxy_peer_connections']);
+ this.proxy_tracker_conn.setValue(value['proxy_tracker_connections']);
+ this.force_proxy.setValue(value['force_proxy']);
+ this.anonymous_mode.setValue(value['anonymous_mode']);
+
+ this.onTypeSelect(this.type, record, index);
+ this.setting = false;
+ },
+
+ onFieldChange: function(field, newValue, oldValue) {
+ if (this.setting) return;
+ var newValues = this.getValue();
+ var oldValues = Ext.apply({}, newValues);
+ oldValues[field.getName()] = oldValue;
+
+ this.fireEvent('change', this, newValues, oldValues);
+ },
+
+ onTypeSelect: function(combo, record, index) {
+ var typeId = record.get('id');
+ if (typeId > 0) {
+ this.hostname.show();
+ this.port.show();
+ this.proxy_peer_conn.show();
+ this.proxy_tracker_conn.show();
+ if (typeId > 1 && typeId < 6) {
+ this.proxy_host_resolve.show();
+ } else {
+ this.proxy_host_resolve.hide();
+ }
+ } else {
+ this.hostname.hide();
+ this.port.hide();
+ this.proxy_host_resolve.hide();
+ this.proxy_peer_conn.hide();
+ this.proxy_tracker_conn.hide();
+ }
+
+ if (typeId == 3 || typeId == 5) {
+ this.username.show();
+ this.password.show();
+ } else {
+ this.username.hide();
+ this.password.hide();
+ }
+ },
+});
+/**
+ * Deluge.preferences.ProxyPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Proxy
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Proxy'),
+ header: false,
+ layout: 'form',
+ autoScroll: true,
+ },
+ config
+ );
+ Deluge.preferences.Proxy.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Proxy.superclass.initComponent.call(this);
+ this.proxy = this.add(
+ new Deluge.preferences.ProxyField({
+ title: _('Proxy'),
+ name: 'proxy',
+ })
+ );
+ this.proxy.on('change', this.onProxyChange, this);
+ deluge.preferences.getOptionsManager().bind('proxy', this.proxy);
+ },
+
+ getValue: function() {
+ return {
+ proxy: this.proxy.getValue(),
+ };
+ },
+
+ setValue: function(value) {
+ for (var proxy in value) {
+ this[proxy].setValue(value[proxy]);
+ }
+ },
+
+ onProxyChange: function(field, newValue, oldValue) {
+ var newValues = this.getValue();
+ var oldValues = Ext.apply({}, newValues);
+ oldValues[field.getName()] = oldValue;
+
+ this.fireEvent('change', this, newValues, oldValues);
+ },
+});
+/**
+ * Deluge.preferences.QueuePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Queue
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Queue = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Queue'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Queue.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('New Torrents'),
+ style: 'padding-top: 5px; margin-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'queue_new_to_top',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Queue to top'),
+ name: 'queue_new_to_top',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Active Torrents'),
+ autoHeight: true,
+ labelWidth: 150,
+ defaultType: 'spinnerfield',
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ });
+ om.bind(
+ 'max_active_limit',
+ fieldset.add({
+ fieldLabel: _('Total:'),
+ labelSeparator: '',
+ name: 'max_active_limit',
+ value: 8,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'max_active_downloading',
+ fieldset.add({
+ fieldLabel: _('Downloading:'),
+ labelSeparator: '',
+ name: 'max_active_downloading',
+ value: 3,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'max_active_seeding',
+ fieldset.add({
+ fieldLabel: _('Seeding:'),
+ labelSeparator: '',
+ name: 'max_active_seeding',
+ value: 5,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'dont_count_slow_torrents',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'dont_count_slow_torrents',
+ height: 22,
+ hideLabel: true,
+ boxLabel: _('Ignore slow torrents'),
+ })
+ );
+ om.bind(
+ 'auto_manage_prefer_seeds',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'auto_manage_prefer_seeds',
+ hideLabel: true,
+ boxLabel: _('Prefer seeding torrents'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Seeding Rotation'),
+ autoHeight: true,
+ labelWidth: 150,
+ defaultType: 'spinnerfield',
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ });
+ om.bind(
+ 'share_ratio_limit',
+ fieldset.add({
+ fieldLabel: _('Share Ratio:'),
+ labelSeparator: '',
+ name: 'share_ratio_limit',
+ value: 8,
+ width: 80,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ })
+ );
+ om.bind(
+ 'seed_time_ratio_limit',
+ fieldset.add({
+ fieldLabel: _('Time Ratio:'),
+ labelSeparator: '',
+ name: 'seed_time_ratio_limit',
+ value: 3,
+ width: 80,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ })
+ );
+ om.bind(
+ 'seed_time_limit',
+ fieldset.add({
+ fieldLabel: _('Time (m):'),
+ labelSeparator: '',
+ name: 'seed_time_limit',
+ value: 5,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ autoHeight: true,
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ title: _('Share Ratio Reached'),
+
+ layout: 'table',
+ layoutConfig: { columns: 2 },
+ labelWidth: 0,
+ defaultType: 'checkbox',
+
+ defaults: {
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+ this.stopAtRatio = fieldset.add({
+ name: 'stop_seed_at_ratio',
+ boxLabel: _('Share Ratio:'),
+ });
+ this.stopAtRatio.on('check', this.onStopRatioCheck, this);
+ om.bind('stop_seed_at_ratio', this.stopAtRatio);
+
+ this.stopRatio = fieldset.add({
+ xtype: 'spinnerfield',
+ name: 'stop_seed_ratio',
+ ctCls: 'x-deluge-indent-checkbox',
+ disabled: true,
+ value: '2.0',
+ width: 60,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ });
+ om.bind('stop_seed_ratio', this.stopRatio);
+
+ this.removeAtRatio = fieldset.add({
+ xtype: 'radiogroup',
+ columns: 1,
+ colspan: 2,
+ disabled: true,
+ style: 'margin-left: 10px',
+ items: [
+ {
+ boxLabel: _('Pause torrent'),
+ name: 'at_ratio',
+ inputValue: false,
+ checked: true,
+ },
+ {
+ boxLabel: _('Remove torrent'),
+ name: 'at_ratio',
+ inputValue: true,
+ },
+ ],
+ });
+ om.bind('remove_seed_at_ratio', this.removeAtRatio);
+ },
+
+ onStopRatioCheck: function(e, checked) {
+ this.stopRatio.setDisabled(!checked);
+ this.removeAtRatio.setDisabled(!checked);
+ },
+});
+/**
+ * Deluge.StatusbarMenu.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * Menu that handles setting the statusbar limits correctly.
+ * @class Deluge.StatusbarMenu
+ * @extends Ext.menu.Menu
+ */
+Deluge.StatusbarMenu = Ext.extend(Ext.menu.Menu, {
+ initComponent: function() {
+ Deluge.StatusbarMenu.superclass.initComponent.call(this);
+ this.otherWin = new Deluge.OtherLimitWindow(
+ this.initialConfig.otherWin || {}
+ );
+
+ this.items.each(function(item) {
+ if (item.getXType() != 'menucheckitem') return;
+ if (item.value == 'other') {
+ item.on('click', this.onOtherClicked, this);
+ } else {
+ item.on('checkchange', this.onLimitChanged, this);
+ }
+ }, this);
+ },
+
+ setValue: function(value) {
+ var beenSet = false;
+ // set the new value
+ this.value = value = value == 0 ? -1 : value;
+
+ var other = null;
+ // uncheck all items
+ this.items.each(function(item) {
+ if (item.setChecked) {
+ item.suspendEvents();
+ if (item.value == value) {
+ item.setChecked(true);
+ beenSet = true;
+ } else {
+ item.setChecked(false);
+ }
+ item.resumeEvents();
+ }
+
+ if (item.value == 'other') other = item;
+ });
+
+ if (beenSet) return;
+
+ other.suspendEvents();
+ other.setChecked(true);
+ other.resumeEvents();
+ },
+
+ onLimitChanged: function(item, checked) {
+ if (!checked || item.value == 'other') return; // We do not care about unchecked or other.
+ var config = {};
+ config[item.group] = item.value;
+ deluge.client.core.set_config(config, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ },
+
+ onOtherClicked: function(item, e) {
+ this.otherWin.group = item.group;
+ this.otherWin.setValue(this.value);
+ this.otherWin.show();
+ },
+});
+/**
+ * Deluge.OptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge');
+
+/**
+ * @class Deluge.OptionsManager
+ * @extends Ext.util.Observable
+ * A class that can be used to manage options throughout the ui.
+ * @constructor
+ * Creates a new OptionsManager
+ * @param {Object} config Configuration options
+ */
+Deluge.OptionsManager = Ext.extend(Ext.util.Observable, {
+ constructor: function(config) {
+ config = config || {};
+ this.binds = {};
+ this.changed = {};
+ this.options = (config && config['options']) || {};
+ this.focused = null;
+
+ this.addEvents({
+ /**
+ * @event add
+ * Fires when an option is added
+ */
+ add: true,
+
+ /**
+ * @event changed
+ * Fires when an option is changed
+ * @param {String} option The changed option
+ * @param {Mixed} value The options new value
+ * @param {Mixed} oldValue The options old value
+ */
+ changed: true,
+
+ /**
+ * @event reset
+ * Fires when the options are reset
+ */
+ reset: true,
+ });
+ this.on('changed', this.onChange, this);
+
+ Deluge.OptionsManager.superclass.constructor.call(this);
+ },
+
+ /**
+ * Add a set of default options and values to the options manager
+ * @param {Object} options The default options.
+ */
+ addOptions: function(options) {
+ this.options = Ext.applyIf(this.options, options);
+ },
+
+ /**
+ * Binds a form field to the specified option.
+ * @param {String} option
+ * @param {Ext.form.Field} field
+ */
+ bind: function(option, field) {
+ this.binds[option] = this.binds[option] || [];
+ this.binds[option].push(field);
+ field._doption = option;
+
+ field.on('focus', this.onFieldFocus, this);
+ field.on('blur', this.onFieldBlur, this);
+ field.on('change', this.onFieldChange, this);
+ field.on('check', this.onFieldChange, this);
+ field.on('spin', this.onFieldChange, this);
+ return field;
+ },
+
+ /**
+ * Changes all the changed values to be the default values
+ */
+ commit: function() {
+ this.options = Ext.apply(this.options, this.changed);
+ this.reset();
+ },
+
+ /**
+ * Converts the value so it matches the originals type
+ * @param {Mixed} oldValue The original value
+ * @param {Mixed} value The new value to convert
+ */
+ convertValueType: function(oldValue, value) {
+ if (Ext.type(oldValue) != Ext.type(value)) {
+ switch (Ext.type(oldValue)) {
+ case 'string':
+ value = String(value);
+ break;
+ case 'number':
+ value = Number(value);
+ break;
+ case 'boolean':
+ if (Ext.type(value) == 'string') {
+ value = value.toLowerCase();
+ value =
+ value == 'true' || value == '1' || value == 'on'
+ ? true
+ : false;
+ } else {
+ value = Boolean(value);
+ }
+ break;
+ }
+ }
+ return value;
+ },
+
+ /**
+ * Get the value for an option or options.
+ * @param {String} [option] A single option or an array of options to return.
+ * @returns {Object} the options value.
+ */
+ get: function() {
+ if (arguments.length == 1) {
+ var option = arguments[0];
+ return this.isDirty(option)
+ ? this.changed[option]
+ : this.options[option];
+ } else {
+ var options = {};
+ Ext.each(
+ arguments,
+ function(option) {
+ if (!this.has(option)) return;
+ options[option] = this.isDirty(option)
+ ? this.changed[option]
+ : this.options[option];
+ },
+ this
+ );
+ return options;
+ }
+ },
+
+ /**
+ * Get the default value for an option or options.
+ * @param {String|Array} [option] A single option or an array of options to return.
+ * @returns {Object} the value of the option
+ */
+ getDefault: function(option) {
+ return this.options[option];
+ },
+
+ /**
+ * Returns the dirty (changed) values.
+ * @returns {Object} the changed options
+ */
+ getDirty: function() {
+ return this.changed;
+ },
+
+ /**
+ * @param {String} [option] The option to check
+ * @returns {Boolean} true if the option has been changed from the default.
+ */
+ isDirty: function(option) {
+ return !Ext.isEmpty(this.changed[option]);
+ },
+
+ /**
+ * Check to see if an option exists in the options manager
+ * @param {String} option
+ * @returns {Boolean} true if the option exists, else false.
+ */
+ has: function(option) {
+ return this.options[option];
+ },
+
+ /**
+ * Reset the options back to the default values.
+ */
+ reset: function() {
+ this.changed = {};
+ },
+
+ /**
+ * Sets the value of specified option(s) for the passed in id.
+ * @param {String} option
+ * @param {Object} value The value for the option
+ */
+ set: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (typeof option == 'object') {
+ var options = option;
+ this.options = Ext.apply(this.options, options);
+ for (var option in options) {
+ this.onChange(option, options[option]);
+ }
+ } else {
+ this.options[option] = value;
+ this.onChange(option, value);
+ }
+ },
+
+ /**
+ * Update the value for the specified option and id.
+ * @param {String/Object} option or options to update
+ * @param {Object} [value];
+ */
+ update: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.update(key, option[key]);
+ }
+ } else {
+ var defaultValue = this.getDefault(option);
+ value = this.convertValueType(defaultValue, value);
+
+ var oldValue = this.get(option);
+ if (oldValue == value) return;
+
+ if (defaultValue == value) {
+ if (this.isDirty(option)) delete this.changed[option];
+ this.fireEvent('changed', option, value, oldValue);
+ return;
+ }
+
+ this.changed[option] = value;
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ },
+
+ /**
+ * Lets the option manager know when a field is blurred so if a value
+ * so value changing operations can continue on that field.
+ */
+ onFieldBlur: function(field, event) {
+ if (this.focused == field) {
+ this.focused = null;
+ }
+ },
+
+ /**
+ * Stops a form fields value from being blocked by the change functions
+ * @param {Ext.form.Field} field
+ * @private
+ */
+ onFieldChange: function(field, event) {
+ if (field.field) field = field.field; // fix for spinners
+ this.update(field._doption, field.getValue());
+ },
+
+ /**
+ * Lets the option manager know when a field is focused so if a value changing
+ * operation is performed it will not change the value of the field.
+ */
+ onFieldFocus: function(field, event) {
+ this.focused = field;
+ },
+
+ onChange: function(option, newValue, oldValue) {
+ // If we don't have a bind there's nothing to do.
+ if (Ext.isEmpty(this.binds[option])) return;
+ Ext.each(
+ this.binds[option],
+ function(bind) {
+ // The field is currently focused so we do not want to change it.
+ if (bind == this.focused) return;
+ // Set the form field to the new value.
+ bind.setValue(newValue);
+ },
+ this
+ );
+ },
+});
+/**
+ * Deluge.AboutWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.about');
+
+/**
+ * @class Deluge.about.AboutWindow
+ * @extends Ext.Window
+ */
+Deluge.about.AboutWindow = Ext.extend(Ext.Window, {
+ id: 'AboutWindow',
+ title: _('About Deluge'),
+ height: 330,
+ width: 270,
+ iconCls: 'x-deluge-main-panel',
+ resizable: false,
+ plain: true,
+ layout: {
+ type: 'vbox',
+ align: 'center',
+ },
+ buttonAlign: 'center',
+
+ initComponent: function() {
+ Deluge.about.AboutWindow.superclass.initComponent.call(this);
+ this.addEvents({
+ build_ready: true,
+ });
+
+ var self = this;
+ var libtorrent = function() {
+ deluge.client.core.get_libtorrent_version({
+ success: function(lt_version) {
+ comment += '<br/>' + _('libtorrent:') + ' ' + lt_version;
+ Ext.getCmp('about_comment').setText(comment, false);
+ self.fireEvent('build_ready');
+ },
+ });
+ };
+
+ var client_version = deluge.version;
+
+ var comment =
+ _(
+ 'A peer-to-peer file sharing program\nutilizing the BitTorrent protocol.'
+ ).replace('\n', '<br/>') +
+ '<br/><br/>' +
+ _('Client:') +
+ ' ' +
+ client_version +
+ '<br/>';
+ deluge.client.web.connected({
+ success: function(connected) {
+ if (connected) {
+ deluge.client.daemon.get_version({
+ success: function(server_version) {
+ comment +=
+ _('Server:') + ' ' + server_version + '<br/>';
+ libtorrent();
+ },
+ });
+ } else {
+ this.fireEvent('build_ready');
+ }
+ },
+ failure: function() {
+ this.fireEvent('build_ready');
+ },
+ scope: this,
+ });
+
+ this.add([
+ {
+ xtype: 'box',
+ style: 'padding-top: 5px',
+ height: 80,
+ width: 240,
+ cls: 'x-deluge-logo',
+ hideLabel: true,
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 10px; font-weight: bold; font-size: 16px;',
+ text: _('Deluge') + ' ' + client_version,
+ },
+ {
+ xtype: 'label',
+ id: 'about_comment',
+ style: 'padding-top: 10px; text-align:center; font-size: 12px;',
+ html: comment,
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 10px; font-size: 10px;',
+ text: _('Copyright 2007-2018 Deluge Team'),
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 5px; font-size: 12px;',
+ html:
+ '<a href="https://deluge-torrent.org" target="_blank">deluge-torrent.org</a>',
+ },
+ ]);
+ this.addButton(_('Close'), this.onCloseClick, this);
+ },
+
+ show: function() {
+ this.on('build_ready', function() {
+ Deluge.about.AboutWindow.superclass.show.call(this);
+ });
+ },
+
+ onCloseClick: function() {
+ this.close();
+ },
+});
+
+Ext.namespace('Deluge');
+
+Deluge.About = function() {
+ new Deluge.about.AboutWindow().show();
+};
+/**
+ * Deluge.AddConnectionWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.AddConnectionWindow
+ * @extends Ext.Window
+ */
+Deluge.AddConnectionWindow = Ext.extend(Ext.Window, {
+ title: _('Add Connection'),
+ iconCls: 'x-deluge-add-window-icon',
+
+ layout: 'fit',
+ width: 300,
+ height: 195,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.AddConnectionWindow.superclass.initComponent.call(this);
+
+ this.addEvents('hostadded');
+
+ this.addButton(_('Close'), this.hide, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 60,
+ items: [
+ {
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ name: 'host',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ xtype: 'spinnerfield',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ name: 'port',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 65535,
+ },
+ value: '58846',
+ anchor: '40%',
+ },
+ {
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ name: 'username',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ anchor: '75%',
+ name: 'password',
+ inputType: 'password',
+ value: '',
+ },
+ ],
+ });
+ },
+
+ onAddClick: function() {
+ var values = this.form.getForm().getValues();
+ deluge.client.web.add_host(
+ values.host,
+ Number(values.port),
+ values.username,
+ values.password,
+ {
+ success: function(result) {
+ if (!result[0]) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: String.format(
+ _('Unable to add host: {0}'),
+ result[1]
+ ),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.fireEvent('hostadded');
+ }
+ this.hide();
+ },
+ scope: this,
+ }
+ );
+ },
+
+ onHide: function() {
+ this.form.getForm().reset();
+ },
+});
+/**
+ * Deluge.AddTrackerWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+// Custom VType validator for tracker urls
+var trackerUrlTest = /(((^https?)|(^udp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+Ext.apply(Ext.form.VTypes, {
+ trackerUrl: function(val, field) {
+ return trackerUrlTest.test(val);
+ },
+ trackerUrlText: 'Not a valid tracker url',
+});
+
+/**
+ * @class Deluge.AddTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.AddTrackerWindow = Ext.extend(Ext.Window, {
+ title: _('Add Tracker'),
+ layout: 'fit',
+ width: 375,
+ height: 150,
+ plain: true,
+ closable: true,
+ resizable: false,
+ constrainHeader: true,
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.AddTrackerWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+ this.addEvents('add');
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textarea',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ items: [
+ {
+ fieldLabel: _('Trackers:'),
+ labelSeparator: '',
+ name: 'trackers',
+ anchor: '100%',
+ },
+ ],
+ });
+ },
+
+ onAddClick: function() {
+ var trackers = this.form
+ .getForm()
+ .findField('trackers')
+ .getValue();
+ trackers = trackers.split('\n');
+
+ var cleaned = [];
+ Ext.each(
+ trackers,
+ function(tracker) {
+ if (Ext.form.VTypes.trackerUrl(tracker)) {
+ cleaned.push(tracker);
+ }
+ },
+ this
+ );
+ this.fireEvent('add', cleaned);
+ this.hide();
+ this.form
+ .getForm()
+ .findField('trackers')
+ .setValue('');
+ },
+
+ onCancelClick: function() {
+ this.form
+ .getForm()
+ .findField('trackers')
+ .setValue('');
+ this.hide();
+ },
+});
+/**
+ * Deluge.Client.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.ux.util');
+
+/**
+ * A class that connects to a json-rpc resource and adds the available
+ * methods as functions to the class instance.
+ * @class Ext.ux.util.RpcClient
+ * @namespace Ext.ux.util
+ */
+Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
+ _components: [],
+
+ _methods: [],
+
+ _requests: {},
+
+ _url: null,
+
+ _optionKeys: ['scope', 'success', 'failure'],
+
+ /**
+ * @event connected
+ * Fires when the client has retrieved the list of methods from the server.
+ * @param {Ext.ux.util.RpcClient} this
+ */
+ constructor: function(config) {
+ Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
+ this._url = config.url || null;
+ this._id = 0;
+
+ this.addEvents(
+ // raw events
+ 'connected',
+ 'error'
+ );
+ this.reloadMethods();
+ },
+
+ reloadMethods: function() {
+ this._execute('system.listMethods', {
+ success: this._setMethods,
+ scope: this,
+ });
+ },
+
+ _execute: function(method, options) {
+ options = options || {};
+ options.params = options.params || [];
+ options.id = this._id;
+
+ var request = Ext.encode({
+ method: method,
+ params: options.params,
+ id: options.id,
+ });
+ this._id++;
+
+ return Ext.Ajax.request({
+ url: this._url,
+ method: 'POST',
+ success: this._onSuccess,
+ failure: this._onFailure,
+ scope: this,
+ jsonData: request,
+ options: options,
+ });
+ },
+
+ _onFailure: function(response, requestOptions) {
+ var options = requestOptions.options;
+ errorObj = {
+ id: options.id,
+ result: null,
+ error: {
+ msg: 'HTTP: ' + response.status + ' ' + response.statusText,
+ code: 255,
+ },
+ };
+
+ this.fireEvent('error', errorObj, response, requestOptions);
+
+ if (Ext.type(options.failure) != 'function') return;
+ if (options.scope) {
+ options.failure.call(
+ options.scope,
+ errorObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.failure(errorObj, response, requestOptions);
+ }
+ },
+
+ _onSuccess: function(response, requestOptions) {
+ var responseObj = Ext.decode(response.responseText);
+ var options = requestOptions.options;
+ if (responseObj.error) {
+ this.fireEvent('error', responseObj, response, requestOptions);
+
+ if (Ext.type(options.failure) != 'function') return;
+ if (options.scope) {
+ options.failure.call(
+ options.scope,
+ responseObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.failure(responseObj, response, requestOptions);
+ }
+ } else {
+ if (Ext.type(options.success) != 'function') return;
+ if (options.scope) {
+ options.success.call(
+ options.scope,
+ responseObj.result,
+ responseObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.success(
+ responseObj.result,
+ responseObj,
+ response,
+ requestOptions
+ );
+ }
+ }
+ },
+
+ _parseArgs: function(args) {
+ var params = [];
+ Ext.each(args, function(arg) {
+ params.push(arg);
+ });
+
+ var options = params[params.length - 1];
+ if (Ext.type(options) == 'object') {
+ var keys = Ext.keys(options),
+ isOption = false;
+
+ Ext.each(this._optionKeys, function(key) {
+ if (keys.indexOf(key) > -1) isOption = true;
+ });
+
+ if (isOption) {
+ params.remove(options);
+ } else {
+ options = {};
+ }
+ } else {
+ options = {};
+ }
+ options.params = params;
+ return options;
+ },
+
+ _setMethods: function(methods) {
+ var components = {},
+ self = this;
+
+ Ext.each(methods, function(method) {
+ var parts = method.split('.');
+ var component = components[parts[0]] || {};
+
+ var fn = function() {
+ var options = self._parseArgs(arguments);
+ return self._execute(method, options);
+ };
+ component[parts[1]] = fn;
+ components[parts[0]] = component;
+ });
+
+ for (var name in components) {
+ self[name] = components[name];
+ }
+ Ext.each(
+ this._components,
+ function(component) {
+ if (!component in components) {
+ delete this[component];
+ }
+ },
+ this
+ );
+ this._components = Ext.keys(components);
+ this.fireEvent('connected', this);
+ },
+});
+/**
+ * Deluge.ConnectionManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.ConnectionManager = Ext.extend(Ext.Window, {
+ layout: 'fit',
+ width: 300,
+ height: 220,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ plain: true,
+ constrainHeader: true,
+ title: _('Connection Manager'),
+ iconCls: 'x-deluge-connect-window-icon',
+
+ initComponent: function() {
+ Deluge.ConnectionManager.superclass.initComponent.call(this);
+ this.on('hide', this.onHide, this);
+ this.on('show', this.onShow, this);
+
+ deluge.events.on('login', this.onLogin, this);
+ deluge.events.on('logout', this.onLogout, this);
+
+ this.addButton(_('Close'), this.onClose, this);
+ this.addButton(_('Connect'), this.onConnect, this);
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.ArrayStore({
+ fields: [
+ { name: 'status', mapping: 4 },
+ { name: 'host', mapping: 1 },
+ { name: 'port', mapping: 2 },
+ { name: 'user', mapping: 3 },
+ { name: 'version', mapping: 5 },
+ ],
+ id: 0,
+ }),
+ columns: [
+ {
+ header: _('Status'),
+ width: 0.24,
+ sortable: true,
+ tpl: new Ext.XTemplate(
+ '<tpl if="status == \'Online\'">',
+ _('Online'),
+ '</tpl>',
+ '<tpl if="status == \'Offline\'">',
+ _('Offline'),
+ '</tpl>',
+ '<tpl if="status == \'Connected\'">',
+ _('Connected'),
+ '</tpl>'
+ ),
+ dataIndex: 'status',
+ },
+ {
+ id: 'host',
+ header: _('Host'),
+ width: 0.51,
+ sortable: true,
+ tpl: '{user}@{host}:{port}',
+ dataIndex: 'host',
+ },
+ {
+ header: _('Version'),
+ width: 0.25,
+ sortable: true,
+ tpl: '<tpl if="version">{version}</tpl>',
+ dataIndex: 'version',
+ },
+ ],
+ singleSelect: true,
+ listeners: {
+ selectionchange: { fn: this.onSelectionChanged, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ autoScroll: true,
+ items: [this.list],
+ bbar: new Ext.Toolbar({
+ buttons: [
+ {
+ id: 'cm-add',
+ cls: 'x-btn-text-icon',
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onAddClick,
+ scope: this,
+ },
+ {
+ id: 'cm-edit',
+ cls: 'x-btn-text-icon',
+ text: _('Edit'),
+ iconCls: 'icon-edit',
+ handler: this.onEditClick,
+ scope: this,
+ },
+ {
+ id: 'cm-remove',
+ cls: 'x-btn-text-icon',
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemoveClick,
+ disabled: true,
+ scope: this,
+ },
+ '->',
+ {
+ id: 'cm-stop',
+ cls: 'x-btn-text-icon',
+ text: _('Stop Daemon'),
+ iconCls: 'icon-error',
+ handler: this.onStopClick,
+ disabled: true,
+ scope: this,
+ },
+ ],
+ }),
+ });
+ this.update = this.update.createDelegate(this);
+ },
+
+ /**
+ * Check to see if the the web interface is currently connected
+ * to a Deluge Daemon and show the Connection Manager if not.
+ */
+ checkConnected: function() {
+ deluge.client.web.connected({
+ success: function(connected) {
+ if (connected) {
+ deluge.events.fire('connect');
+ } else {
+ this.show();
+ }
+ },
+ scope: this,
+ });
+ },
+
+ disconnect: function(show) {
+ deluge.events.fire('disconnect');
+ if (show) {
+ if (this.isVisible()) return;
+ this.show();
+ }
+ },
+
+ loadHosts: function() {
+ deluge.client.web.get_hosts({
+ success: this.onGetHosts,
+ scope: this,
+ });
+ },
+
+ update: function() {
+ this.list.getStore().each(function(r) {
+ deluge.client.web.get_host_status(r.id, {
+ success: this.onGetHostStatus,
+ scope: this,
+ });
+ }, this);
+ },
+
+ /**
+ * Updates the buttons in the Connection Manager UI according to the
+ * passed in records host state.
+ * @param {Ext.data.Record} record The hosts record to update the UI for
+ */
+ updateButtons: function(record) {
+ var button = this.buttons[1],
+ status = record.get('status');
+
+ // Update the Connect/Disconnect button
+ button.enable();
+ if (status.toLowerCase() == 'connected') {
+ button.setText(_('Disconnect'));
+ } else {
+ button.setText(_('Connect'));
+ if (status.toLowerCase() != 'online') button.disable();
+ }
+
+ // Update the Stop/Start Daemon button
+ if (
+ status.toLowerCase() == 'connected' ||
+ status.toLowerCase() == 'online'
+ ) {
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Stop Daemon'));
+ } else {
+ if (
+ record.get('host') == '127.0.0.1' ||
+ record.get('host') == 'localhost'
+ ) {
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Start Daemon'));
+ } else {
+ this.stopHostButton.disable();
+ }
+ }
+ },
+
+ // private
+ onAddClick: function(button, e) {
+ if (!this.addWindow) {
+ this.addWindow = new Deluge.AddConnectionWindow();
+ this.addWindow.on('hostadded', this.onHostChange, this);
+ }
+ this.addWindow.show();
+ },
+
+ // private
+ onEditClick: function(button, e) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ if (!this.editWindow) {
+ this.editWindow = new Deluge.EditConnectionWindow();
+ this.editWindow.on('hostedited', this.onHostChange, this);
+ }
+ this.editWindow.show(connection);
+ },
+
+ // private
+ onHostChange: function() {
+ this.loadHosts();
+ },
+
+ // private
+ onClose: function(e) {
+ this.hide();
+ },
+
+ // private
+ onConnect: function(e) {
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+
+ var me = this;
+ var disconnect = function() {
+ deluge.client.web.disconnect({
+ success: function(result) {
+ this.update(this);
+ deluge.events.fire('disconnect');
+ },
+ scope: me,
+ });
+ };
+
+ if (selected.get('status').toLowerCase() == 'connected') {
+ disconnect();
+ } else {
+ if (
+ this.list
+ .getStore()
+ .find('status', 'Connected', 0, false, false) > -1
+ ) {
+ disconnect();
+ }
+
+ var id = selected.id;
+ deluge.client.web.connect(id, {
+ success: function(methods) {
+ deluge.client.reloadMethods();
+ deluge.client.on(
+ 'connected',
+ function(e) {
+ deluge.events.fire('connect');
+ },
+ this,
+ { single: true }
+ );
+ },
+ });
+ this.hide();
+ }
+ },
+
+ // private
+ onGetHosts: function(hosts) {
+ this.list.getStore().loadData(hosts);
+ Ext.each(
+ hosts,
+ function(host) {
+ deluge.client.web.get_host_status(host[0], {
+ success: this.onGetHostStatus,
+ scope: this,
+ });
+ },
+ this
+ );
+ },
+
+ // private
+ onGetHostStatus: function(host) {
+ var record = this.list.getStore().getById(host[0]);
+ record.set('status', host[1]);
+ record.set('version', host[2]);
+ record.commit();
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ if (selected == record) this.updateButtons(record);
+ },
+
+ // private
+ onHide: function() {
+ if (this.running) window.clearInterval(this.running);
+ },
+
+ // private
+ onLogin: function() {
+ if (deluge.config.first_login) {
+ Ext.MessageBox.confirm(
+ _('Change Default Password'),
+ _(
+ 'We recommend changing the default password.<br><br>Would you like to change it now?'
+ ),
+ function(res) {
+ this.checkConnected();
+ if (res == 'yes') {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Interface');
+ }
+ deluge.client.web.set_config({ first_login: false });
+ },
+ this
+ );
+ } else {
+ this.checkConnected();
+ }
+ },
+
+ // private
+ onLogout: function() {
+ this.disconnect();
+ if (!this.hidden && this.rendered) {
+ this.hide();
+ }
+ },
+
+ // private
+ onRemoveClick: function(button) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ deluge.client.web.remove_host(connection.id, {
+ success: function(result) {
+ if (!result) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: result[1],
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.list.getStore().remove(connection);
+ }
+ },
+ scope: this,
+ });
+ },
+
+ // private
+ onSelectionChanged: function(list, selections) {
+ if (selections[0]) {
+ this.editHostButton.enable();
+ this.removeHostButton.enable();
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Stop Daemon'));
+ this.updateButtons(this.list.getRecord(selections[0]));
+ } else {
+ this.editHostButton.disable();
+ this.removeHostButton.disable();
+ this.stopHostButton.disable();
+ }
+ },
+
+ // FIXME: Find out why this is being fired twice
+ // private
+ onShow: function() {
+ if (!this.addHostButton) {
+ var bbar = this.panel.getBottomToolbar();
+ this.addHostButton = bbar.items.get('cm-add');
+ this.editHostButton = bbar.items.get('cm-edit');
+ this.removeHostButton = bbar.items.get('cm-remove');
+ this.stopHostButton = bbar.items.get('cm-stop');
+ }
+ this.loadHosts();
+ if (this.running) return;
+ this.running = window.setInterval(this.update, 2000, this);
+ },
+
+ // private
+ onStopClick: function(button, e) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ if (connection.get('status') == 'Offline') {
+ // This means we need to start the daemon
+ deluge.client.web.start_daemon(connection.get('port'));
+ } else {
+ // This means we need to stop the daemon
+ deluge.client.web.stop_daemon(connection.id, {
+ success: function(result) {
+ if (!result[0]) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: result[1],
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ }
+ },
+ });
+ }
+ },
+});
+/**
+ * Deluge.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Setup the state manager
+Ext.state.Manager.setProvider(
+ new Ext.state.CookieProvider({
+ /**
+ * By default, cookies will expire after 7 days. Provide
+ * an expiry date 10 years in the future to approximate
+ * a cookie that does not expire.
+ */
+ expires: new Date(
+ new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 10
+ ),
+ })
+);
+
+// Add some additional functions to ext and setup some of the
+// configurable parameters
+Ext.apply(Ext, {
+ escapeHTML: function(text) {
+ text = String(text)
+ .replace('<', '&lt;')
+ .replace('>', '&gt;');
+ return text.replace('&', '&amp;');
+ },
+
+ isObjectEmpty: function(obj) {
+ for (var i in obj) {
+ return false;
+ }
+ return true;
+ },
+
+ areObjectsEqual: function(obj1, obj2) {
+ var equal = true;
+ if (!obj1 || !obj2) return false;
+ for (var i in obj1) {
+ if (obj1[i] != obj2[i]) {
+ equal = false;
+ }
+ }
+ return equal;
+ },
+
+ keys: function(obj) {
+ var keys = [];
+ for (var i in obj)
+ if (obj.hasOwnProperty(i)) {
+ keys.push(i);
+ }
+ return keys;
+ },
+
+ values: function(obj) {
+ var values = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ values.push(obj[i]);
+ }
+ }
+ return values;
+ },
+
+ splat: function(obj) {
+ var type = Ext.type(obj);
+ return type ? (type != 'array' ? [obj] : obj) : [];
+ },
+});
+Ext.getKeys = Ext.keys;
+Ext.BLANK_IMAGE_URL = deluge.config.base + 'images/s.gif';
+Ext.USE_NATIVE_JSON = true;
+
+// Create the Deluge namespace
+Ext.apply(Deluge, {
+ // private
+ pluginStore: {},
+
+ // private
+ progressTpl:
+ '<div class="x-progress-wrap x-progress-renderered">' +
+ '<div class="x-progress-inner">' +
+ '<div style="width: {2}px" class="x-progress-bar">' +
+ '<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
+ '<div style="width: {1}px;">{0}</div>' +
+ '</div>' +
+ '</div>' +
+ '<div class="x-progress-text x-progress-text-back">' +
+ '<div style="width: {1}px;">{0}</div>' +
+ '</div>' +
+ '</div>' +
+ '</div>',
+
+ /**
+ * A method to create a progress bar that can be used by renderers
+ * to display a bar within a grid or tree.
+ * @param {Number} progress The bars progress
+ * @param {Number} width The width of the bar
+ * @param {String} text The text to display on the bar
+ * @param {Number} modified Amount to subtract from the width allowing for fixes
+ */
+ progressBar: function(progress, width, text, modifier) {
+ modifier = Ext.value(modifier, 10);
+ var progressWidth = ((width / 100.0) * progress).toFixed(0);
+ var barWidth = progressWidth - 1;
+ var textWidth =
+ progressWidth - modifier > 0 ? progressWidth - modifier : 0;
+ return String.format(
+ Deluge.progressTpl,
+ text,
+ width,
+ barWidth,
+ textWidth
+ );
+ },
+
+ /**
+ * Constructs a new instance of the specified plugin.
+ * @param {String} name The plugin name to create
+ */
+ createPlugin: function(name) {
+ return new Deluge.pluginStore[name]();
+ },
+
+ /**
+ * Check to see if a plugin has been registered.
+ * @param {String} name The plugin name to check
+ */
+ hasPlugin: function(name) {
+ return Deluge.pluginStore[name] ? true : false;
+ },
+
+ /**
+ * Register a plugin with the Deluge interface.
+ * @param {String} name The plugin name to register
+ * @param {Plugin} plugin The plugin to register
+ */
+ registerPlugin: function(name, plugin) {
+ Deluge.pluginStore[name] = plugin;
+ },
+});
+
+// Setup a space for plugins to insert themselves
+deluge.plugins = {};
+
+// Hinting for gettext_gen.py
+// _('Skip')
+// _('Low')
+// _('Normal')
+// _('High')
+// _('Mixed')
+FILE_PRIORITY = {
+ 0: 'Skip',
+ 1: 'Low',
+ 2: 'Low',
+ 3: 'Low',
+ 4: 'Normal',
+ 5: 'High',
+ 6: 'High',
+ 7: 'High',
+ 9: 'Mixed',
+ Skip: 0,
+ Low: 1,
+ Normal: 4,
+ High: 7,
+ Mixed: 9,
+};
+
+FILE_PRIORITY_CSS = {
+ 0: 'x-no-download',
+ 1: 'x-low-download',
+ 2: 'x-low-download',
+ 3: 'x-low-download',
+ 4: 'x-normal-download',
+ 5: 'x-high-download',
+ 6: 'x-high-download',
+ 7: 'x-high-download',
+ 9: 'x-mixed-download',
+};
+/**
+ * Deluge.EditConnectionWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditConnectionWindow
+ * @extends Ext.Window
+ */
+Deluge.EditConnectionWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Connection'),
+ iconCls: 'x-deluge-add-window-icon',
+
+ layout: 'fit',
+ width: 300,
+ height: 195,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.EditConnectionWindow.superclass.initComponent.call(this);
+
+ this.addEvents('hostedited');
+
+ this.addButton(_('Close'), this.hide, this);
+ this.addButton(_('Edit'), this.onEditClick, this);
+
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 60,
+ items: [
+ {
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ name: 'host',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ xtype: 'spinnerfield',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ name: 'port',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ anchor: '40%',
+ value: 58846,
+ },
+ {
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ name: 'username',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ anchor: '75%',
+ name: 'password',
+ inputType: 'password',
+ value: '',
+ },
+ ],
+ });
+ },
+
+ show: function(connection) {
+ Deluge.EditConnectionWindow.superclass.show.call(this);
+
+ this.form
+ .getForm()
+ .findField('host')
+ .setValue(connection.get('host'));
+ this.form
+ .getForm()
+ .findField('port')
+ .setValue(connection.get('port'));
+ this.form
+ .getForm()
+ .findField('username')
+ .setValue(connection.get('user'));
+ this.host_id = connection.id;
+ },
+
+ onEditClick: function() {
+ var values = this.form.getForm().getValues();
+ deluge.client.web.edit_host(
+ this.host_id,
+ values.host,
+ Number(values.port),
+ values.username,
+ values.password,
+ {
+ success: function(result) {
+ if (!result) {
+ console.log(result);
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: String.format(_('Unable to edit host')),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.fireEvent('hostedited');
+ }
+ this.hide();
+ },
+ scope: this,
+ }
+ );
+ },
+
+ onHide: function() {
+ this.form.getForm().reset();
+ },
+});
+/**
+ * Deluge.EditTrackerWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.EditTrackerWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Tracker'),
+ layout: 'fit',
+ width: 375,
+ height: 110,
+ plain: true,
+ closable: true,
+ resizable: false,
+ constrainHeader: true,
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.EditTrackerWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Save'), this.onSaveClick, this);
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ items: [
+ {
+ fieldLabel: _('Tracker:'),
+ labelSeparator: '',
+ name: 'tracker',
+ anchor: '100%',
+ },
+ ],
+ });
+ },
+
+ show: function(record) {
+ Deluge.EditTrackerWindow.superclass.show.call(this);
+
+ this.record = record;
+ this.form
+ .getForm()
+ .findField('tracker')
+ .setValue(record.data['url']);
+ },
+
+ onCancelClick: function() {
+ this.hide();
+ },
+
+ onHide: function() {
+ this.form
+ .getForm()
+ .findField('tracker')
+ .setValue('');
+ },
+
+ onSaveClick: function() {
+ var url = this.form
+ .getForm()
+ .findField('tracker')
+ .getValue();
+ this.record.set('url', url);
+ this.record.commit();
+ this.hide();
+ },
+});
+/**
+ * Deluge.EditTrackers.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.EditTrackersWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Trackers'),
+ layout: 'fit',
+ width: 350,
+ height: 220,
+ plain: true,
+ closable: true,
+ resizable: true,
+ constrainHeader: true,
+
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.EditTrackersWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('OK'), this.onOkClick, this);
+ this.addEvents('save');
+
+ this.on('show', this.onShow, this);
+ this.on('save', this.onSave, this);
+
+ this.addWindow = new Deluge.AddTrackerWindow();
+ this.addWindow.on('add', this.onAddTrackers, this);
+ this.editWindow = new Deluge.EditTrackerWindow();
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.JsonStore({
+ root: 'trackers',
+ fields: ['tier', 'url'],
+ }),
+ columns: [
+ {
+ header: _('Tier'),
+ width: 0.1,
+ dataIndex: 'tier',
+ },
+ {
+ header: _('Tracker'),
+ width: 0.9,
+ dataIndex: 'url',
+ },
+ ],
+ columnSort: {
+ sortClasses: ['', ''],
+ },
+ stripeRows: true,
+ singleSelect: true,
+ listeners: {
+ dblclick: { fn: this.onListNodeDblClicked, scope: this },
+ selectionchange: { fn: this.onSelect, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ items: [this.list],
+ autoScroll: true,
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: this.onUpClick,
+ scope: this,
+ },
+ {
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: this.onDownClick,
+ scope: this,
+ },
+ '->',
+ {
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onAddClick,
+ scope: this,
+ },
+ {
+ text: _('Edit'),
+ iconCls: 'icon-edit-trackers',
+ handler: this.onEditClick,
+ scope: this,
+ },
+ {
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemoveClick,
+ scope: this,
+ },
+ ],
+ }),
+ });
+ },
+
+ onAddClick: function() {
+ this.addWindow.show();
+ },
+
+ onAddTrackers: function(trackers) {
+ var store = this.list.getStore();
+ Ext.each(
+ trackers,
+ function(tracker) {
+ var duplicate = false,
+ heightestTier = -1;
+ store.each(function(record) {
+ if (record.get('tier') > heightestTier) {
+ heightestTier = record.get('tier');
+ }
+ if (tracker == record.get('tracker')) {
+ duplicate = true;
+ return false;
+ }
+ }, this);
+ if (duplicate) return;
+ store.add(
+ new store.recordType({
+ tier: heightestTier + 1,
+ url: tracker,
+ })
+ );
+ },
+ this
+ );
+ },
+
+ onCancelClick: function() {
+ this.hide();
+ },
+
+ onEditClick: function() {
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ this.editWindow.show(selected);
+ },
+
+ onHide: function() {
+ this.list.getStore().removeAll();
+ },
+
+ onListNodeDblClicked: function(list, index, node, e) {
+ this.editWindow.show(this.list.getRecord(node));
+ },
+
+ onOkClick: function() {
+ var trackers = [];
+ this.list.getStore().each(function(record) {
+ trackers.push({
+ tier: record.get('tier'),
+ url: record.get('url'),
+ });
+ }, this);
+
+ deluge.client.core.set_torrent_trackers(this.torrentId, trackers, {
+ failure: this.onSaveFail,
+ scope: this,
+ });
+
+ this.hide();
+ },
+
+ onRemoveClick: function() {
+ // Remove from the grid
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ this.list.getStore().remove(selected);
+ },
+
+ onRequestComplete: function(status) {
+ this.list.getStore().loadData(status);
+ this.list.getStore().sort('tier', 'ASC');
+ },
+
+ onSaveFail: function() {},
+
+ onSelect: function(list) {
+ if (list.getSelectionCount()) {
+ this.panel
+ .getBottomToolbar()
+ .items.get(4)
+ .enable();
+ }
+ },
+
+ onShow: function() {
+ this.panel
+ .getBottomToolbar()
+ .items.get(4)
+ .disable();
+ var r = deluge.torrents.getSelected();
+ this.torrentId = r.id;
+ deluge.client.core.get_torrent_status(r.id, ['trackers'], {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onDownClick: function() {
+ var r = this.list.getSelectedRecords()[0];
+ if (!r) return;
+
+ r.set('tier', r.get('tier') + 1);
+ r.store.sort('tier', 'ASC');
+ r.store.commitChanges();
+
+ this.list.select(r.store.indexOf(r));
+ },
+
+ onUpClick: function() {
+ var r = this.list.getSelectedRecords()[0];
+ if (!r) return;
+
+ if (r.get('tier') == 0) return;
+ r.set('tier', r.get('tier') - 1);
+ r.store.sort('tier', 'ASC');
+ r.store.commitChanges();
+
+ this.list.select(r.store.indexOf(r));
+ },
+});
+/**
+ * Deluge.EventsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @class Deluge.EventsManager
+ * @extends Ext.util.Observable
+ * <p>Deluge.EventsManager is instantated as <tt>deluge.events</tt> and can be used by components of the UI to fire global events</p>
+ * Class for holding global events that occur within the UI.
+ */
+Deluge.EventsManager = Ext.extend(Ext.util.Observable, {
+ constructor: function() {
+ this.toRegister = [];
+ this.on('login', this.onLogin, this);
+ Deluge.EventsManager.superclass.constructor.call(this);
+ },
+
+ /**
+ * Append an event handler to this object.
+ */
+ addListener: function(eventName, fn, scope, o) {
+ this.addEvents(eventName);
+ if (/[A-Z]/.test(eventName.substring(0, 1))) {
+ if (!deluge.client) {
+ this.toRegister.push(eventName);
+ } else {
+ deluge.client.web.register_event_listener(eventName);
+ }
+ }
+ Deluge.EventsManager.superclass.addListener.call(
+ this,
+ eventName,
+ fn,
+ scope,
+ o
+ );
+ },
+
+ getEvents: function() {
+ deluge.client.web.get_events({
+ success: this.onGetEventsSuccess,
+ failure: this.onGetEventsFailure,
+ scope: this,
+ });
+ },
+
+ /**
+ * Starts the EventsManagerManager checking for events.
+ */
+ start: function() {
+ Ext.each(this.toRegister, function(eventName) {
+ deluge.client.web.register_event_listener(eventName);
+ });
+ this.running = true;
+ this.errorCount = 0;
+ this.getEvents();
+ },
+
+ /**
+ * Stops the EventsManagerManager checking for events.
+ */
+ stop: function() {
+ this.running = false;
+ },
+
+ // private
+ onLogin: function() {
+ this.start();
+ },
+
+ onGetEventsSuccess: function(events) {
+ if (!this.running) return;
+ if (events) {
+ Ext.each(
+ events,
+ function(event) {
+ var name = event[0],
+ args = event[1];
+ args.splice(0, 0, name);
+ this.fireEvent.apply(this, args);
+ },
+ this
+ );
+ }
+ this.getEvents();
+ },
+
+ // private
+ onGetEventsFailure: function(result, error) {
+ // the request timed out or we had a communication failure
+ if (!this.running) return;
+ if (!error.isTimeout && this.errorCount++ >= 3) {
+ this.stop();
+ return;
+ }
+ this.getEvents();
+ },
+});
+
+/**
+ * Appends an event handler to this object (shorthand for {@link #addListener})
+ * @method
+ */
+Deluge.EventsManager.prototype.on = Deluge.EventsManager.prototype.addListener;
+
+/**
+ * Fires the specified event with the passed parameters (minus the
+ * event name).
+ * @method
+ */
+Deluge.EventsManager.prototype.fire = Deluge.EventsManager.prototype.fireEvent;
+deluge.events = new Deluge.EventsManager();
+/**
+ * Deluge.FileBrowser.js
+ *
+ * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge');
+Deluge.FileBrowser = Ext.extend(Ext.Window, {
+ title: _('File Browser'),
+
+ width: 500,
+ height: 400,
+
+ initComponent: function() {
+ Deluge.FileBrowser.superclass.initComponent.call(this);
+
+ this.add({
+ xtype: 'toolbar',
+ items: [
+ {
+ text: _('Back'),
+ iconCls: 'icon-back',
+ },
+ {
+ text: _('Forward'),
+ iconCls: 'icon-forward',
+ },
+ {
+ text: _('Up'),
+ iconCls: 'icon-up',
+ },
+ {
+ text: _('Home'),
+ iconCls: 'icon-home',
+ },
+ ],
+ });
+ },
+});
+/**
+ * Deluge.FilterPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.FilterPanel
+ * @extends Ext.list.ListView
+ */
+Deluge.FilterPanel = Ext.extend(Ext.Panel, {
+ autoScroll: true,
+
+ border: false,
+
+ show_zero: null,
+
+ initComponent: function() {
+ Deluge.FilterPanel.superclass.initComponent.call(this);
+ this.filterType = this.initialConfig.filter;
+ var title = '';
+ if (this.filterType == 'state') {
+ title = _('States');
+ } else if (this.filterType == 'tracker_host') {
+ title = _('Trackers');
+ } else if (this.filterType == 'owner') {
+ title = _('Owner');
+ } else if (this.filterType == 'label') {
+ title = _('Labels');
+ } else {
+ (title = this.filterType.replace('_', ' ')),
+ (parts = title.split(' ')),
+ (title = '');
+ Ext.each(parts, function(p) {
+ fl = p.substring(0, 1).toUpperCase();
+ title += fl + p.substring(1) + ' ';
+ });
+ }
+ this.setTitle(_(title));
+
+ if (Deluge.FilterPanel.templates[this.filterType]) {
+ var tpl = Deluge.FilterPanel.templates[this.filterType];
+ } else {
+ var tpl =
+ '<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';
+ }
+
+ this.list = this.add({
+ xtype: 'listview',
+ singleSelect: true,
+ hideHeaders: true,
+ reserveScrollOffset: true,
+ store: new Ext.data.ArrayStore({
+ idIndex: 0,
+ fields: ['filter', 'count'],
+ }),
+ columns: [
+ {
+ id: 'filter',
+ sortable: false,
+ tpl: tpl,
+ dataIndex: 'filter',
+ },
+ ],
+ });
+ this.relayEvents(this.list, ['selectionchange']);
+ },
+
+ /**
+ * Return the currently selected filter state
+ * @returns {String} the current filter state
+ */
+ getState: function() {
+ if (!this.list.getSelectionCount()) return;
+
+ var state = this.list.getSelectedRecords()[0];
+ if (!state) return;
+ if (state.id == 'All') return;
+ return state.id;
+ },
+
+ /**
+ * Return the current states in the filter
+ */
+ getStates: function() {
+ return this.states;
+ },
+
+ /**
+ * Return the Store for the ListView of the FilterPanel
+ * @returns {Ext.data.Store} the ListView store
+ */
+ getStore: function() {
+ return this.list.getStore();
+ },
+
+ /**
+ * Update the states in the FilterPanel
+ */
+ updateStates: function(states) {
+ this.states = {};
+ Ext.each(
+ states,
+ function(state) {
+ this.states[state[0]] = state[1];
+ },
+ this
+ );
+
+ var show_zero =
+ this.show_zero == null
+ ? deluge.config.sidebar_show_zero
+ : this.show_zero;
+ if (!show_zero) {
+ var newStates = [];
+ Ext.each(states, function(state) {
+ if (state[1] > 0 || state[0] == 'All') {
+ newStates.push(state);
+ }
+ });
+ states = newStates;
+ }
+
+ var store = this.getStore();
+ var filters = {};
+ Ext.each(
+ states,
+ function(s, i) {
+ var record = store.getById(s[0]);
+ if (!record) {
+ record = new store.recordType({
+ filter: s[0],
+ count: s[1],
+ });
+ record.id = s[0];
+ store.insert(i, record);
+ }
+ record.beginEdit();
+ record.set('filter', _(s[0]));
+ record.set('count', s[1]);
+ record.endEdit();
+ filters[s[0]] = true;
+ },
+ this
+ );
+
+ store.each(function(record) {
+ if (filters[record.id]) return;
+ store.remove(record);
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ if (selected.id == record.id) {
+ this.list.select(0);
+ }
+ }, this);
+
+ store.commitChanges();
+
+ if (!this.list.getSelectionCount()) {
+ this.list.select(0);
+ }
+ },
+});
+
+Deluge.FilterPanel.templates = {
+ tracker_host:
+ '<div class="x-deluge-filter" style="background-image: url(' +
+ deluge.config.base +
+ 'tracker/{filter});">{filter} ({count})</div>',
+};
+/**
+ * Deluge.Formatters.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * A collection of functions for string formatting values.
+ * @class Deluge.Formatters
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ * @singleton
+ */
+Deluge.Formatters = {
+ /**
+ * Formats a date string in the date representation of the current locale,
+ * based on the systems timezone.
+ *
+ * @param {Number} timestamp time in seconds since the Epoch.
+ * @return {String} a string in the date representation of the current locale
+ * or "" if seconds < 0.
+ */
+ date: function(timestamp) {
+ function zeroPad(num, count) {
+ var numZeropad = num + '';
+ while (numZeropad.length < count) {
+ numZeropad = '0' + numZeropad;
+ }
+ return numZeropad;
+ }
+ timestamp = timestamp * 1000;
+ var date = new Date(timestamp);
+ return String.format(
+ '{0}/{1}/{2} {3}:{4}:{5}',
+ zeroPad(date.getDate(), 2),
+ zeroPad(date.getMonth() + 1, 2),
+ date.getFullYear(),
+ zeroPad(date.getHours(), 2),
+ zeroPad(date.getMinutes(), 2),
+ zeroPad(date.getSeconds(), 2)
+ );
+ },
+
+ /**
+ * Formats the bytes value into a string with KiB, MiB or GiB units.
+ *
+ * @param {Number} bytes the filesize in bytes
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with KiB, MiB or GiB units.
+ */
+ size: function(bytes, showZero) {
+ if (!bytes && !showZero) return '';
+ bytes = bytes / 1024.0;
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' KiB';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' MiB';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ return bytes.toFixed(1) + ' GiB';
+ },
+
+ /**
+ * Formats the bytes value into a string with K, M or G units.
+ *
+ * @param {Number} bytes the filesize in bytes
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with K, M or G units.
+ */
+ sizeShort: function(bytes, showZero) {
+ if (!bytes && !showZero) return '';
+ bytes = bytes / 1024.0;
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' K';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' M';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ return bytes.toFixed(1) + ' G';
+ },
+
+ /**
+ * Formats a string to display a transfer speed utilizing {@link #size}
+ *
+ * @param {Number} bytes the number of bytes per second
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with KiB, MiB or GiB units.
+ */
+ speed: function(bytes, showZero) {
+ return !bytes && !showZero ? '' : fsize(bytes, showZero) + '/s';
+ },
+
+ /**
+ * Formats a string to show time in a human readable form.
+ *
+ * @param {Number} time the number of seconds
+ * @return {String} a formatted time string. will return '' if seconds == 0
+ */
+ timeRemaining: function(time) {
+ if (time <= 0) {
+ return '&infin;';
+ }
+ time = time.toFixed(0);
+ if (time < 60) {
+ return time + 's';
+ } else {
+ time = time / 60;
+ }
+
+ if (time < 60) {
+ var minutes = Math.floor(time);
+ var seconds = Math.round(60 * (time - minutes));
+ if (seconds > 0) {
+ return minutes + 'm ' + seconds + 's';
+ } else {
+ return minutes + 'm';
+ }
+ } else {
+ time = time / 60;
+ }
+
+ if (time < 24) {
+ var hours = Math.floor(time);
+ var minutes = Math.round(60 * (time - hours));
+ if (minutes > 0) {
+ return hours + 'h ' + minutes + 'm';
+ } else {
+ return hours + 'h';
+ }
+ } else {
+ time = time / 24;
+ }
+
+ var days = Math.floor(time);
+ var hours = Math.round(24 * (time - days));
+ if (hours > 0) {
+ return days + 'd ' + hours + 'h';
+ } else {
+ return days + 'd';
+ }
+ },
+
+ /**
+ * Simply returns the value untouched, for when no formatting is required.
+ *
+ * @param {Mixed} value the value to be displayed
+ * @return the untouched value.
+ */
+ plain: function(value) {
+ return value;
+ },
+
+ cssClassEscape: function(value) {
+ return value.toLowerCase().replace('.', '_');
+ },
+};
+var fsize = Deluge.Formatters.size;
+var fsize_short = Deluge.Formatters.sizeShort;
+var fspeed = Deluge.Formatters.speed;
+var ftime = Deluge.Formatters.timeRemaining;
+var fdate = Deluge.Formatters.date;
+var fplain = Deluge.Formatters.plain;
+Ext.util.Format.cssClassEscape = Deluge.Formatters.cssClassEscape;
+/**
+ * Deluge.Keys.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @description The torrent status keys that are commonly used around the UI.
+ * @class Deluge.Keys
+ * @singleton
+ */
+Deluge.Keys = {
+ /**
+ * Keys that are used within the torrent grid.
+ * <pre>['queue', 'name', 'total_wanted', 'state', 'progress', 'num_seeds',
+ * 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
+ * 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
+ * 'is_auto_managed', 'time_added', 'tracker_host', 'download_location', 'last_seen_complete',
+ * 'total_done', 'total_uploaded', 'max_download_speed', 'max_upload_speed',
+ * 'seeds_peers_ratio', 'total_remaining', 'completed_time', 'time_since_transfer']</pre>
+ */
+ Grid: [
+ 'queue',
+ 'name',
+ 'total_wanted',
+ 'state',
+ 'progress',
+ 'num_seeds',
+ 'total_seeds',
+ 'num_peers',
+ 'total_peers',
+ 'download_payload_rate',
+ 'upload_payload_rate',
+ 'eta',
+ 'ratio',
+ 'distributed_copies',
+ 'is_auto_managed',
+ 'time_added',
+ 'tracker_host',
+ 'download_location',
+ 'last_seen_complete',
+ 'total_done',
+ 'total_uploaded',
+ 'max_download_speed',
+ 'max_upload_speed',
+ 'seeds_peers_ratio',
+ 'total_remaining',
+ 'completed_time',
+ 'time_since_transfer',
+ ],
+
+ /**
+ * Keys used in the status tab of the statistics panel.
+ * These get updated to include the keys in {@link #Grid}.
+ * <pre>['total_done', 'total_payload_download', 'total_uploaded',
+ * 'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
+ * 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time', 'time_since_transfer',
+ * 'seed_rank', 'last_seen_complete', 'completed_time', 'owner', 'public', 'shared']</pre>
+ */
+ Status: [
+ 'total_done',
+ 'total_payload_download',
+ 'total_uploaded',
+ 'total_payload_upload',
+ 'next_announce',
+ 'tracker_status',
+ 'num_pieces',
+ 'piece_length',
+ 'is_auto_managed',
+ 'active_time',
+ 'seeding_time',
+ 'time_since_transfer',
+ 'seed_rank',
+ 'last_seen_complete',
+ 'completed_time',
+ 'owner',
+ 'public',
+ 'shared',
+ ],
+
+ /**
+ * Keys used in the files tab of the statistics panel.
+ * <pre>['files', 'file_progress', 'file_priorities']</pre>
+ */
+ Files: ['files', 'file_progress', 'file_priorities'],
+
+ /**
+ * Keys used in the peers tab of the statistics panel.
+ * <pre>['peers']</pre>
+ */
+ Peers: ['peers'],
+
+ /**
+ * Keys used in the details tab of the statistics panel.
+ */
+ Details: [
+ 'name',
+ 'download_location',
+ 'total_size',
+ 'num_files',
+ 'message',
+ 'tracker_host',
+ 'comment',
+ 'creator',
+ ],
+
+ /**
+ * Keys used in the options tab of the statistics panel.
+ * <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
+ * 'is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'remove_at_ratio', 'private',
+ * 'prioritize_first_last']</pre>
+ */
+ Options: [
+ 'max_download_speed',
+ 'max_upload_speed',
+ 'max_connections',
+ 'max_upload_slots',
+ 'is_auto_managed',
+ 'stop_at_ratio',
+ 'stop_ratio',
+ 'remove_at_ratio',
+ 'private',
+ 'prioritize_first_last',
+ 'move_completed',
+ 'move_completed_path',
+ 'super_seeding',
+ ],
+};
+
+// Merge the grid and status keys together as the status keys contain all the
+// grid ones.
+Ext.each(Deluge.Keys.Grid, function(key) {
+ Deluge.Keys.Status.push(key);
+});
+/**
+ * Deluge.LoginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.LoginWindow = Ext.extend(Ext.Window, {
+ firstShow: true,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'center',
+ closable: false,
+ closeAction: 'hide',
+ iconCls: 'x-deluge-login-window-icon',
+ layout: 'fit',
+ modal: true,
+ plain: true,
+ resizable: false,
+ title: _('Login'),
+ width: 300,
+ height: 120,
+
+ initComponent: function() {
+ Deluge.LoginWindow.superclass.initComponent.call(this);
+ this.on('show', this.onShow, this);
+
+ this.addButton({
+ text: _('Login'),
+ handler: this.onLogin,
+ scope: this,
+ });
+
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ labelWidth: 120,
+ labelAlign: 'right',
+ defaults: { width: 110 },
+ defaultType: 'textfield',
+ });
+
+ this.passwordField = this.form.add({
+ xtype: 'textfield',
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ grow: true,
+ growMin: '110',
+ growMax: '145',
+ id: '_password',
+ name: 'password',
+ inputType: 'password',
+ });
+ this.passwordField.on('specialkey', this.onSpecialKey, this);
+ },
+
+ logout: function() {
+ deluge.events.fire('logout');
+ deluge.client.auth.delete_session({
+ success: function(result) {
+ this.show(true);
+ },
+ scope: this,
+ });
+ },
+
+ show: function(skipCheck) {
+ if (this.firstShow) {
+ deluge.client.on('error', this.onClientError, this);
+ this.firstShow = false;
+ }
+
+ if (skipCheck) {
+ return Deluge.LoginWindow.superclass.show.call(this);
+ }
+
+ deluge.client.auth.check_session({
+ success: function(result) {
+ if (result) {
+ deluge.events.fire('login');
+ } else {
+ this.show(true);
+ }
+ },
+ failure: function(result) {
+ this.show(true);
+ },
+ scope: this,
+ });
+ },
+
+ onSpecialKey: function(field, e) {
+ if (e.getKey() == 13) this.onLogin();
+ },
+
+ onLogin: function() {
+ var passwordField = this.passwordField;
+ deluge.client.auth.login(passwordField.getValue(), {
+ success: function(result) {
+ if (result) {
+ deluge.events.fire('login');
+ this.hide();
+ passwordField.setRawValue('');
+ } else {
+ Ext.MessageBox.show({
+ title: _('Login Failed'),
+ msg: _('You entered an incorrect password'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ fn: function() {
+ passwordField.focus(true, 10);
+ },
+ icon: Ext.MessageBox.WARNING,
+ iconCls: 'x-deluge-icon-warning',
+ });
+ }
+ },
+ scope: this,
+ });
+ },
+
+ onClientError: function(errorObj, response, requestOptions) {
+ if (errorObj.error.code == 1) {
+ deluge.events.fire('logout');
+ this.show(true);
+ }
+ },
+
+ onShow: function() {
+ this.passwordField.focus(true, 300);
+ },
+});
+/**
+ * Deluge.Menus.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+deluge.menus = {
+ onTorrentActionSetOpt: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ var opts = {};
+ opts[action[0]] = action[1];
+ deluge.client.core.set_torrent_options(ids, opts);
+ },
+
+ onTorrentActionMethod: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ deluge.client.core[action](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ },
+
+ onTorrentActionShow: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ switch (action) {
+ case 'edit_trackers':
+ deluge.editTrackers.show();
+ break;
+ case 'remove':
+ deluge.removeWindow.show(ids);
+ break;
+ case 'move':
+ deluge.moveStorage.show(ids);
+ break;
+ }
+ },
+};
+
+deluge.menus.torrent = new Ext.menu.Menu({
+ id: 'torrentMenu',
+ items: [
+ {
+ torrentAction: 'pause_torrent',
+ text: _('Pause'),
+ iconCls: 'icon-pause',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'resume_torrent',
+ text: _('Resume'),
+ iconCls: 'icon-resume',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ text: _('Options'),
+ iconCls: 'icon-options',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ text: _('D/L Speed Limit'),
+ iconCls: 'x-deluge-downloading',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_download_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('U/L Speed Limit'),
+ iconCls: 'x-deluge-seeding',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_upload_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('Connection Limit'),
+ iconCls: 'x-deluge-connections',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_connections', 50],
+ text: '50',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 100],
+ text: '100',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 200],
+ text: '200',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 300],
+ text: '300',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 500],
+ text: '500',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('Upload Slot Limit'),
+ iconCls: 'icon-upload-slots',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_upload_slots', 0],
+ text: '0',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 1],
+ text: '1',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 2],
+ text: '2',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 3],
+ text: '3',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 5],
+ text: '5',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ id: 'auto_managed',
+ text: _('Auto Managed'),
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['auto_managed', true],
+ text: _('On'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['auto_managed', false],
+ text: _('Off'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ ],
+ }),
+ },
+ '-',
+ {
+ text: _('Queue'),
+ iconCls: 'icon-queue',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: 'queue_top',
+ text: _('Top'),
+ iconCls: 'icon-top',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_up',
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_down',
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_bottom',
+ text: _('Bottom'),
+ iconCls: 'icon-bottom',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ '-',
+ {
+ torrentAction: 'force_reannounce',
+ text: _('Update Tracker'),
+ iconCls: 'icon-update-tracker',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'edit_trackers',
+ text: _('Edit Trackers'),
+ iconCls: 'icon-edit-trackers',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ torrentAction: 'remove',
+ text: _('Remove Torrent'),
+ iconCls: 'icon-remove',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ torrentAction: 'force_recheck',
+ text: _('Force Recheck'),
+ iconCls: 'icon-recheck',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'move',
+ text: _('Move Download Folder'),
+ iconCls: 'icon-move',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ ],
+});
+
+deluge.menus.filePriorities = new Ext.menu.Menu({
+ id: 'filePrioritiesMenu',
+ items: [
+ {
+ id: 'expandAll',
+ text: _('Expand All'),
+ iconCls: 'icon-expand-all',
+ },
+ '-',
+ {
+ id: 'skip',
+ text: _('Skip'),
+ iconCls: 'icon-do-not-download',
+ filePriority: FILE_PRIORITY['Skip'],
+ },
+ {
+ id: 'low',
+ text: _('Low'),
+ iconCls: 'icon-low',
+ filePriority: FILE_PRIORITY['Low'],
+ },
+ {
+ id: 'normal',
+ text: _('Normal'),
+ iconCls: 'icon-normal',
+ filePriority: FILE_PRIORITY['Normal'],
+ },
+ {
+ id: 'high',
+ text: _('High'),
+ iconCls: 'icon-high',
+ filePriority: FILE_PRIORITY['High'],
+ },
+ ],
+});
+/**
+ * Deluge.MoveStorage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge');
+Deluge.MoveStorage = Ext.extend(Ext.Window, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ title: _('Move Download Folder'),
+ width: 375,
+ height: 110,
+ layout: 'fit',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-move-storage',
+ plain: true,
+ constrainHeader: true,
+ resizable: false,
+ },
+ config
+ );
+ Deluge.MoveStorage.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.MoveStorage.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancel, this);
+ this.addButton(_('Move'), this.onMove, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ border: false,
+ defaultType: 'textfield',
+ width: 300,
+ bodyStyle: 'padding: 5px',
+ });
+
+ this.moveLocation = this.form.add({
+ fieldLabel: _('Download Folder'),
+ name: 'location',
+ width: 240,
+ });
+ //this.form.add({
+ // xtype: 'button',
+ // text: _('Browse'),
+ // handler: function() {
+ // if (!this.fileBrowser) {
+ // this.fileBrowser = new Deluge.FileBrowser();
+ // }
+ // this.fileBrowser.show();
+ // },
+ // scope: this
+ //});
+ },
+
+ hide: function() {
+ Deluge.MoveStorage.superclass.hide.call(this);
+ this.torrentIds = null;
+ },
+
+ show: function(torrentIds) {
+ Deluge.MoveStorage.superclass.show.call(this);
+ this.torrentIds = torrentIds;
+ },
+
+ onCancel: function() {
+ this.hide();
+ },
+
+ onMove: function() {
+ var dest = this.moveLocation.getValue();
+ deluge.client.core.move_storage(this.torrentIds, dest);
+ this.hide();
+ },
+});
+deluge.moveStorage = new Deluge.MoveStorage();
+/**
+ * Deluge.MultiOptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @description A class that can be used to manage options throughout the ui.
+ * @namespace Deluge
+ * @class Deluge.MultiOptionsManager
+ * @extends Deluge.OptionsManager
+ */
+Deluge.MultiOptionsManager = Ext.extend(Deluge.OptionsManager, {
+ constructor: function(config) {
+ this.currentId = null;
+ this.stored = {};
+ Deluge.MultiOptionsManager.superclass.constructor.call(this, config);
+ },
+
+ /**
+ * Changes bound fields to use the specified id.
+ * @param {String} id
+ */
+ changeId: function(id, dontUpdateBinds) {
+ var oldId = this.currentId;
+ this.currentId = id;
+ if (!dontUpdateBinds) {
+ for (var option in this.options) {
+ if (!this.binds[option]) continue;
+ Ext.each(
+ this.binds[option],
+ function(bind) {
+ bind.setValue(this.get(option));
+ },
+ this
+ );
+ }
+ }
+ return oldId;
+ },
+
+ /**
+ * Changes all the changed values to be the default values
+ * @param {String} id
+ */
+ commit: function() {
+ this.stored[this.currentId] = Ext.apply(
+ this.stored[this.currentId],
+ this.changed[this.currentId]
+ );
+ this.reset();
+ },
+
+ /**
+ * Get the value for an option
+ * @param {String/Array} option A single option or an array of options to return.
+ * @returns {Object} the options value.
+ */
+ get: function() {
+ if (arguments.length == 1) {
+ var option = arguments[0];
+ return this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ } else if (arguments.length == 0) {
+ var options = {};
+ for (var option in this.options) {
+ options[option] = this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ }
+ return options;
+ } else {
+ var options = {};
+ Ext.each(
+ arguments,
+ function(option) {
+ options[option] = this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ },
+ this
+ );
+ return options;
+ }
+ },
+
+ /**
+ * Get the default value for an option.
+ * @param {String} option A single option.
+ * @returns {Object} the value of the option
+ */
+ getDefault: function(option) {
+ return this.has(option)
+ ? this.stored[this.currentId][option]
+ : this.options[option];
+ },
+
+ /**
+ * Returns the dirty (changed) values.
+ * @returns {Object} the changed options
+ */
+ getDirty: function() {
+ return this.changed[this.currentId] ? this.changed[this.currentId] : {};
+ },
+
+ /**
+ * Check to see if the option has been changed.
+ * @param {String} option
+ * @returns {Boolean} true if the option has been changed, else false.
+ */
+ isDirty: function(option) {
+ return (
+ this.changed[this.currentId] &&
+ !Ext.isEmpty(this.changed[this.currentId][option])
+ );
+ },
+
+ /**
+ * Check to see if an id has had an option set to something other than the
+ * default value.
+ * @param {String} option
+ * @returns {Boolean} true if the id has an option, else false.
+ */
+ has: function(option) {
+ return (
+ this.stored[this.currentId] &&
+ !Ext.isEmpty(this.stored[this.currentId][option])
+ );
+ },
+
+ /**
+ * Reset the options back to the default values for the specified id.
+ */
+ reset: function() {
+ if (this.changed[this.currentId]) delete this.changed[this.currentId];
+ if (this.stored[this.currentId]) delete this.stored[this.currentId];
+ },
+
+ /**
+ * Reset the options back to their defaults for all ids.
+ */
+ resetAll: function() {
+ this.changed = {};
+ this.stored = {};
+ this.changeId(null);
+ },
+
+ /**
+ * Sets the value of specified option for the passed in id.
+ * @param {String} id
+ * @param {String} option
+ * @param {Object} value The value for the option
+ */
+ setDefault: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.setDefault(key, option[key]);
+ }
+ } else {
+ var oldValue = this.getDefault(option);
+ value = this.convertValueType(oldValue, value);
+
+ // If the value is the same as the old value there is
+ // no point in setting it again.
+ if (oldValue == value) return;
+
+ // Store the new default
+ if (!this.stored[this.currentId]) this.stored[this.currentId] = {};
+ this.stored[this.currentId][option] = value;
+
+ if (!this.isDirty(option)) {
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ }
+ },
+
+ /**
+ * Update the value for the specified option and id.
+ * @param {String} id
+ * @param {String/Object} option or options to update
+ * @param {Object} [value];
+ */
+ update: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.update(key, option[key]);
+ }
+ } else {
+ if (!this.changed[this.currentId])
+ this.changed[this.currentId] = {};
+
+ var defaultValue = this.getDefault(option);
+ value = this.convertValueType(defaultValue, value);
+
+ var oldValue = this.get(option);
+ if (oldValue == value) return;
+
+ if (defaultValue == value) {
+ if (this.isDirty(option))
+ delete this.changed[this.currentId][option];
+ this.fireEvent('changed', option, value, oldValue);
+ return;
+ } else {
+ this.changed[this.currentId][option] = value;
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ }
+ },
+});
+/**
+ * Deluge.OtherLimitWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.OtherLimitWindow
+ * @extends Ext.Window
+ */
+Deluge.OtherLimitWindow = Ext.extend(Ext.Window, {
+ layout: 'fit',
+ width: 210,
+ height: 100,
+ constrainHeader: true,
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.OtherLimitWindow.superclass.initComponent.call(this);
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ bodyStyle: 'padding: 5px',
+ layout: 'hbox',
+ layoutConfig: {
+ pack: 'start',
+ },
+ items: [
+ {
+ xtype: 'spinnerfield',
+ name: 'limit',
+ },
+ ],
+ });
+ if (this.initialConfig.unit) {
+ this.form.add({
+ border: false,
+ baseCls: 'x-plain',
+ bodyStyle: 'padding: 5px',
+ html: this.initialConfig.unit,
+ });
+ } else {
+ this.setSize(180, 100);
+ }
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('OK'), this.onOkClick, this);
+ this.afterMethod('show', this.doFocusField, this);
+ },
+
+ setValue: function(value) {
+ this.form.getForm().setValues({ limit: value });
+ },
+
+ onCancelClick: function() {
+ this.form.getForm().reset();
+ this.hide();
+ },
+
+ onOkClick: function() {
+ var config = {};
+ config[this.group] = this.form.getForm().getValues().limit;
+ deluge.client.core.set_config(config, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ this.hide();
+ },
+
+ doFocusField: function() {
+ this.form
+ .getForm()
+ .findField('limit')
+ .focus(true, 10);
+ },
+});
+/**
+ * Deluge.Plugin.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.Plugin
+ * @extends Ext.util.Observable
+ */
+Deluge.Plugin = Ext.extend(Ext.util.Observable, {
+ /**
+ * The plugins name
+ * @property name
+ * @type {String}
+ */
+ name: null,
+
+ constructor: function(config) {
+ this.isDelugePlugin = true;
+ this.addEvents({
+ /**
+ * @event enabled
+ * @param {Plugin} plugin the plugin instance
+ */
+ enabled: true,
+
+ /**
+ * @event disabled
+ * @param {Plugin} plugin the plugin instance
+ */
+ disabled: true,
+ });
+ Deluge.Plugin.superclass.constructor.call(this, config);
+ },
+
+ /**
+ * Disables the plugin, firing the "{@link #disabled}" event and
+ * then executing the plugins clean up method onDisabled.
+ */
+ disable: function() {
+ this.fireEvent('disabled', this);
+ if (this.onDisable) this.onDisable();
+ },
+
+ /**
+ * Enables the plugin, firing the "{@link #enabled}" event and
+ * then executes the plugins setup method, onEnabled.
+ */
+ enable: function() {
+ deluge.client.reloadMethods();
+ this.fireEvent('enable', this);
+ if (this.onEnable) this.onEnable();
+ },
+
+ registerTorrentStatus: function(key, header, options) {
+ options = options || {};
+ var cc = options.colCfg || {},
+ sc = options.storeCfg || {};
+ sc = Ext.apply(sc, { name: key });
+ deluge.torrents.meta.fields.push(sc);
+ deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
+
+ cc = Ext.apply(cc, {
+ header: header,
+ dataIndex: key,
+ });
+ var cols = deluge.torrents.columns.slice(0);
+ cols.push(cc);
+ deluge.torrents.colModel.setConfig(cols);
+ deluge.torrents.columns = cols;
+
+ Deluge.Keys.Grid.push(key);
+ deluge.torrents.getView().refresh(true);
+ },
+
+ deregisterTorrentStatus: function(key) {
+ var fields = [];
+ Ext.each(deluge.torrents.meta.fields, function(field) {
+ if (field.name != key) fields.push(field);
+ });
+ deluge.torrents.meta.fields = fields;
+ deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
+
+ var cols = [];
+ Ext.each(deluge.torrents.columns, function(col) {
+ if (col.dataIndex != key) cols.push(col);
+ });
+ deluge.torrents.colModel.setConfig(cols);
+ deluge.torrents.columns = cols;
+
+ var keys = [];
+ Ext.each(Deluge.Keys.Grid, function(k) {
+ if (k == key) keys.push(k);
+ });
+ Deluge.Keys.Grid = keys;
+ deluge.torrents.getView().refresh(true);
+ },
+});
+
+Ext.ns('Deluge.plugins');
+/**
+ * Deluge.RemoveWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @class Deluge.RemoveWindow
+ * @extends Ext.Window
+ */
+Deluge.RemoveWindow = Ext.extend(Ext.Window, {
+ title: _('Remove Torrent'),
+ layout: 'fit',
+ width: 350,
+ height: 100,
+ constrainHeader: true,
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-remove-window-icon',
+ plain: true,
+
+ bodyStyle: 'padding: 5px; padding-left: 10px;',
+ html: 'Are you sure you wish to remove the torrent (s)?',
+
+ initComponent: function() {
+ Deluge.RemoveWindow.superclass.initComponent.call(this);
+ this.addButton(_('Cancel'), this.onCancel, this);
+ this.addButton(_('Remove With Data'), this.onRemoveData, this);
+ this.addButton(_('Remove Torrent'), this.onRemove, this);
+ },
+
+ remove: function(removeData) {
+ deluge.client.core.remove_torrents(this.torrentIds, removeData, {
+ success: function(result) {
+ if (result == true) {
+ console.log(
+ 'Error(s) occured when trying to delete torrent(s).'
+ );
+ }
+ this.onRemoved(this.torrentIds);
+ },
+ scope: this,
+ torrentIds: this.torrentIds,
+ });
+ },
+
+ show: function(ids) {
+ Deluge.RemoveWindow.superclass.show.call(this);
+ this.torrentIds = ids;
+ },
+
+ onCancel: function() {
+ this.hide();
+ this.torrentIds = null;
+ },
+
+ onRemove: function() {
+ this.remove(false);
+ },
+
+ onRemoveData: function() {
+ this.remove(true);
+ },
+
+ onRemoved: function(torrentIds) {
+ deluge.events.fire('torrentsRemoved', torrentIds);
+ this.hide();
+ deluge.ui.update();
+ },
+});
+
+deluge.removeWindow = new Deluge.RemoveWindow();
+/**
+ * Deluge.Sidebar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// These are just so gen_gettext.py will pick up the strings
+// _('State')
+// _('Tracker Host')
+
+/**
+ * @class Deluge.Sidebar
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ */
+Deluge.Sidebar = Ext.extend(Ext.Panel, {
+ // private
+ panels: {},
+
+ // private
+ selected: null,
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'sidebar',
+ region: 'west',
+ cls: 'deluge-sidebar',
+ title: _('Filters'),
+ layout: 'accordion',
+ split: true,
+ width: 200,
+ minSize: 100,
+ collapsible: true,
+ },
+ config
+ );
+ Deluge.Sidebar.superclass.constructor.call(this, config);
+ },
+
+ // private
+ initComponent: function() {
+ Deluge.Sidebar.superclass.initComponent.call(this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ },
+
+ createFilter: function(filter, states) {
+ var panel = new Deluge.FilterPanel({
+ filter: filter,
+ });
+ panel.on('selectionchange', function(view, nodes) {
+ deluge.ui.update();
+ });
+ this.add(panel);
+
+ this.doLayout();
+ this.panels[filter] = panel;
+
+ panel.header.on('click', function(header) {
+ if (!deluge.config.sidebar_multiple_filters) {
+ deluge.ui.update();
+ }
+ if (!panel.list.getSelectionCount()) {
+ panel.list.select(0);
+ }
+ });
+ this.fireEvent('filtercreate', this, panel);
+
+ panel.updateStates(states);
+ this.fireEvent('afterfiltercreate', this, panel);
+ },
+
+ getFilter: function(filter) {
+ return this.panels[filter];
+ },
+
+ getFilterStates: function() {
+ var states = {};
+
+ if (deluge.config.sidebar_multiple_filters) {
+ // Grab the filters from each of the filter panels
+ this.items.each(function(panel) {
+ var state = panel.getState();
+ if (state == null) return;
+ states[panel.filterType] = state;
+ }, this);
+ } else {
+ var panel = this.getLayout().activeItem;
+ if (panel) {
+ var state = panel.getState();
+ if (!state == null) return;
+ states[panel.filterType] = state;
+ }
+ }
+
+ return states;
+ },
+
+ hasFilter: function(filter) {
+ return this.panels[filter] ? true : false;
+ },
+
+ // private
+ onDisconnect: function() {
+ for (var filter in this.panels) {
+ this.remove(this.panels[filter]);
+ }
+ this.panels = {};
+ this.selected = null;
+ },
+
+ onFilterSelect: function(selModel, rowIndex, record) {
+ deluge.ui.update();
+ },
+
+ update: function(filters) {
+ for (var filter in filters) {
+ var states = filters[filter];
+ if (Ext.getKeys(this.panels).indexOf(filter) > -1) {
+ this.panels[filter].updateStates(states);
+ } else {
+ this.createFilter(filter, states);
+ }
+ }
+
+ // Perform a cleanup of fitlers that are not enabled any more.
+ Ext.each(
+ Ext.keys(this.panels),
+ function(filter) {
+ if (Ext.keys(filters).indexOf(filter) == -1) {
+ // We need to remove the panel
+ this.remove(this.panels[filter]);
+ this.doLayout();
+ delete this.panels[filter];
+ }
+ },
+ this
+ );
+ },
+});
+/**
+ * Deluge.Statusbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge');
+
+Deluge.Statusbar = Ext.extend(Ext.ux.StatusBar, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'deluge-statusbar',
+ defaultIconCls: 'x-deluge-statusbar x-not-connected',
+ defaultText: _('Not Connected'),
+ },
+ config
+ );
+ Deluge.Statusbar.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.Statusbar.superclass.initComponent.call(this);
+
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ },
+
+ createButtons: function() {
+ this.buttons = this.add(
+ {
+ id: 'statusbar-connections',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-connections',
+ tooltip: _('Connections'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ text: '50',
+ value: '50',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '100',
+ value: '100',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '200',
+ value: '200',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '300',
+ value: '300',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '500',
+ value: '500',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: _('Unlimited'),
+ value: '-1',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ '-',
+ {
+ text: _('Other'),
+ value: 'other',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Connections'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-downspeed',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-downloading',
+ tooltip: _('Download Speed'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ value: '5',
+ text: _('5 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '10',
+ text: _('10 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '30',
+ text: _('30 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '80',
+ text: _('80 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '300',
+ text: _('300 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '-1',
+ text: _('Unlimited'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ '-',
+ {
+ value: 'other',
+ text: _('Other'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Download Speed'),
+ unit: _('KiB/s'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-upspeed',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-seeding',
+ tooltip: _('Upload Speed'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ value: '5',
+ text: _('5 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '10',
+ text: _('10 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '30',
+ text: _('30 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '80',
+ text: _('80 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '300',
+ text: _('300 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '-1',
+ text: _('Unlimited'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ '-',
+ {
+ value: 'other',
+ text: _('Other'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Upload Speed'),
+ unit: _('KiB/s'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-traffic',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-traffic',
+ tooltip: _('Protocol Traffic Download/Upload'),
+ handler: function() {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Network');
+ },
+ },
+ '-',
+ {
+ id: 'statusbar-externalip',
+ text: ' ',
+ cls: 'x-btn-text',
+ tooltip: _('External IP Address'),
+ },
+ '-',
+ {
+ id: 'statusbar-dht',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-dht',
+ tooltip: _('DHT Nodes'),
+ },
+ '-',
+ {
+ id: 'statusbar-freespace',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-freespace',
+ tooltip: _('Freespace in download folder'),
+ handler: function() {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Downloads');
+ },
+ }
+ );
+ this.created = true;
+ },
+
+ onConnect: function() {
+ this.setStatus({
+ iconCls: 'x-connected',
+ text: '',
+ });
+ if (!this.created) {
+ this.createButtons();
+ } else {
+ Ext.each(this.buttons, function(item) {
+ item.show();
+ item.enable();
+ });
+ }
+ this.doLayout();
+ },
+
+ onDisconnect: function() {
+ this.clearStatus({ useDefaults: true });
+ Ext.each(this.buttons, function(item) {
+ item.hide();
+ item.disable();
+ });
+ this.doLayout();
+ },
+
+ update: function(stats) {
+ if (!stats) return;
+
+ function addSpeed(val) {
+ return val + ' KiB/s';
+ }
+
+ var updateStat = function(name, config) {
+ var item = this.items.get('statusbar-' + name);
+ if (config.limit.value > 0) {
+ var value = config.value.formatter
+ ? config.value.formatter(config.value.value, true)
+ : config.value.value;
+ var limit = config.limit.formatter
+ ? config.limit.formatter(config.limit.value, true)
+ : config.limit.value;
+ var str = String.format(config.format, value, limit);
+ } else {
+ var str = config.value.formatter
+ ? config.value.formatter(config.value.value, true)
+ : config.value.value;
+ }
+ item.setText(str);
+
+ if (!item.menu) return;
+ item.menu.setValue(config.limit.value);
+ }.createDelegate(this);
+
+ updateStat('connections', {
+ value: { value: stats.num_connections },
+ limit: { value: stats.max_num_connections },
+ format: '{0} ({1})',
+ });
+
+ updateStat('downspeed', {
+ value: {
+ value: stats.download_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.max_download,
+ formatter: addSpeed,
+ },
+ format: '{0} ({1})',
+ });
+
+ updateStat('upspeed', {
+ value: {
+ value: stats.upload_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.max_upload,
+ formatter: addSpeed,
+ },
+ format: '{0} ({1})',
+ });
+
+ updateStat('traffic', {
+ value: {
+ value: stats.download_protocol_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.upload_protocol_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ format: '{0}/{1}',
+ });
+
+ this.items.get('statusbar-dht').setText(stats.dht_nodes);
+ this.items
+ .get('statusbar-freespace')
+ .setText(
+ stats.free_space >= 0 ? fsize(stats.free_space) : _('Error')
+ );
+ this.items
+ .get('statusbar-externalip')
+ .setText(
+ String.format(
+ _('<b>IP</b> {0}'),
+ stats.external_ip ? stats.external_ip : _('n/a')
+ )
+ );
+ },
+});
+/**
+ * Deluge.Toolbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * An extension of the <tt>Ext.Toolbar</tt> class that provides an extensible toolbar for Deluge.
+ * @class Deluge.Toolbar
+ * @extends Ext.Toolbar
+ */
+Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ items: [
+ {
+ id: 'tbar-deluge-text',
+ text: _('Deluge'),
+ iconCls: 'x-deluge-main-panel',
+ handler: this.onAboutClick,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'create',
+ disabled: true,
+ hidden: true,
+ text: _('Create'),
+ iconCls: 'icon-create',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'add',
+ disabled: true,
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onTorrentAdd,
+ },
+ {
+ id: 'remove',
+ disabled: true,
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'pause',
+ disabled: true,
+ text: _('Pause'),
+ iconCls: 'icon-pause',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'resume',
+ disabled: true,
+ text: _('Resume'),
+ iconCls: 'icon-resume',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'up',
+ cls: 'x-btn-text-icon',
+ disabled: true,
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'down',
+ disabled: true,
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'preferences',
+ text: _('Preferences'),
+ iconCls: 'x-deluge-preferences',
+ handler: this.onPreferencesClick,
+ scope: this,
+ },
+ {
+ id: 'connectionman',
+ text: _('Connection Manager'),
+ iconCls: 'x-deluge-connection-manager',
+ handler: this.onConnectionManagerClick,
+ scope: this,
+ },
+ '->',
+ {
+ id: 'help',
+ iconCls: 'icon-help',
+ text: _('Help'),
+ handler: this.onHelpClick,
+ scope: this,
+ },
+ {
+ id: 'logout',
+ iconCls: 'icon-logout',
+ disabled: true,
+ text: _('Logout'),
+ handler: this.onLogout,
+ scope: this,
+ },
+ ],
+ },
+ config
+ );
+ Deluge.Toolbar.superclass.constructor.call(this, config);
+ },
+
+ connectedButtons: ['add', 'remove', 'pause', 'resume', 'up', 'down'],
+
+ initComponent: function() {
+ Deluge.Toolbar.superclass.initComponent.call(this);
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('login', this.onLogin, this);
+ },
+
+ onConnect: function() {
+ Ext.each(
+ this.connectedButtons,
+ function(buttonId) {
+ this.items.get(buttonId).enable();
+ },
+ this
+ );
+ },
+
+ onDisconnect: function() {
+ Ext.each(
+ this.connectedButtons,
+ function(buttonId) {
+ this.items.get(buttonId).disable();
+ },
+ this
+ );
+ },
+
+ onLogin: function() {
+ this.items.get('logout').enable();
+ },
+
+ onLogout: function() {
+ this.items.get('logout').disable();
+ deluge.login.logout();
+ },
+
+ onConnectionManagerClick: function() {
+ deluge.connectionManager.show();
+ },
+
+ onHelpClick: function() {
+ window.open('http://dev.deluge-torrent.org/wiki/UserGuide');
+ },
+
+ onAboutClick: function() {
+ var about = new Deluge.about.AboutWindow();
+ about.show();
+ },
+
+ onPreferencesClick: function() {
+ deluge.preferences.show();
+ },
+
+ onTorrentAction: function(item) {
+ var selection = deluge.torrents.getSelections();
+ var ids = [];
+ Ext.each(selection, function(record) {
+ ids.push(record.id);
+ });
+
+ switch (item.id) {
+ case 'remove':
+ deluge.removeWindow.show(ids);
+ break;
+ case 'pause':
+ case 'resume':
+ deluge.client.core[item.id + '_torrent'](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ break;
+ case 'up':
+ case 'down':
+ deluge.client.core['queue_' + item.id](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ break;
+ }
+ },
+
+ onTorrentAdd: function() {
+ deluge.add.show();
+ },
+});
+/**
+ * Deluge.TorrentGrid.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+(function() {
+ /* Renderers for the Torrent Grid */
+ function queueRenderer(value) {
+ return value == -1 ? '' : value + 1;
+ }
+ function torrentNameRenderer(value, p, r) {
+ return String.format(
+ '<div class="torrent-name x-deluge-{0}">{1}</div>',
+ r.data['state'].toLowerCase(),
+ value
+ );
+ }
+ function torrentSpeedRenderer(value) {
+ if (!value) return;
+ return fspeed(value);
+ }
+ function torrentLimitRenderer(value) {
+ if (value == -1) return '';
+ return fspeed(value * 1024.0);
+ }
+ function torrentProgressRenderer(value, p, r) {
+ value = new Number(value);
+ var progress = value;
+ var text = _(r.data['state']) + ' ' + value.toFixed(2) + '%';
+ if (this.style) {
+ var style = this.style;
+ } else {
+ var style = p.style;
+ }
+ var width = new Number(style.match(/\w+:\s*(\d+)\w+/)[1]);
+ return Deluge.progressBar(value, width - 8, text);
+ }
+ function seedsRenderer(value, p, r) {
+ if (r.data['total_seeds'] > -1) {
+ return String.format('{0} ({1})', value, r.data['total_seeds']);
+ } else {
+ return value;
+ }
+ }
+ function peersRenderer(value, p, r) {
+ if (r.data['total_peers'] > -1) {
+ return String.format('{0} ({1})', value, r.data['total_peers']);
+ } else {
+ return value;
+ }
+ }
+ function availRenderer(value, p, r) {
+ return value < 0 ? '&infin;' : parseFloat(new Number(value).toFixed(3));
+ }
+ function trackerRenderer(value, p, r) {
+ return String.format(
+ '<div style="background: url(' +
+ deluge.config.base +
+ 'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',
+ value
+ );
+ }
+
+ function etaSorter(eta) {
+ return eta * -1;
+ }
+
+ function dateOrNever(date) {
+ return date > 0.0 ? fdate(date) : _('Never');
+ }
+
+ function timeOrInf(time) {
+ return time < 0 ? '&infin;' : ftime(time);
+ }
+
+ /**
+ * Deluge.TorrentGrid Class
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.TorrentGrid
+ * @extends Ext.grid.GridPanel
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+ Deluge.TorrentGrid = Ext.extend(Ext.grid.GridPanel, {
+ // object to store contained torrent ids
+ torrents: {},
+
+ columns: [
+ {
+ id: 'queue',
+ header: '#',
+ width: 30,
+ sortable: true,
+ renderer: queueRenderer,
+ dataIndex: 'queue',
+ },
+ {
+ id: 'name',
+ header: _('Name'),
+ width: 150,
+ sortable: true,
+ renderer: torrentNameRenderer,
+ dataIndex: 'name',
+ },
+ {
+ header: _('Size'),
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_wanted',
+ },
+ {
+ header: _('Progress'),
+ width: 150,
+ sortable: true,
+ renderer: torrentProgressRenderer,
+ dataIndex: 'progress',
+ },
+ {
+ header: _('Seeds'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: seedsRenderer,
+ dataIndex: 'num_seeds',
+ },
+ {
+ header: _('Peers'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: peersRenderer,
+ dataIndex: 'num_peers',
+ },
+ {
+ header: _('Down Speed'),
+ width: 80,
+ sortable: true,
+ renderer: torrentSpeedRenderer,
+ dataIndex: 'download_payload_rate',
+ },
+ {
+ header: _('Up Speed'),
+ width: 80,
+ sortable: true,
+ renderer: torrentSpeedRenderer,
+ dataIndex: 'upload_payload_rate',
+ },
+ {
+ header: _('ETA'),
+ width: 60,
+ sortable: true,
+ renderer: timeOrInf,
+ dataIndex: 'eta',
+ },
+ {
+ header: _('Ratio'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'ratio',
+ },
+ {
+ header: _('Avail'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'distributed_copies',
+ },
+ {
+ header: _('Added'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fdate,
+ dataIndex: 'time_added',
+ },
+ {
+ header: _('Complete Seen'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: dateOrNever,
+ dataIndex: 'last_seen_complete',
+ },
+ {
+ header: _('Completed'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: dateOrNever,
+ dataIndex: 'completed_time',
+ },
+ {
+ header: _('Tracker'),
+ hidden: true,
+ width: 120,
+ sortable: true,
+ renderer: trackerRenderer,
+ dataIndex: 'tracker_host',
+ },
+ {
+ header: _('Download Folder'),
+ hidden: true,
+ width: 120,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'download_location',
+ },
+ {
+ header: _('Owner'),
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'owner',
+ },
+ {
+ header: _('Public'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'public',
+ },
+ {
+ header: _('Shared'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'shared',
+ },
+ {
+ header: _('Downloaded'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_done',
+ },
+ {
+ header: _('Uploaded'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_uploaded',
+ },
+ {
+ header: _('Remaining'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_remaining',
+ },
+ {
+ header: _('Down Limit'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: torrentLimitRenderer,
+ dataIndex: 'max_download_speed',
+ },
+ {
+ header: _('Up Limit'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: torrentLimitRenderer,
+ dataIndex: 'max_upload_speed',
+ },
+ {
+ header: _('Seeds:Peers'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'seeds_peers_ratio',
+ },
+ {
+ header: _('Last Transfer'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: ftime,
+ dataIndex: 'time_since_transfer',
+ },
+ ],
+
+ meta: {
+ root: 'torrents',
+ idProperty: 'id',
+ fields: [
+ {
+ name: 'queue',
+ sortType: Deluge.data.SortTypes.asQueuePosition,
+ },
+ { name: 'name', sortType: Deluge.data.SortTypes.asName },
+ { name: 'total_wanted', type: 'int' },
+ { name: 'state' },
+ { name: 'progress', type: 'float' },
+ { name: 'num_seeds', type: 'int' },
+ { name: 'total_seeds', type: 'int' },
+ { name: 'num_peers', type: 'int' },
+ { name: 'total_peers', type: 'int' },
+ { name: 'download_payload_rate', type: 'int' },
+ { name: 'upload_payload_rate', type: 'int' },
+ { name: 'eta', type: 'int', sortType: etaSorter },
+ { name: 'ratio', type: 'float' },
+ { name: 'distributed_copies', type: 'float' },
+ { name: 'time_added', type: 'int' },
+ { name: 'tracker_host' },
+ { name: 'download_location' },
+ { name: 'total_done', type: 'int' },
+ { name: 'total_uploaded', type: 'int' },
+ { name: 'total_remaining', type: 'int' },
+ { name: 'max_download_speed', type: 'int' },
+ { name: 'max_upload_speed', type: 'int' },
+ { name: 'seeds_peers_ratio', type: 'float' },
+ { name: 'time_since_transfer', type: 'int' },
+ ],
+ },
+
+ keys: [
+ {
+ key: 'a',
+ ctrl: true,
+ stopEvent: true,
+ handler: function() {
+ deluge.torrents.getSelectionModel().selectAll();
+ },
+ },
+ {
+ key: [46],
+ stopEvent: true,
+ handler: function() {
+ ids = deluge.torrents.getSelectedIds();
+ deluge.removeWindow.show(ids);
+ },
+ },
+ ],
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'torrentGrid',
+ store: new Ext.data.JsonStore(this.meta),
+ columns: this.columns,
+ keys: this.keys,
+ region: 'center',
+ cls: 'deluge-torrents',
+ stripeRows: true,
+ autoExpandColumn: 'name',
+ autoExpandMin: 150,
+ deferredRender: false,
+ autoScroll: true,
+ stateful: true,
+ view: new Ext.ux.grid.BufferView({
+ rowHeight: 26,
+ scrollDelay: false,
+ }),
+ },
+ config
+ );
+ Deluge.TorrentGrid.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.TorrentGrid.superclass.initComponent.call(this);
+ deluge.events.on('torrentsRemoved', this.onTorrentsRemoved, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+
+ this.on('rowcontextmenu', function(grid, rowIndex, e) {
+ e.stopEvent();
+ var selection = grid.getSelectionModel();
+ if (!selection.isSelected(rowIndex)) {
+ selection.selectRow(rowIndex);
+ }
+ deluge.menus.torrent.showAt(e.getPoint());
+ });
+ },
+
+ /**
+ * Returns the record representing the torrent at the specified index.
+ *
+ * @param index {int} The row index of the torrent you wish to retrieve.
+ * @return {Ext.data.Record} The record representing the torrent.
+ */
+ getTorrent: function(index) {
+ return this.getStore().getAt(index);
+ },
+
+ /**
+ * Returns the currently selected record.
+ * @ return {Array/Ext.data.Record} The record(s) representing the rows
+ */
+ getSelected: function() {
+ return this.getSelectionModel().getSelected();
+ },
+
+ /**
+ * Returns the currently selected records.
+ */
+ getSelections: function() {
+ return this.getSelectionModel().getSelections();
+ },
+
+ /**
+ * Return the currently selected torrent id.
+ * @return {String} The currently selected id.
+ */
+ getSelectedId: function() {
+ return this.getSelectionModel().getSelected().id;
+ },
+
+ /**
+ * Return the currently selected torrent ids.
+ * @return {Array} The currently selected ids.
+ */
+ getSelectedIds: function() {
+ var ids = [];
+ Ext.each(this.getSelectionModel().getSelections(), function(r) {
+ ids.push(r.id);
+ });
+ return ids;
+ },
+
+ update: function(torrents, wipe) {
+ var store = this.getStore();
+
+ // Need to perform a complete reload of the torrent grid.
+ if (wipe) {
+ store.removeAll();
+ this.torrents = {};
+ }
+
+ var newTorrents = [];
+
+ // Update and add any new torrents.
+ for (var t in torrents) {
+ var torrent = torrents[t];
+
+ if (this.torrents[t]) {
+ var record = store.getById(t);
+ record.beginEdit();
+ for (var k in torrent) {
+ if (record.get(k) != torrent[k]) {
+ record.set(k, torrent[k]);
+ }
+ }
+ record.endEdit();
+ } else {
+ var record = new Deluge.data.Torrent(torrent);
+ record.id = t;
+ this.torrents[t] = 1;
+ newTorrents.push(record);
+ }
+ }
+ store.add(newTorrents);
+
+ // Remove any torrents that should not be in the store.
+ store.each(function(record) {
+ if (!torrents[record.id]) {
+ store.remove(record);
+ delete this.torrents[record.id];
+ }
+ }, this);
+ store.commitChanges();
+
+ var sortState = store.getSortState();
+ if (!sortState) return;
+ store.sort(sortState.field, sortState.direction);
+ },
+
+ // private
+ onDisconnect: function() {
+ this.getStore().removeAll();
+ this.torrents = {};
+ },
+
+ // private
+ onTorrentsRemoved: function(torrentIds) {
+ var selModel = this.getSelectionModel();
+ Ext.each(
+ torrentIds,
+ function(torrentId) {
+ var record = this.getStore().getById(torrentId);
+ if (selModel.isSelected(record)) {
+ selModel.deselectRow(this.getStore().indexOf(record));
+ }
+ this.getStore().remove(record);
+ delete this.torrents[torrentId];
+ },
+ this
+ );
+ },
+ });
+ deluge.torrents = new Deluge.TorrentGrid();
+})();
+/**
+ * Deluge.UI.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/** Dummy translation arrays so Torrent states are available for gettext.js and Translators.
+ *
+ * All entries in deluge.common.TORRENT_STATE should be added here.
+ *
+ * No need to import these, just simply use the `_()` function around a status variable.
+ */
+var TORRENT_STATE_TRANSLATION = [
+ _('All'),
+ _('Active'),
+ _('Allocating'),
+ _('Checking'),
+ _('Downloading'),
+ _('Seeding'),
+ _('Paused'),
+ _('Checking'),
+ _('Queued'),
+ _('Error'),
+];
+
+/**
+ * @static
+ * @class Deluge.UI
+ * The controller for the whole interface, that ties all the components
+ * together and handles the 2 second poll.
+ */
+deluge.ui = {
+ errorCount: 0,
+
+ filters: null,
+
+ /**
+ * @description Create all the interface components, the json-rpc client
+ * and set up various events that the UI will utilise.
+ */
+ initialize: function() {
+ deluge.add = new Deluge.add.AddWindow();
+ deluge.details = new Deluge.details.DetailsPanel();
+ deluge.connectionManager = new Deluge.ConnectionManager();
+ deluge.editTrackers = new Deluge.EditTrackersWindow();
+ deluge.login = new Deluge.LoginWindow();
+ deluge.preferences = new Deluge.preferences.PreferencesWindow();
+ deluge.sidebar = new Deluge.Sidebar();
+ deluge.statusbar = new Deluge.Statusbar();
+ deluge.toolbar = new Deluge.Toolbar();
+
+ this.detailsPanel = new Ext.Panel({
+ id: 'detailsPanel',
+ cls: 'detailsPanel',
+ region: 'south',
+ split: true,
+ height: 215,
+ minSize: 100,
+ collapsible: true,
+ layout: 'fit',
+ items: [deluge.details],
+ });
+
+ this.MainPanel = new Ext.Panel({
+ id: 'mainPanel',
+ iconCls: 'x-deluge-main-panel',
+ layout: 'border',
+ border: false,
+ tbar: deluge.toolbar,
+ items: [deluge.sidebar, this.detailsPanel, deluge.torrents],
+ bbar: deluge.statusbar,
+ });
+
+ this.Viewport = new Ext.Viewport({
+ layout: 'fit',
+ items: [this.MainPanel],
+ });
+
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
+ deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
+ deluge.client = new Ext.ux.util.RpcClient({
+ url: deluge.config.base + 'json',
+ });
+
+ // enable all the already active plugins
+ for (var plugin in Deluge.pluginStore) {
+ plugin = Deluge.createPlugin(plugin);
+ plugin.enable();
+ deluge.plugins[plugin.name] = plugin;
+ }
+
+ // Initialize quicktips so all the tooltip configs start working.
+ Ext.QuickTips.init();
+
+ deluge.client.on(
+ 'connected',
+ function(e) {
+ deluge.login.show();
+ },
+ this,
+ { single: true }
+ );
+
+ this.update = this.update.createDelegate(this);
+ this.checkConnection = this.checkConnection.createDelegate(this);
+
+ this.originalTitle = document.title;
+ },
+
+ checkConnection: function() {
+ deluge.client.web.connected({
+ success: this.onConnectionSuccess,
+ failure: this.onConnectionError,
+ scope: this,
+ });
+ },
+
+ update: function() {
+ var filters = deluge.sidebar.getFilterStates();
+ this.oldFilters = this.filters;
+ this.filters = filters;
+
+ deluge.client.web.update_ui(Deluge.Keys.Grid, filters, {
+ success: this.onUpdate,
+ failure: this.onUpdateError,
+ scope: this,
+ });
+ deluge.details.update();
+ },
+
+ onConnectionError: function(error) {},
+
+ onConnectionSuccess: function(result) {
+ deluge.statusbar.setStatus({
+ iconCls: 'x-deluge-statusbar icon-ok',
+ text: _('Connection restored'),
+ });
+ clearInterval(this.checking);
+ if (!result) {
+ deluge.connectionManager.show();
+ }
+ },
+
+ onUpdateError: function(error) {
+ if (this.errorCount == 2) {
+ Ext.MessageBox.show({
+ title: _('Lost Connection'),
+ msg: _('The connection to the webserver has been lost!'),
+ buttons: Ext.MessageBox.OK,
+ icon: Ext.MessageBox.ERROR,
+ });
+ deluge.events.fire('disconnect');
+ deluge.statusbar.setStatus({
+ text: _('Lost connection to webserver'),
+ });
+ this.checking = setInterval(this.checkConnection, 2000);
+ }
+ this.errorCount++;
+ },
+
+ /**
+ * @static
+ * @private
+ * Updates the various components in the interface.
+ */
+ onUpdate: function(data) {
+ if (!data['connected']) {
+ deluge.connectionManager.disconnect(true);
+ return;
+ }
+
+ if (deluge.config.show_session_speed) {
+ document.title =
+ 'D: ' +
+ fsize_short(data['stats'].download_rate, true) +
+ ' U: ' +
+ fsize_short(data['stats'].upload_rate, true) +
+ ' - ' +
+ this.originalTitle;
+ }
+ if (Ext.areObjectsEqual(this.filters, this.oldFilters)) {
+ deluge.torrents.update(data['torrents']);
+ } else {
+ deluge.torrents.update(data['torrents'], true);
+ }
+ deluge.statusbar.update(data['stats']);
+ deluge.sidebar.update(data['filters']);
+ this.errorCount = 0;
+ },
+
+ /**
+ * @static
+ * @private
+ * Start the Deluge UI polling the server and update the interface.
+ */
+ onConnect: function() {
+ if (!this.running) {
+ this.running = setInterval(this.update, 2000);
+ this.update();
+ }
+ deluge.client.web.get_plugins({
+ success: this.onGotPlugins,
+ scope: this,
+ });
+ },
+
+ /**
+ * @static
+ * @private
+ */
+ onDisconnect: function() {
+ this.stop();
+ },
+
+ onGotPlugins: function(plugins) {
+ Ext.each(
+ plugins.enabled_plugins,
+ function(plugin) {
+ if (deluge.plugins[plugin]) return;
+ deluge.client.web.get_plugin_resources(plugin, {
+ success: this.onGotPluginResources,
+ scope: this,
+ });
+ },
+ this
+ );
+ },
+
+ onPluginEnabled: function(pluginName) {
+ if (deluge.plugins[pluginName]) {
+ deluge.plugins[pluginName].enable();
+ } else {
+ deluge.client.web.get_plugin_resources(pluginName, {
+ success: this.onGotPluginResources,
+ scope: this,
+ });
+ }
+ },
+
+ onGotPluginResources: function(resources) {
+ var scripts = Deluge.debug
+ ? resources.debug_scripts
+ : resources.scripts;
+ Ext.each(
+ scripts,
+ function(script) {
+ Ext.ux.JSLoader({
+ url: deluge.config.base + script,
+ onLoad: this.onPluginLoaded,
+ pluginName: resources.name,
+ });
+ },
+ this
+ );
+ },
+
+ onPluginDisabled: function(pluginName) {
+ if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable();
+ },
+
+ onPluginLoaded: function(options) {
+ // This could happen if the plugin has multiple scripts
+ if (!Deluge.hasPlugin(options.pluginName)) return;
+
+ // Enable the plugin
+ plugin = Deluge.createPlugin(options.pluginName);
+ plugin.enable();
+ deluge.plugins[plugin.name] = plugin;
+ },
+
+ /**
+ * @static
+ * Stop the Deluge UI polling the server and clear the interface.
+ */
+ stop: function() {
+ if (this.running) {
+ clearInterval(this.running);
+ this.running = false;
+ deluge.torrents.getStore().removeAll();
+ }
+ },
+};
+
+Ext.onReady(function(e) {
+ deluge.ui.initialize();
+});
diff --git a/deluge/ui/web/js/deluge-all/.order b/deluge/ui/web/js/deluge-all/.order
new file mode 100644
index 0000000..4b6be43
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/.order
@@ -0,0 +1,2 @@
++ OptionsManager.js
++ StatusbarMenu.js
diff --git a/deluge/ui/web/js/deluge-all/AboutWindow.js b/deluge/ui/web/js/deluge-all/AboutWindow.js
new file mode 100644
index 0000000..5376d05
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/AboutWindow.js
@@ -0,0 +1,129 @@
+/**
+ * Deluge.AboutWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.about');
+
+/**
+ * @class Deluge.about.AboutWindow
+ * @extends Ext.Window
+ */
+Deluge.about.AboutWindow = Ext.extend(Ext.Window, {
+ id: 'AboutWindow',
+ title: _('About Deluge'),
+ height: 330,
+ width: 270,
+ iconCls: 'x-deluge-main-panel',
+ resizable: false,
+ plain: true,
+ layout: {
+ type: 'vbox',
+ align: 'center',
+ },
+ buttonAlign: 'center',
+
+ initComponent: function() {
+ Deluge.about.AboutWindow.superclass.initComponent.call(this);
+ this.addEvents({
+ build_ready: true,
+ });
+
+ var self = this;
+ var libtorrent = function() {
+ deluge.client.core.get_libtorrent_version({
+ success: function(lt_version) {
+ comment += '<br/>' + _('libtorrent:') + ' ' + lt_version;
+ Ext.getCmp('about_comment').setText(comment, false);
+ self.fireEvent('build_ready');
+ },
+ });
+ };
+
+ var client_version = deluge.version;
+
+ var comment =
+ _(
+ 'A peer-to-peer file sharing program\nutilizing the BitTorrent protocol.'
+ ).replace('\n', '<br/>') +
+ '<br/><br/>' +
+ _('Client:') +
+ ' ' +
+ client_version +
+ '<br/>';
+ deluge.client.web.connected({
+ success: function(connected) {
+ if (connected) {
+ deluge.client.daemon.get_version({
+ success: function(server_version) {
+ comment +=
+ _('Server:') + ' ' + server_version + '<br/>';
+ libtorrent();
+ },
+ });
+ } else {
+ this.fireEvent('build_ready');
+ }
+ },
+ failure: function() {
+ this.fireEvent('build_ready');
+ },
+ scope: this,
+ });
+
+ this.add([
+ {
+ xtype: 'box',
+ style: 'padding-top: 5px',
+ height: 80,
+ width: 240,
+ cls: 'x-deluge-logo',
+ hideLabel: true,
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 10px; font-weight: bold; font-size: 16px;',
+ text: _('Deluge') + ' ' + client_version,
+ },
+ {
+ xtype: 'label',
+ id: 'about_comment',
+ style: 'padding-top: 10px; text-align:center; font-size: 12px;',
+ html: comment,
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 10px; font-size: 10px;',
+ text: _('Copyright 2007-2018 Deluge Team'),
+ },
+ {
+ xtype: 'label',
+ style: 'padding-top: 5px; font-size: 12px;',
+ html:
+ '<a href="https://deluge-torrent.org" target="_blank">deluge-torrent.org</a>',
+ },
+ ]);
+ this.addButton(_('Close'), this.onCloseClick, this);
+ },
+
+ show: function() {
+ this.on('build_ready', function() {
+ Deluge.about.AboutWindow.superclass.show.call(this);
+ });
+ },
+
+ onCloseClick: function() {
+ this.close();
+ },
+});
+
+Ext.namespace('Deluge');
+
+Deluge.About = function() {
+ new Deluge.about.AboutWindow().show();
+};
diff --git a/deluge/ui/web/js/deluge-all/AddConnectionWindow.js b/deluge/ui/web/js/deluge-all/AddConnectionWindow.js
new file mode 100644
index 0000000..6d26370
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/AddConnectionWindow.js
@@ -0,0 +1,117 @@
+/**
+ * Deluge.AddConnectionWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.AddConnectionWindow
+ * @extends Ext.Window
+ */
+Deluge.AddConnectionWindow = Ext.extend(Ext.Window, {
+ title: _('Add Connection'),
+ iconCls: 'x-deluge-add-window-icon',
+
+ layout: 'fit',
+ width: 300,
+ height: 195,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.AddConnectionWindow.superclass.initComponent.call(this);
+
+ this.addEvents('hostadded');
+
+ this.addButton(_('Close'), this.hide, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 60,
+ items: [
+ {
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ name: 'host',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ xtype: 'spinnerfield',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ name: 'port',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 65535,
+ },
+ value: '58846',
+ anchor: '40%',
+ },
+ {
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ name: 'username',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ anchor: '75%',
+ name: 'password',
+ inputType: 'password',
+ value: '',
+ },
+ ],
+ });
+ },
+
+ onAddClick: function() {
+ var values = this.form.getForm().getValues();
+ deluge.client.web.add_host(
+ values.host,
+ Number(values.port),
+ values.username,
+ values.password,
+ {
+ success: function(result) {
+ if (!result[0]) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: String.format(
+ _('Unable to add host: {0}'),
+ result[1]
+ ),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.fireEvent('hostadded');
+ }
+ this.hide();
+ },
+ scope: this,
+ }
+ );
+ },
+
+ onHide: function() {
+ this.form.getForm().reset();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/AddTrackerWindow.js b/deluge/ui/web/js/deluge-all/AddTrackerWindow.js
new file mode 100644
index 0000000..c9c835d
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/AddTrackerWindow.js
@@ -0,0 +1,94 @@
+/**
+ * Deluge.AddTrackerWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+// Custom VType validator for tracker urls
+var trackerUrlTest = /(((^https?)|(^udp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+Ext.apply(Ext.form.VTypes, {
+ trackerUrl: function(val, field) {
+ return trackerUrlTest.test(val);
+ },
+ trackerUrlText: 'Not a valid tracker url',
+});
+
+/**
+ * @class Deluge.AddTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.AddTrackerWindow = Ext.extend(Ext.Window, {
+ title: _('Add Tracker'),
+ layout: 'fit',
+ width: 375,
+ height: 150,
+ plain: true,
+ closable: true,
+ resizable: false,
+ constrainHeader: true,
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.AddTrackerWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+ this.addEvents('add');
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textarea',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ items: [
+ {
+ fieldLabel: _('Trackers:'),
+ labelSeparator: '',
+ name: 'trackers',
+ anchor: '100%',
+ },
+ ],
+ });
+ },
+
+ onAddClick: function() {
+ var trackers = this.form
+ .getForm()
+ .findField('trackers')
+ .getValue();
+ trackers = trackers.split('\n');
+
+ var cleaned = [];
+ Ext.each(
+ trackers,
+ function(tracker) {
+ if (Ext.form.VTypes.trackerUrl(tracker)) {
+ cleaned.push(tracker);
+ }
+ },
+ this
+ );
+ this.fireEvent('add', cleaned);
+ this.hide();
+ this.form
+ .getForm()
+ .findField('trackers')
+ .setValue('');
+ },
+
+ onCancelClick: function() {
+ this.form
+ .getForm()
+ .findField('trackers')
+ .setValue('');
+ this.hide();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Client.js b/deluge/ui/web/js/deluge-all/Client.js
new file mode 100644
index 0000000..bcabbae
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Client.js
@@ -0,0 +1,199 @@
+/**
+ * Deluge.Client.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.ux.util');
+
+/**
+ * A class that connects to a json-rpc resource and adds the available
+ * methods as functions to the class instance.
+ * @class Ext.ux.util.RpcClient
+ * @namespace Ext.ux.util
+ */
+Ext.ux.util.RpcClient = Ext.extend(Ext.util.Observable, {
+ _components: [],
+
+ _methods: [],
+
+ _requests: {},
+
+ _url: null,
+
+ _optionKeys: ['scope', 'success', 'failure'],
+
+ /**
+ * @event connected
+ * Fires when the client has retrieved the list of methods from the server.
+ * @param {Ext.ux.util.RpcClient} this
+ */
+ constructor: function(config) {
+ Ext.ux.util.RpcClient.superclass.constructor.call(this, config);
+ this._url = config.url || null;
+ this._id = 0;
+
+ this.addEvents(
+ // raw events
+ 'connected',
+ 'error'
+ );
+ this.reloadMethods();
+ },
+
+ reloadMethods: function() {
+ this._execute('system.listMethods', {
+ success: this._setMethods,
+ scope: this,
+ });
+ },
+
+ _execute: function(method, options) {
+ options = options || {};
+ options.params = options.params || [];
+ options.id = this._id;
+
+ var request = Ext.encode({
+ method: method,
+ params: options.params,
+ id: options.id,
+ });
+ this._id++;
+
+ return Ext.Ajax.request({
+ url: this._url,
+ method: 'POST',
+ success: this._onSuccess,
+ failure: this._onFailure,
+ scope: this,
+ jsonData: request,
+ options: options,
+ });
+ },
+
+ _onFailure: function(response, requestOptions) {
+ var options = requestOptions.options;
+ errorObj = {
+ id: options.id,
+ result: null,
+ error: {
+ msg: 'HTTP: ' + response.status + ' ' + response.statusText,
+ code: 255,
+ },
+ };
+
+ this.fireEvent('error', errorObj, response, requestOptions);
+
+ if (Ext.type(options.failure) != 'function') return;
+ if (options.scope) {
+ options.failure.call(
+ options.scope,
+ errorObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.failure(errorObj, response, requestOptions);
+ }
+ },
+
+ _onSuccess: function(response, requestOptions) {
+ var responseObj = Ext.decode(response.responseText);
+ var options = requestOptions.options;
+ if (responseObj.error) {
+ this.fireEvent('error', responseObj, response, requestOptions);
+
+ if (Ext.type(options.failure) != 'function') return;
+ if (options.scope) {
+ options.failure.call(
+ options.scope,
+ responseObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.failure(responseObj, response, requestOptions);
+ }
+ } else {
+ if (Ext.type(options.success) != 'function') return;
+ if (options.scope) {
+ options.success.call(
+ options.scope,
+ responseObj.result,
+ responseObj,
+ response,
+ requestOptions
+ );
+ } else {
+ options.success(
+ responseObj.result,
+ responseObj,
+ response,
+ requestOptions
+ );
+ }
+ }
+ },
+
+ _parseArgs: function(args) {
+ var params = [];
+ Ext.each(args, function(arg) {
+ params.push(arg);
+ });
+
+ var options = params[params.length - 1];
+ if (Ext.type(options) == 'object') {
+ var keys = Ext.keys(options),
+ isOption = false;
+
+ Ext.each(this._optionKeys, function(key) {
+ if (keys.indexOf(key) > -1) isOption = true;
+ });
+
+ if (isOption) {
+ params.remove(options);
+ } else {
+ options = {};
+ }
+ } else {
+ options = {};
+ }
+ options.params = params;
+ return options;
+ },
+
+ _setMethods: function(methods) {
+ var components = {},
+ self = this;
+
+ Ext.each(methods, function(method) {
+ var parts = method.split('.');
+ var component = components[parts[0]] || {};
+
+ var fn = function() {
+ var options = self._parseArgs(arguments);
+ return self._execute(method, options);
+ };
+ component[parts[1]] = fn;
+ components[parts[0]] = component;
+ });
+
+ for (var name in components) {
+ self[name] = components[name];
+ }
+ Ext.each(
+ this._components,
+ function(component) {
+ if (!component in components) {
+ delete this[component];
+ }
+ },
+ this
+ );
+ this._components = Ext.keys(components);
+ this.fireEvent('connected', this);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/ConnectionManager.js b/deluge/ui/web/js/deluge-all/ConnectionManager.js
new file mode 100644
index 0000000..001e46b
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/ConnectionManager.js
@@ -0,0 +1,429 @@
+/**
+ * Deluge.ConnectionManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.ConnectionManager = Ext.extend(Ext.Window, {
+ layout: 'fit',
+ width: 300,
+ height: 220,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ plain: true,
+ constrainHeader: true,
+ title: _('Connection Manager'),
+ iconCls: 'x-deluge-connect-window-icon',
+
+ initComponent: function() {
+ Deluge.ConnectionManager.superclass.initComponent.call(this);
+ this.on('hide', this.onHide, this);
+ this.on('show', this.onShow, this);
+
+ deluge.events.on('login', this.onLogin, this);
+ deluge.events.on('logout', this.onLogout, this);
+
+ this.addButton(_('Close'), this.onClose, this);
+ this.addButton(_('Connect'), this.onConnect, this);
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.ArrayStore({
+ fields: [
+ { name: 'status', mapping: 4 },
+ { name: 'host', mapping: 1 },
+ { name: 'port', mapping: 2 },
+ { name: 'user', mapping: 3 },
+ { name: 'version', mapping: 5 },
+ ],
+ id: 0,
+ }),
+ columns: [
+ {
+ header: _('Status'),
+ width: 0.24,
+ sortable: true,
+ tpl: new Ext.XTemplate(
+ '<tpl if="status == \'Online\'">',
+ _('Online'),
+ '</tpl>',
+ '<tpl if="status == \'Offline\'">',
+ _('Offline'),
+ '</tpl>',
+ '<tpl if="status == \'Connected\'">',
+ _('Connected'),
+ '</tpl>'
+ ),
+ dataIndex: 'status',
+ },
+ {
+ id: 'host',
+ header: _('Host'),
+ width: 0.51,
+ sortable: true,
+ tpl: '{user}@{host}:{port}',
+ dataIndex: 'host',
+ },
+ {
+ header: _('Version'),
+ width: 0.25,
+ sortable: true,
+ tpl: '<tpl if="version">{version}</tpl>',
+ dataIndex: 'version',
+ },
+ ],
+ singleSelect: true,
+ listeners: {
+ selectionchange: { fn: this.onSelectionChanged, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ autoScroll: true,
+ items: [this.list],
+ bbar: new Ext.Toolbar({
+ buttons: [
+ {
+ id: 'cm-add',
+ cls: 'x-btn-text-icon',
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onAddClick,
+ scope: this,
+ },
+ {
+ id: 'cm-edit',
+ cls: 'x-btn-text-icon',
+ text: _('Edit'),
+ iconCls: 'icon-edit',
+ handler: this.onEditClick,
+ scope: this,
+ },
+ {
+ id: 'cm-remove',
+ cls: 'x-btn-text-icon',
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemoveClick,
+ disabled: true,
+ scope: this,
+ },
+ '->',
+ {
+ id: 'cm-stop',
+ cls: 'x-btn-text-icon',
+ text: _('Stop Daemon'),
+ iconCls: 'icon-error',
+ handler: this.onStopClick,
+ disabled: true,
+ scope: this,
+ },
+ ],
+ }),
+ });
+ this.update = this.update.createDelegate(this);
+ },
+
+ /**
+ * Check to see if the the web interface is currently connected
+ * to a Deluge Daemon and show the Connection Manager if not.
+ */
+ checkConnected: function() {
+ deluge.client.web.connected({
+ success: function(connected) {
+ if (connected) {
+ deluge.events.fire('connect');
+ } else {
+ this.show();
+ }
+ },
+ scope: this,
+ });
+ },
+
+ disconnect: function(show) {
+ deluge.events.fire('disconnect');
+ if (show) {
+ if (this.isVisible()) return;
+ this.show();
+ }
+ },
+
+ loadHosts: function() {
+ deluge.client.web.get_hosts({
+ success: this.onGetHosts,
+ scope: this,
+ });
+ },
+
+ update: function() {
+ this.list.getStore().each(function(r) {
+ deluge.client.web.get_host_status(r.id, {
+ success: this.onGetHostStatus,
+ scope: this,
+ });
+ }, this);
+ },
+
+ /**
+ * Updates the buttons in the Connection Manager UI according to the
+ * passed in records host state.
+ * @param {Ext.data.Record} record The hosts record to update the UI for
+ */
+ updateButtons: function(record) {
+ var button = this.buttons[1],
+ status = record.get('status');
+
+ // Update the Connect/Disconnect button
+ button.enable();
+ if (status.toLowerCase() == 'connected') {
+ button.setText(_('Disconnect'));
+ } else {
+ button.setText(_('Connect'));
+ if (status.toLowerCase() != 'online') button.disable();
+ }
+
+ // Update the Stop/Start Daemon button
+ if (
+ status.toLowerCase() == 'connected' ||
+ status.toLowerCase() == 'online'
+ ) {
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Stop Daemon'));
+ } else {
+ if (
+ record.get('host') == '127.0.0.1' ||
+ record.get('host') == 'localhost'
+ ) {
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Start Daemon'));
+ } else {
+ this.stopHostButton.disable();
+ }
+ }
+ },
+
+ // private
+ onAddClick: function(button, e) {
+ if (!this.addWindow) {
+ this.addWindow = new Deluge.AddConnectionWindow();
+ this.addWindow.on('hostadded', this.onHostChange, this);
+ }
+ this.addWindow.show();
+ },
+
+ // private
+ onEditClick: function(button, e) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ if (!this.editWindow) {
+ this.editWindow = new Deluge.EditConnectionWindow();
+ this.editWindow.on('hostedited', this.onHostChange, this);
+ }
+ this.editWindow.show(connection);
+ },
+
+ // private
+ onHostChange: function() {
+ this.loadHosts();
+ },
+
+ // private
+ onClose: function(e) {
+ this.hide();
+ },
+
+ // private
+ onConnect: function(e) {
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+
+ var me = this;
+ var disconnect = function() {
+ deluge.client.web.disconnect({
+ success: function(result) {
+ this.update(this);
+ deluge.events.fire('disconnect');
+ },
+ scope: me,
+ });
+ };
+
+ if (selected.get('status').toLowerCase() == 'connected') {
+ disconnect();
+ } else {
+ if (
+ this.list
+ .getStore()
+ .find('status', 'Connected', 0, false, false) > -1
+ ) {
+ disconnect();
+ }
+
+ var id = selected.id;
+ deluge.client.web.connect(id, {
+ success: function(methods) {
+ deluge.client.reloadMethods();
+ deluge.client.on(
+ 'connected',
+ function(e) {
+ deluge.events.fire('connect');
+ },
+ this,
+ { single: true }
+ );
+ },
+ });
+ this.hide();
+ }
+ },
+
+ // private
+ onGetHosts: function(hosts) {
+ this.list.getStore().loadData(hosts);
+ Ext.each(
+ hosts,
+ function(host) {
+ deluge.client.web.get_host_status(host[0], {
+ success: this.onGetHostStatus,
+ scope: this,
+ });
+ },
+ this
+ );
+ },
+
+ // private
+ onGetHostStatus: function(host) {
+ var record = this.list.getStore().getById(host[0]);
+ record.set('status', host[1]);
+ record.set('version', host[2]);
+ record.commit();
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ if (selected == record) this.updateButtons(record);
+ },
+
+ // private
+ onHide: function() {
+ if (this.running) window.clearInterval(this.running);
+ },
+
+ // private
+ onLogin: function() {
+ if (deluge.config.first_login) {
+ Ext.MessageBox.confirm(
+ _('Change Default Password'),
+ _(
+ 'We recommend changing the default password.<br><br>Would you like to change it now?'
+ ),
+ function(res) {
+ this.checkConnected();
+ if (res == 'yes') {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Interface');
+ }
+ deluge.client.web.set_config({ first_login: false });
+ },
+ this
+ );
+ } else {
+ this.checkConnected();
+ }
+ },
+
+ // private
+ onLogout: function() {
+ this.disconnect();
+ if (!this.hidden && this.rendered) {
+ this.hide();
+ }
+ },
+
+ // private
+ onRemoveClick: function(button) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ deluge.client.web.remove_host(connection.id, {
+ success: function(result) {
+ if (!result) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: result[1],
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.list.getStore().remove(connection);
+ }
+ },
+ scope: this,
+ });
+ },
+
+ // private
+ onSelectionChanged: function(list, selections) {
+ if (selections[0]) {
+ this.editHostButton.enable();
+ this.removeHostButton.enable();
+ this.stopHostButton.enable();
+ this.stopHostButton.setText(_('Stop Daemon'));
+ this.updateButtons(this.list.getRecord(selections[0]));
+ } else {
+ this.editHostButton.disable();
+ this.removeHostButton.disable();
+ this.stopHostButton.disable();
+ }
+ },
+
+ // FIXME: Find out why this is being fired twice
+ // private
+ onShow: function() {
+ if (!this.addHostButton) {
+ var bbar = this.panel.getBottomToolbar();
+ this.addHostButton = bbar.items.get('cm-add');
+ this.editHostButton = bbar.items.get('cm-edit');
+ this.removeHostButton = bbar.items.get('cm-remove');
+ this.stopHostButton = bbar.items.get('cm-stop');
+ }
+ this.loadHosts();
+ if (this.running) return;
+ this.running = window.setInterval(this.update, 2000, this);
+ },
+
+ // private
+ onStopClick: function(button, e) {
+ var connection = this.list.getSelectedRecords()[0];
+ if (!connection) return;
+
+ if (connection.get('status') == 'Offline') {
+ // This means we need to start the daemon
+ deluge.client.web.start_daemon(connection.get('port'));
+ } else {
+ // This means we need to stop the daemon
+ deluge.client.web.stop_daemon(connection.id, {
+ success: function(result) {
+ if (!result[0]) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: result[1],
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ }
+ },
+ });
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Deluge.js b/deluge/ui/web/js/deluge-all/Deluge.js
new file mode 100644
index 0000000..31b9947
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Deluge.js
@@ -0,0 +1,186 @@
+/**
+ * Deluge.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Setup the state manager
+Ext.state.Manager.setProvider(
+ new Ext.state.CookieProvider({
+ /**
+ * By default, cookies will expire after 7 days. Provide
+ * an expiry date 10 years in the future to approximate
+ * a cookie that does not expire.
+ */
+ expires: new Date(
+ new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 10
+ ),
+ })
+);
+
+// Add some additional functions to ext and setup some of the
+// configurable parameters
+Ext.apply(Ext, {
+ escapeHTML: function(text) {
+ text = String(text)
+ .replace('<', '&lt;')
+ .replace('>', '&gt;');
+ return text.replace('&', '&amp;');
+ },
+
+ isObjectEmpty: function(obj) {
+ for (var i in obj) {
+ return false;
+ }
+ return true;
+ },
+
+ areObjectsEqual: function(obj1, obj2) {
+ var equal = true;
+ if (!obj1 || !obj2) return false;
+ for (var i in obj1) {
+ if (obj1[i] != obj2[i]) {
+ equal = false;
+ }
+ }
+ return equal;
+ },
+
+ keys: function(obj) {
+ var keys = [];
+ for (var i in obj)
+ if (obj.hasOwnProperty(i)) {
+ keys.push(i);
+ }
+ return keys;
+ },
+
+ values: function(obj) {
+ var values = [];
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ values.push(obj[i]);
+ }
+ }
+ return values;
+ },
+
+ splat: function(obj) {
+ var type = Ext.type(obj);
+ return type ? (type != 'array' ? [obj] : obj) : [];
+ },
+});
+Ext.getKeys = Ext.keys;
+Ext.BLANK_IMAGE_URL = deluge.config.base + 'images/s.gif';
+Ext.USE_NATIVE_JSON = true;
+
+// Create the Deluge namespace
+Ext.apply(Deluge, {
+ // private
+ pluginStore: {},
+
+ // private
+ progressTpl:
+ '<div class="x-progress-wrap x-progress-renderered">' +
+ '<div class="x-progress-inner">' +
+ '<div style="width: {2}px" class="x-progress-bar">' +
+ '<div style="z-index: 99; width: {3}px" class="x-progress-text">' +
+ '<div style="width: {1}px;">{0}</div>' +
+ '</div>' +
+ '</div>' +
+ '<div class="x-progress-text x-progress-text-back">' +
+ '<div style="width: {1}px;">{0}</div>' +
+ '</div>' +
+ '</div>' +
+ '</div>',
+
+ /**
+ * A method to create a progress bar that can be used by renderers
+ * to display a bar within a grid or tree.
+ * @param {Number} progress The bars progress
+ * @param {Number} width The width of the bar
+ * @param {String} text The text to display on the bar
+ * @param {Number} modified Amount to subtract from the width allowing for fixes
+ */
+ progressBar: function(progress, width, text, modifier) {
+ modifier = Ext.value(modifier, 10);
+ var progressWidth = ((width / 100.0) * progress).toFixed(0);
+ var barWidth = progressWidth - 1;
+ var textWidth =
+ progressWidth - modifier > 0 ? progressWidth - modifier : 0;
+ return String.format(
+ Deluge.progressTpl,
+ text,
+ width,
+ barWidth,
+ textWidth
+ );
+ },
+
+ /**
+ * Constructs a new instance of the specified plugin.
+ * @param {String} name The plugin name to create
+ */
+ createPlugin: function(name) {
+ return new Deluge.pluginStore[name]();
+ },
+
+ /**
+ * Check to see if a plugin has been registered.
+ * @param {String} name The plugin name to check
+ */
+ hasPlugin: function(name) {
+ return Deluge.pluginStore[name] ? true : false;
+ },
+
+ /**
+ * Register a plugin with the Deluge interface.
+ * @param {String} name The plugin name to register
+ * @param {Plugin} plugin The plugin to register
+ */
+ registerPlugin: function(name, plugin) {
+ Deluge.pluginStore[name] = plugin;
+ },
+});
+
+// Setup a space for plugins to insert themselves
+deluge.plugins = {};
+
+// Hinting for gettext_gen.py
+// _('Skip')
+// _('Low')
+// _('Normal')
+// _('High')
+// _('Mixed')
+FILE_PRIORITY = {
+ 0: 'Skip',
+ 1: 'Low',
+ 2: 'Low',
+ 3: 'Low',
+ 4: 'Normal',
+ 5: 'High',
+ 6: 'High',
+ 7: 'High',
+ 9: 'Mixed',
+ Skip: 0,
+ Low: 1,
+ Normal: 4,
+ High: 7,
+ Mixed: 9,
+};
+
+FILE_PRIORITY_CSS = {
+ 0: 'x-no-download',
+ 1: 'x-low-download',
+ 2: 'x-low-download',
+ 3: 'x-low-download',
+ 4: 'x-normal-download',
+ 5: 'x-high-download',
+ 6: 'x-high-download',
+ 7: 'x-high-download',
+ 9: 'x-mixed-download',
+};
diff --git a/deluge/ui/web/js/deluge-all/EditConnectionWindow.js b/deluge/ui/web/js/deluge-all/EditConnectionWindow.js
new file mode 100644
index 0000000..63bd305
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/EditConnectionWindow.js
@@ -0,0 +1,134 @@
+/**
+ * Deluge.EditConnectionWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditConnectionWindow
+ * @extends Ext.Window
+ */
+Deluge.EditConnectionWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Connection'),
+ iconCls: 'x-deluge-add-window-icon',
+
+ layout: 'fit',
+ width: 300,
+ height: 195,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.EditConnectionWindow.superclass.initComponent.call(this);
+
+ this.addEvents('hostedited');
+
+ this.addButton(_('Close'), this.hide, this);
+ this.addButton(_('Edit'), this.onEditClick, this);
+
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 60,
+ items: [
+ {
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ name: 'host',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ xtype: 'spinnerfield',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ name: 'port',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ anchor: '40%',
+ value: 58846,
+ },
+ {
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ name: 'username',
+ anchor: '75%',
+ value: '',
+ },
+ {
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ anchor: '75%',
+ name: 'password',
+ inputType: 'password',
+ value: '',
+ },
+ ],
+ });
+ },
+
+ show: function(connection) {
+ Deluge.EditConnectionWindow.superclass.show.call(this);
+
+ this.form
+ .getForm()
+ .findField('host')
+ .setValue(connection.get('host'));
+ this.form
+ .getForm()
+ .findField('port')
+ .setValue(connection.get('port'));
+ this.form
+ .getForm()
+ .findField('username')
+ .setValue(connection.get('user'));
+ this.host_id = connection.id;
+ },
+
+ onEditClick: function() {
+ var values = this.form.getForm().getValues();
+ deluge.client.web.edit_host(
+ this.host_id,
+ values.host,
+ Number(values.port),
+ values.username,
+ values.password,
+ {
+ success: function(result) {
+ if (!result) {
+ console.log(result);
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: String.format(_('Unable to edit host')),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ } else {
+ this.fireEvent('hostedited');
+ }
+ this.hide();
+ },
+ scope: this,
+ }
+ );
+ },
+
+ onHide: function() {
+ this.form.getForm().reset();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/EditTrackerWindow.js b/deluge/ui/web/js/deluge-all/EditTrackerWindow.js
new file mode 100644
index 0000000..82bc32c
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/EditTrackerWindow.js
@@ -0,0 +1,83 @@
+/**
+ * Deluge.EditTrackerWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.EditTrackerWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Tracker'),
+ layout: 'fit',
+ width: 375,
+ height: 110,
+ plain: true,
+ closable: true,
+ resizable: false,
+ constrainHeader: true,
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.EditTrackerWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Save'), this.onSaveClick, this);
+ this.on('hide', this.onHide, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ items: [
+ {
+ fieldLabel: _('Tracker:'),
+ labelSeparator: '',
+ name: 'tracker',
+ anchor: '100%',
+ },
+ ],
+ });
+ },
+
+ show: function(record) {
+ Deluge.EditTrackerWindow.superclass.show.call(this);
+
+ this.record = record;
+ this.form
+ .getForm()
+ .findField('tracker')
+ .setValue(record.data['url']);
+ },
+
+ onCancelClick: function() {
+ this.hide();
+ },
+
+ onHide: function() {
+ this.form
+ .getForm()
+ .findField('tracker')
+ .setValue('');
+ },
+
+ onSaveClick: function() {
+ var url = this.form
+ .getForm()
+ .findField('tracker')
+ .getValue();
+ this.record.set('url', url);
+ this.record.commit();
+ this.hide();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/EditTrackersWindow.js b/deluge/ui/web/js/deluge-all/EditTrackersWindow.js
new file mode 100644
index 0000000..47ffa86
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/EditTrackersWindow.js
@@ -0,0 +1,239 @@
+/**
+ * Deluge.EditTrackers.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.EditTrackerWindow
+ * @extends Ext.Window
+ */
+Deluge.EditTrackersWindow = Ext.extend(Ext.Window, {
+ title: _('Edit Trackers'),
+ layout: 'fit',
+ width: 350,
+ height: 220,
+ plain: true,
+ closable: true,
+ resizable: true,
+ constrainHeader: true,
+
+ bodyStyle: 'padding: 5px',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-edit-trackers',
+
+ initComponent: function() {
+ Deluge.EditTrackersWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('OK'), this.onOkClick, this);
+ this.addEvents('save');
+
+ this.on('show', this.onShow, this);
+ this.on('save', this.onSave, this);
+
+ this.addWindow = new Deluge.AddTrackerWindow();
+ this.addWindow.on('add', this.onAddTrackers, this);
+ this.editWindow = new Deluge.EditTrackerWindow();
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.JsonStore({
+ root: 'trackers',
+ fields: ['tier', 'url'],
+ }),
+ columns: [
+ {
+ header: _('Tier'),
+ width: 0.1,
+ dataIndex: 'tier',
+ },
+ {
+ header: _('Tracker'),
+ width: 0.9,
+ dataIndex: 'url',
+ },
+ ],
+ columnSort: {
+ sortClasses: ['', ''],
+ },
+ stripeRows: true,
+ singleSelect: true,
+ listeners: {
+ dblclick: { fn: this.onListNodeDblClicked, scope: this },
+ selectionchange: { fn: this.onSelect, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ items: [this.list],
+ autoScroll: true,
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: this.onUpClick,
+ scope: this,
+ },
+ {
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: this.onDownClick,
+ scope: this,
+ },
+ '->',
+ {
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onAddClick,
+ scope: this,
+ },
+ {
+ text: _('Edit'),
+ iconCls: 'icon-edit-trackers',
+ handler: this.onEditClick,
+ scope: this,
+ },
+ {
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemoveClick,
+ scope: this,
+ },
+ ],
+ }),
+ });
+ },
+
+ onAddClick: function() {
+ this.addWindow.show();
+ },
+
+ onAddTrackers: function(trackers) {
+ var store = this.list.getStore();
+ Ext.each(
+ trackers,
+ function(tracker) {
+ var duplicate = false,
+ heightestTier = -1;
+ store.each(function(record) {
+ if (record.get('tier') > heightestTier) {
+ heightestTier = record.get('tier');
+ }
+ if (tracker == record.get('tracker')) {
+ duplicate = true;
+ return false;
+ }
+ }, this);
+ if (duplicate) return;
+ store.add(
+ new store.recordType({
+ tier: heightestTier + 1,
+ url: tracker,
+ })
+ );
+ },
+ this
+ );
+ },
+
+ onCancelClick: function() {
+ this.hide();
+ },
+
+ onEditClick: function() {
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ this.editWindow.show(selected);
+ },
+
+ onHide: function() {
+ this.list.getStore().removeAll();
+ },
+
+ onListNodeDblClicked: function(list, index, node, e) {
+ this.editWindow.show(this.list.getRecord(node));
+ },
+
+ onOkClick: function() {
+ var trackers = [];
+ this.list.getStore().each(function(record) {
+ trackers.push({
+ tier: record.get('tier'),
+ url: record.get('url'),
+ });
+ }, this);
+
+ deluge.client.core.set_torrent_trackers(this.torrentId, trackers, {
+ failure: this.onSaveFail,
+ scope: this,
+ });
+
+ this.hide();
+ },
+
+ onRemoveClick: function() {
+ // Remove from the grid
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ this.list.getStore().remove(selected);
+ },
+
+ onRequestComplete: function(status) {
+ this.list.getStore().loadData(status);
+ this.list.getStore().sort('tier', 'ASC');
+ },
+
+ onSaveFail: function() {},
+
+ onSelect: function(list) {
+ if (list.getSelectionCount()) {
+ this.panel
+ .getBottomToolbar()
+ .items.get(4)
+ .enable();
+ }
+ },
+
+ onShow: function() {
+ this.panel
+ .getBottomToolbar()
+ .items.get(4)
+ .disable();
+ var r = deluge.torrents.getSelected();
+ this.torrentId = r.id;
+ deluge.client.core.get_torrent_status(r.id, ['trackers'], {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onDownClick: function() {
+ var r = this.list.getSelectedRecords()[0];
+ if (!r) return;
+
+ r.set('tier', r.get('tier') + 1);
+ r.store.sort('tier', 'ASC');
+ r.store.commitChanges();
+
+ this.list.select(r.store.indexOf(r));
+ },
+
+ onUpClick: function() {
+ var r = this.list.getSelectedRecords()[0];
+ if (!r) return;
+
+ if (r.get('tier') == 0) return;
+ r.set('tier', r.get('tier') - 1);
+ r.store.sort('tier', 'ASC');
+ r.store.commitChanges();
+
+ this.list.select(r.store.indexOf(r));
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/EventsManager.js b/deluge/ui/web/js/deluge-all/EventsManager.js
new file mode 100644
index 0000000..1714339
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/EventsManager.js
@@ -0,0 +1,118 @@
+/**
+ * Deluge.EventsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @class Deluge.EventsManager
+ * @extends Ext.util.Observable
+ * <p>Deluge.EventsManager is instantated as <tt>deluge.events</tt> and can be used by components of the UI to fire global events</p>
+ * Class for holding global events that occur within the UI.
+ */
+Deluge.EventsManager = Ext.extend(Ext.util.Observable, {
+ constructor: function() {
+ this.toRegister = [];
+ this.on('login', this.onLogin, this);
+ Deluge.EventsManager.superclass.constructor.call(this);
+ },
+
+ /**
+ * Append an event handler to this object.
+ */
+ addListener: function(eventName, fn, scope, o) {
+ this.addEvents(eventName);
+ if (/[A-Z]/.test(eventName.substring(0, 1))) {
+ if (!deluge.client) {
+ this.toRegister.push(eventName);
+ } else {
+ deluge.client.web.register_event_listener(eventName);
+ }
+ }
+ Deluge.EventsManager.superclass.addListener.call(
+ this,
+ eventName,
+ fn,
+ scope,
+ o
+ );
+ },
+
+ getEvents: function() {
+ deluge.client.web.get_events({
+ success: this.onGetEventsSuccess,
+ failure: this.onGetEventsFailure,
+ scope: this,
+ });
+ },
+
+ /**
+ * Starts the EventsManagerManager checking for events.
+ */
+ start: function() {
+ Ext.each(this.toRegister, function(eventName) {
+ deluge.client.web.register_event_listener(eventName);
+ });
+ this.running = true;
+ this.errorCount = 0;
+ this.getEvents();
+ },
+
+ /**
+ * Stops the EventsManagerManager checking for events.
+ */
+ stop: function() {
+ this.running = false;
+ },
+
+ // private
+ onLogin: function() {
+ this.start();
+ },
+
+ onGetEventsSuccess: function(events) {
+ if (!this.running) return;
+ if (events) {
+ Ext.each(
+ events,
+ function(event) {
+ var name = event[0],
+ args = event[1];
+ args.splice(0, 0, name);
+ this.fireEvent.apply(this, args);
+ },
+ this
+ );
+ }
+ this.getEvents();
+ },
+
+ // private
+ onGetEventsFailure: function(result, error) {
+ // the request timed out or we had a communication failure
+ if (!this.running) return;
+ if (!error.isTimeout && this.errorCount++ >= 3) {
+ this.stop();
+ return;
+ }
+ this.getEvents();
+ },
+});
+
+/**
+ * Appends an event handler to this object (shorthand for {@link #addListener})
+ * @method
+ */
+Deluge.EventsManager.prototype.on = Deluge.EventsManager.prototype.addListener;
+
+/**
+ * Fires the specified event with the passed parameters (minus the
+ * event name).
+ * @method
+ */
+Deluge.EventsManager.prototype.fire = Deluge.EventsManager.prototype.fireEvent;
+deluge.events = new Deluge.EventsManager();
diff --git a/deluge/ui/web/js/deluge-all/FileBrowser.js b/deluge/ui/web/js/deluge-all/FileBrowser.js
new file mode 100644
index 0000000..72962a6
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/FileBrowser.js
@@ -0,0 +1,43 @@
+/**
+ * Deluge.FileBrowser.js
+ *
+ * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge');
+Deluge.FileBrowser = Ext.extend(Ext.Window, {
+ title: _('File Browser'),
+
+ width: 500,
+ height: 400,
+
+ initComponent: function() {
+ Deluge.FileBrowser.superclass.initComponent.call(this);
+
+ this.add({
+ xtype: 'toolbar',
+ items: [
+ {
+ text: _('Back'),
+ iconCls: 'icon-back',
+ },
+ {
+ text: _('Forward'),
+ iconCls: 'icon-forward',
+ },
+ {
+ text: _('Up'),
+ iconCls: 'icon-up',
+ },
+ {
+ text: _('Home'),
+ iconCls: 'icon-home',
+ },
+ ],
+ });
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/FilterPanel.js b/deluge/ui/web/js/deluge-all/FilterPanel.js
new file mode 100644
index 0000000..2362dbb
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/FilterPanel.js
@@ -0,0 +1,175 @@
+/**
+ * Deluge.FilterPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.FilterPanel
+ * @extends Ext.list.ListView
+ */
+Deluge.FilterPanel = Ext.extend(Ext.Panel, {
+ autoScroll: true,
+
+ border: false,
+
+ show_zero: null,
+
+ initComponent: function() {
+ Deluge.FilterPanel.superclass.initComponent.call(this);
+ this.filterType = this.initialConfig.filter;
+ var title = '';
+ if (this.filterType == 'state') {
+ title = _('States');
+ } else if (this.filterType == 'tracker_host') {
+ title = _('Trackers');
+ } else if (this.filterType == 'owner') {
+ title = _('Owner');
+ } else if (this.filterType == 'label') {
+ title = _('Labels');
+ } else {
+ (title = this.filterType.replace('_', ' ')),
+ (parts = title.split(' ')),
+ (title = '');
+ Ext.each(parts, function(p) {
+ fl = p.substring(0, 1).toUpperCase();
+ title += fl + p.substring(1) + ' ';
+ });
+ }
+ this.setTitle(_(title));
+
+ if (Deluge.FilterPanel.templates[this.filterType]) {
+ var tpl = Deluge.FilterPanel.templates[this.filterType];
+ } else {
+ var tpl =
+ '<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';
+ }
+
+ this.list = this.add({
+ xtype: 'listview',
+ singleSelect: true,
+ hideHeaders: true,
+ reserveScrollOffset: true,
+ store: new Ext.data.ArrayStore({
+ idIndex: 0,
+ fields: ['filter', 'count'],
+ }),
+ columns: [
+ {
+ id: 'filter',
+ sortable: false,
+ tpl: tpl,
+ dataIndex: 'filter',
+ },
+ ],
+ });
+ this.relayEvents(this.list, ['selectionchange']);
+ },
+
+ /**
+ * Return the currently selected filter state
+ * @returns {String} the current filter state
+ */
+ getState: function() {
+ if (!this.list.getSelectionCount()) return;
+
+ var state = this.list.getSelectedRecords()[0];
+ if (!state) return;
+ if (state.id == 'All') return;
+ return state.id;
+ },
+
+ /**
+ * Return the current states in the filter
+ */
+ getStates: function() {
+ return this.states;
+ },
+
+ /**
+ * Return the Store for the ListView of the FilterPanel
+ * @returns {Ext.data.Store} the ListView store
+ */
+ getStore: function() {
+ return this.list.getStore();
+ },
+
+ /**
+ * Update the states in the FilterPanel
+ */
+ updateStates: function(states) {
+ this.states = {};
+ Ext.each(
+ states,
+ function(state) {
+ this.states[state[0]] = state[1];
+ },
+ this
+ );
+
+ var show_zero =
+ this.show_zero == null
+ ? deluge.config.sidebar_show_zero
+ : this.show_zero;
+ if (!show_zero) {
+ var newStates = [];
+ Ext.each(states, function(state) {
+ if (state[1] > 0 || state[0] == 'All') {
+ newStates.push(state);
+ }
+ });
+ states = newStates;
+ }
+
+ var store = this.getStore();
+ var filters = {};
+ Ext.each(
+ states,
+ function(s, i) {
+ var record = store.getById(s[0]);
+ if (!record) {
+ record = new store.recordType({
+ filter: s[0],
+ count: s[1],
+ });
+ record.id = s[0];
+ store.insert(i, record);
+ }
+ record.beginEdit();
+ record.set('filter', _(s[0]));
+ record.set('count', s[1]);
+ record.endEdit();
+ filters[s[0]] = true;
+ },
+ this
+ );
+
+ store.each(function(record) {
+ if (filters[record.id]) return;
+ store.remove(record);
+ var selected = this.list.getSelectedRecords()[0];
+ if (!selected) return;
+ if (selected.id == record.id) {
+ this.list.select(0);
+ }
+ }, this);
+
+ store.commitChanges();
+
+ if (!this.list.getSelectionCount()) {
+ this.list.select(0);
+ }
+ },
+});
+
+Deluge.FilterPanel.templates = {
+ tracker_host:
+ '<div class="x-deluge-filter" style="background-image: url(' +
+ deluge.config.base +
+ 'tracker/{filter});">{filter} ({count})</div>',
+};
diff --git a/deluge/ui/web/js/deluge-all/Formatters.js b/deluge/ui/web/js/deluge-all/Formatters.js
new file mode 100644
index 0000000..a511f34
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Formatters.js
@@ -0,0 +1,181 @@
+/**
+ * Deluge.Formatters.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * A collection of functions for string formatting values.
+ * @class Deluge.Formatters
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ * @singleton
+ */
+Deluge.Formatters = {
+ /**
+ * Formats a date string in the date representation of the current locale,
+ * based on the systems timezone.
+ *
+ * @param {Number} timestamp time in seconds since the Epoch.
+ * @return {String} a string in the date representation of the current locale
+ * or "" if seconds < 0.
+ */
+ date: function(timestamp) {
+ function zeroPad(num, count) {
+ var numZeropad = num + '';
+ while (numZeropad.length < count) {
+ numZeropad = '0' + numZeropad;
+ }
+ return numZeropad;
+ }
+ timestamp = timestamp * 1000;
+ var date = new Date(timestamp);
+ return String.format(
+ '{0}/{1}/{2} {3}:{4}:{5}',
+ zeroPad(date.getDate(), 2),
+ zeroPad(date.getMonth() + 1, 2),
+ date.getFullYear(),
+ zeroPad(date.getHours(), 2),
+ zeroPad(date.getMinutes(), 2),
+ zeroPad(date.getSeconds(), 2)
+ );
+ },
+
+ /**
+ * Formats the bytes value into a string with KiB, MiB or GiB units.
+ *
+ * @param {Number} bytes the filesize in bytes
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with KiB, MiB or GiB units.
+ */
+ size: function(bytes, showZero) {
+ if (!bytes && !showZero) return '';
+ bytes = bytes / 1024.0;
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' KiB';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' MiB';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ return bytes.toFixed(1) + ' GiB';
+ },
+
+ /**
+ * Formats the bytes value into a string with K, M or G units.
+ *
+ * @param {Number} bytes the filesize in bytes
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with K, M or G units.
+ */
+ sizeShort: function(bytes, showZero) {
+ if (!bytes && !showZero) return '';
+ bytes = bytes / 1024.0;
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' K';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ if (bytes < 1024) {
+ return bytes.toFixed(1) + ' M';
+ } else {
+ bytes = bytes / 1024;
+ }
+
+ return bytes.toFixed(1) + ' G';
+ },
+
+ /**
+ * Formats a string to display a transfer speed utilizing {@link #size}
+ *
+ * @param {Number} bytes the number of bytes per second
+ * @param {Boolean} showZero pass in true to displays 0 values
+ * @return {String} formatted string with KiB, MiB or GiB units.
+ */
+ speed: function(bytes, showZero) {
+ return !bytes && !showZero ? '' : fsize(bytes, showZero) + '/s';
+ },
+
+ /**
+ * Formats a string to show time in a human readable form.
+ *
+ * @param {Number} time the number of seconds
+ * @return {String} a formatted time string. will return '' if seconds == 0
+ */
+ timeRemaining: function(time) {
+ if (time <= 0) {
+ return '&infin;';
+ }
+ time = time.toFixed(0);
+ if (time < 60) {
+ return time + 's';
+ } else {
+ time = time / 60;
+ }
+
+ if (time < 60) {
+ var minutes = Math.floor(time);
+ var seconds = Math.round(60 * (time - minutes));
+ if (seconds > 0) {
+ return minutes + 'm ' + seconds + 's';
+ } else {
+ return minutes + 'm';
+ }
+ } else {
+ time = time / 60;
+ }
+
+ if (time < 24) {
+ var hours = Math.floor(time);
+ var minutes = Math.round(60 * (time - hours));
+ if (minutes > 0) {
+ return hours + 'h ' + minutes + 'm';
+ } else {
+ return hours + 'h';
+ }
+ } else {
+ time = time / 24;
+ }
+
+ var days = Math.floor(time);
+ var hours = Math.round(24 * (time - days));
+ if (hours > 0) {
+ return days + 'd ' + hours + 'h';
+ } else {
+ return days + 'd';
+ }
+ },
+
+ /**
+ * Simply returns the value untouched, for when no formatting is required.
+ *
+ * @param {Mixed} value the value to be displayed
+ * @return the untouched value.
+ */
+ plain: function(value) {
+ return value;
+ },
+
+ cssClassEscape: function(value) {
+ return value.toLowerCase().replace('.', '_');
+ },
+};
+var fsize = Deluge.Formatters.size;
+var fsize_short = Deluge.Formatters.sizeShort;
+var fspeed = Deluge.Formatters.speed;
+var ftime = Deluge.Formatters.timeRemaining;
+var fdate = Deluge.Formatters.date;
+var fplain = Deluge.Formatters.plain;
+Ext.util.Format.cssClassEscape = Deluge.Formatters.cssClassEscape;
diff --git a/deluge/ui/web/js/deluge-all/Keys.js b/deluge/ui/web/js/deluge-all/Keys.js
new file mode 100644
index 0000000..25cf38b
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Keys.js
@@ -0,0 +1,138 @@
+/**
+ * Deluge.Keys.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @description The torrent status keys that are commonly used around the UI.
+ * @class Deluge.Keys
+ * @singleton
+ */
+Deluge.Keys = {
+ /**
+ * Keys that are used within the torrent grid.
+ * <pre>['queue', 'name', 'total_wanted', 'state', 'progress', 'num_seeds',
+ * 'total_seeds', 'num_peers', 'total_peers', 'download_payload_rate',
+ * 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
+ * 'is_auto_managed', 'time_added', 'tracker_host', 'download_location', 'last_seen_complete',
+ * 'total_done', 'total_uploaded', 'max_download_speed', 'max_upload_speed',
+ * 'seeds_peers_ratio', 'total_remaining', 'completed_time', 'time_since_transfer']</pre>
+ */
+ Grid: [
+ 'queue',
+ 'name',
+ 'total_wanted',
+ 'state',
+ 'progress',
+ 'num_seeds',
+ 'total_seeds',
+ 'num_peers',
+ 'total_peers',
+ 'download_payload_rate',
+ 'upload_payload_rate',
+ 'eta',
+ 'ratio',
+ 'distributed_copies',
+ 'is_auto_managed',
+ 'time_added',
+ 'tracker_host',
+ 'download_location',
+ 'last_seen_complete',
+ 'total_done',
+ 'total_uploaded',
+ 'max_download_speed',
+ 'max_upload_speed',
+ 'seeds_peers_ratio',
+ 'total_remaining',
+ 'completed_time',
+ 'time_since_transfer',
+ ],
+
+ /**
+ * Keys used in the status tab of the statistics panel.
+ * These get updated to include the keys in {@link #Grid}.
+ * <pre>['total_done', 'total_payload_download', 'total_uploaded',
+ * 'total_payload_upload', 'next_announce', 'tracker_status', 'num_pieces',
+ * 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time', 'time_since_transfer',
+ * 'seed_rank', 'last_seen_complete', 'completed_time', 'owner', 'public', 'shared']</pre>
+ */
+ Status: [
+ 'total_done',
+ 'total_payload_download',
+ 'total_uploaded',
+ 'total_payload_upload',
+ 'next_announce',
+ 'tracker_status',
+ 'num_pieces',
+ 'piece_length',
+ 'is_auto_managed',
+ 'active_time',
+ 'seeding_time',
+ 'time_since_transfer',
+ 'seed_rank',
+ 'last_seen_complete',
+ 'completed_time',
+ 'owner',
+ 'public',
+ 'shared',
+ ],
+
+ /**
+ * Keys used in the files tab of the statistics panel.
+ * <pre>['files', 'file_progress', 'file_priorities']</pre>
+ */
+ Files: ['files', 'file_progress', 'file_priorities'],
+
+ /**
+ * Keys used in the peers tab of the statistics panel.
+ * <pre>['peers']</pre>
+ */
+ Peers: ['peers'],
+
+ /**
+ * Keys used in the details tab of the statistics panel.
+ */
+ Details: [
+ 'name',
+ 'download_location',
+ 'total_size',
+ 'num_files',
+ 'message',
+ 'tracker_host',
+ 'comment',
+ 'creator',
+ ],
+
+ /**
+ * Keys used in the options tab of the statistics panel.
+ * <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
+ * 'is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'remove_at_ratio', 'private',
+ * 'prioritize_first_last']</pre>
+ */
+ Options: [
+ 'max_download_speed',
+ 'max_upload_speed',
+ 'max_connections',
+ 'max_upload_slots',
+ 'is_auto_managed',
+ 'stop_at_ratio',
+ 'stop_ratio',
+ 'remove_at_ratio',
+ 'private',
+ 'prioritize_first_last',
+ 'move_completed',
+ 'move_completed_path',
+ 'super_seeding',
+ ],
+};
+
+// Merge the grid and status keys together as the status keys contain all the
+// grid ones.
+Ext.each(Deluge.Keys.Grid, function(key) {
+ Deluge.Keys.Status.push(key);
+});
diff --git a/deluge/ui/web/js/deluge-all/LoginWindow.js b/deluge/ui/web/js/deluge-all/LoginWindow.js
new file mode 100644
index 0000000..964f5ff
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/LoginWindow.js
@@ -0,0 +1,134 @@
+/**
+ * Deluge.LoginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.LoginWindow = Ext.extend(Ext.Window, {
+ firstShow: true,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'center',
+ closable: false,
+ closeAction: 'hide',
+ iconCls: 'x-deluge-login-window-icon',
+ layout: 'fit',
+ modal: true,
+ plain: true,
+ resizable: false,
+ title: _('Login'),
+ width: 300,
+ height: 120,
+
+ initComponent: function() {
+ Deluge.LoginWindow.superclass.initComponent.call(this);
+ this.on('show', this.onShow, this);
+
+ this.addButton({
+ text: _('Login'),
+ handler: this.onLogin,
+ scope: this,
+ });
+
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ labelWidth: 120,
+ labelAlign: 'right',
+ defaults: { width: 110 },
+ defaultType: 'textfield',
+ });
+
+ this.passwordField = this.form.add({
+ xtype: 'textfield',
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ grow: true,
+ growMin: '110',
+ growMax: '145',
+ id: '_password',
+ name: 'password',
+ inputType: 'password',
+ });
+ this.passwordField.on('specialkey', this.onSpecialKey, this);
+ },
+
+ logout: function() {
+ deluge.events.fire('logout');
+ deluge.client.auth.delete_session({
+ success: function(result) {
+ this.show(true);
+ },
+ scope: this,
+ });
+ },
+
+ show: function(skipCheck) {
+ if (this.firstShow) {
+ deluge.client.on('error', this.onClientError, this);
+ this.firstShow = false;
+ }
+
+ if (skipCheck) {
+ return Deluge.LoginWindow.superclass.show.call(this);
+ }
+
+ deluge.client.auth.check_session({
+ success: function(result) {
+ if (result) {
+ deluge.events.fire('login');
+ } else {
+ this.show(true);
+ }
+ },
+ failure: function(result) {
+ this.show(true);
+ },
+ scope: this,
+ });
+ },
+
+ onSpecialKey: function(field, e) {
+ if (e.getKey() == 13) this.onLogin();
+ },
+
+ onLogin: function() {
+ var passwordField = this.passwordField;
+ deluge.client.auth.login(passwordField.getValue(), {
+ success: function(result) {
+ if (result) {
+ deluge.events.fire('login');
+ this.hide();
+ passwordField.setRawValue('');
+ } else {
+ Ext.MessageBox.show({
+ title: _('Login Failed'),
+ msg: _('You entered an incorrect password'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ fn: function() {
+ passwordField.focus(true, 10);
+ },
+ icon: Ext.MessageBox.WARNING,
+ iconCls: 'x-deluge-icon-warning',
+ });
+ }
+ },
+ scope: this,
+ });
+ },
+
+ onClientError: function(errorObj, response, requestOptions) {
+ if (errorObj.error.code == 1) {
+ deluge.events.fire('logout');
+ this.show(true);
+ }
+ },
+
+ onShow: function() {
+ this.passwordField.focus(true, 300);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Menus.js b/deluge/ui/web/js/deluge-all/Menus.js
new file mode 100644
index 0000000..529c6cc
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Menus.js
@@ -0,0 +1,388 @@
+/**
+ * Deluge.Menus.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+deluge.menus = {
+ onTorrentActionSetOpt: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ var opts = {};
+ opts[action[0]] = action[1];
+ deluge.client.core.set_torrent_options(ids, opts);
+ },
+
+ onTorrentActionMethod: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ deluge.client.core[action](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ },
+
+ onTorrentActionShow: function(item, e) {
+ var ids = deluge.torrents.getSelectedIds();
+ var action = item.initialConfig.torrentAction;
+ switch (action) {
+ case 'edit_trackers':
+ deluge.editTrackers.show();
+ break;
+ case 'remove':
+ deluge.removeWindow.show(ids);
+ break;
+ case 'move':
+ deluge.moveStorage.show(ids);
+ break;
+ }
+ },
+};
+
+deluge.menus.torrent = new Ext.menu.Menu({
+ id: 'torrentMenu',
+ items: [
+ {
+ torrentAction: 'pause_torrent',
+ text: _('Pause'),
+ iconCls: 'icon-pause',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'resume_torrent',
+ text: _('Resume'),
+ iconCls: 'icon-resume',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ text: _('Options'),
+ iconCls: 'icon-options',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ text: _('D/L Speed Limit'),
+ iconCls: 'x-deluge-downloading',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_download_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_download_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('U/L Speed Limit'),
+ iconCls: 'x-deluge-seeding',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_upload_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('Connection Limit'),
+ iconCls: 'x-deluge-connections',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_connections', 50],
+ text: '50',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 100],
+ text: '100',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 200],
+ text: '200',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 300],
+ text: '300',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', 500],
+ text: '500',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_connections', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ text: _('Upload Slot Limit'),
+ iconCls: 'icon-upload-slots',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['max_upload_slots', 0],
+ text: '0',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 1],
+ text: '1',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 2],
+ text: '2',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 3],
+ text: '3',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', 5],
+ text: '5',
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['max_upload_slots', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ {
+ id: 'auto_managed',
+ text: _('Auto Managed'),
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: ['auto_managed', true],
+ text: _('On'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: ['auto_managed', false],
+ text: _('Off'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ ],
+ }),
+ },
+ '-',
+ {
+ text: _('Queue'),
+ iconCls: 'icon-queue',
+ hideOnClick: false,
+ menu: new Ext.menu.Menu({
+ items: [
+ {
+ torrentAction: 'queue_top',
+ text: _('Top'),
+ iconCls: 'icon-top',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_up',
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_down',
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'queue_bottom',
+ text: _('Bottom'),
+ iconCls: 'icon-bottom',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ ],
+ }),
+ },
+ '-',
+ {
+ torrentAction: 'force_reannounce',
+ text: _('Update Tracker'),
+ iconCls: 'icon-update-tracker',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'edit_trackers',
+ text: _('Edit Trackers'),
+ iconCls: 'icon-edit-trackers',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ torrentAction: 'remove',
+ text: _('Remove Torrent'),
+ iconCls: 'icon-remove',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ '-',
+ {
+ torrentAction: 'force_recheck',
+ text: _('Force Recheck'),
+ iconCls: 'icon-recheck',
+ handler: deluge.menus.onTorrentActionMethod,
+ scope: deluge.menus,
+ },
+ {
+ torrentAction: 'move',
+ text: _('Move Download Folder'),
+ iconCls: 'icon-move',
+ handler: deluge.menus.onTorrentActionShow,
+ scope: deluge.menus,
+ },
+ ],
+});
+
+deluge.menus.filePriorities = new Ext.menu.Menu({
+ id: 'filePrioritiesMenu',
+ items: [
+ {
+ id: 'expandAll',
+ text: _('Expand All'),
+ iconCls: 'icon-expand-all',
+ },
+ '-',
+ {
+ id: 'skip',
+ text: _('Skip'),
+ iconCls: 'icon-do-not-download',
+ filePriority: FILE_PRIORITY['Skip'],
+ },
+ {
+ id: 'low',
+ text: _('Low'),
+ iconCls: 'icon-low',
+ filePriority: FILE_PRIORITY['Low'],
+ },
+ {
+ id: 'normal',
+ text: _('Normal'),
+ iconCls: 'icon-normal',
+ filePriority: FILE_PRIORITY['Normal'],
+ },
+ {
+ id: 'high',
+ text: _('High'),
+ iconCls: 'icon-high',
+ filePriority: FILE_PRIORITY['High'],
+ },
+ ],
+});
diff --git a/deluge/ui/web/js/deluge-all/MoveStorage.js b/deluge/ui/web/js/deluge-all/MoveStorage.js
new file mode 100644
index 0000000..208031f
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/MoveStorage.js
@@ -0,0 +1,85 @@
+/**
+ * Deluge.MoveStorage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge');
+Deluge.MoveStorage = Ext.extend(Ext.Window, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ title: _('Move Download Folder'),
+ width: 375,
+ height: 110,
+ layout: 'fit',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-move-storage',
+ plain: true,
+ constrainHeader: true,
+ resizable: false,
+ },
+ config
+ );
+ Deluge.MoveStorage.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.MoveStorage.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancel, this);
+ this.addButton(_('Move'), this.onMove, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ border: false,
+ defaultType: 'textfield',
+ width: 300,
+ bodyStyle: 'padding: 5px',
+ });
+
+ this.moveLocation = this.form.add({
+ fieldLabel: _('Download Folder'),
+ name: 'location',
+ width: 240,
+ });
+ //this.form.add({
+ // xtype: 'button',
+ // text: _('Browse'),
+ // handler: function() {
+ // if (!this.fileBrowser) {
+ // this.fileBrowser = new Deluge.FileBrowser();
+ // }
+ // this.fileBrowser.show();
+ // },
+ // scope: this
+ //});
+ },
+
+ hide: function() {
+ Deluge.MoveStorage.superclass.hide.call(this);
+ this.torrentIds = null;
+ },
+
+ show: function(torrentIds) {
+ Deluge.MoveStorage.superclass.show.call(this);
+ this.torrentIds = torrentIds;
+ },
+
+ onCancel: function() {
+ this.hide();
+ },
+
+ onMove: function() {
+ var dest = this.moveLocation.getValue();
+ deluge.client.core.move_storage(this.torrentIds, dest);
+ this.hide();
+ },
+});
+deluge.moveStorage = new Deluge.MoveStorage();
diff --git a/deluge/ui/web/js/deluge-all/MultiOptionsManager.js b/deluge/ui/web/js/deluge-all/MultiOptionsManager.js
new file mode 100644
index 0000000..1cd7d19
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/MultiOptionsManager.js
@@ -0,0 +1,218 @@
+/**
+ * Deluge.MultiOptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @description A class that can be used to manage options throughout the ui.
+ * @namespace Deluge
+ * @class Deluge.MultiOptionsManager
+ * @extends Deluge.OptionsManager
+ */
+Deluge.MultiOptionsManager = Ext.extend(Deluge.OptionsManager, {
+ constructor: function(config) {
+ this.currentId = null;
+ this.stored = {};
+ Deluge.MultiOptionsManager.superclass.constructor.call(this, config);
+ },
+
+ /**
+ * Changes bound fields to use the specified id.
+ * @param {String} id
+ */
+ changeId: function(id, dontUpdateBinds) {
+ var oldId = this.currentId;
+ this.currentId = id;
+ if (!dontUpdateBinds) {
+ for (var option in this.options) {
+ if (!this.binds[option]) continue;
+ Ext.each(
+ this.binds[option],
+ function(bind) {
+ bind.setValue(this.get(option));
+ },
+ this
+ );
+ }
+ }
+ return oldId;
+ },
+
+ /**
+ * Changes all the changed values to be the default values
+ * @param {String} id
+ */
+ commit: function() {
+ this.stored[this.currentId] = Ext.apply(
+ this.stored[this.currentId],
+ this.changed[this.currentId]
+ );
+ this.reset();
+ },
+
+ /**
+ * Get the value for an option
+ * @param {String/Array} option A single option or an array of options to return.
+ * @returns {Object} the options value.
+ */
+ get: function() {
+ if (arguments.length == 1) {
+ var option = arguments[0];
+ return this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ } else if (arguments.length == 0) {
+ var options = {};
+ for (var option in this.options) {
+ options[option] = this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ }
+ return options;
+ } else {
+ var options = {};
+ Ext.each(
+ arguments,
+ function(option) {
+ options[option] = this.isDirty(option)
+ ? this.changed[this.currentId][option]
+ : this.getDefault(option);
+ },
+ this
+ );
+ return options;
+ }
+ },
+
+ /**
+ * Get the default value for an option.
+ * @param {String} option A single option.
+ * @returns {Object} the value of the option
+ */
+ getDefault: function(option) {
+ return this.has(option)
+ ? this.stored[this.currentId][option]
+ : this.options[option];
+ },
+
+ /**
+ * Returns the dirty (changed) values.
+ * @returns {Object} the changed options
+ */
+ getDirty: function() {
+ return this.changed[this.currentId] ? this.changed[this.currentId] : {};
+ },
+
+ /**
+ * Check to see if the option has been changed.
+ * @param {String} option
+ * @returns {Boolean} true if the option has been changed, else false.
+ */
+ isDirty: function(option) {
+ return (
+ this.changed[this.currentId] &&
+ !Ext.isEmpty(this.changed[this.currentId][option])
+ );
+ },
+
+ /**
+ * Check to see if an id has had an option set to something other than the
+ * default value.
+ * @param {String} option
+ * @returns {Boolean} true if the id has an option, else false.
+ */
+ has: function(option) {
+ return (
+ this.stored[this.currentId] &&
+ !Ext.isEmpty(this.stored[this.currentId][option])
+ );
+ },
+
+ /**
+ * Reset the options back to the default values for the specified id.
+ */
+ reset: function() {
+ if (this.changed[this.currentId]) delete this.changed[this.currentId];
+ if (this.stored[this.currentId]) delete this.stored[this.currentId];
+ },
+
+ /**
+ * Reset the options back to their defaults for all ids.
+ */
+ resetAll: function() {
+ this.changed = {};
+ this.stored = {};
+ this.changeId(null);
+ },
+
+ /**
+ * Sets the value of specified option for the passed in id.
+ * @param {String} id
+ * @param {String} option
+ * @param {Object} value The value for the option
+ */
+ setDefault: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.setDefault(key, option[key]);
+ }
+ } else {
+ var oldValue = this.getDefault(option);
+ value = this.convertValueType(oldValue, value);
+
+ // If the value is the same as the old value there is
+ // no point in setting it again.
+ if (oldValue == value) return;
+
+ // Store the new default
+ if (!this.stored[this.currentId]) this.stored[this.currentId] = {};
+ this.stored[this.currentId][option] = value;
+
+ if (!this.isDirty(option)) {
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ }
+ },
+
+ /**
+ * Update the value for the specified option and id.
+ * @param {String} id
+ * @param {String/Object} option or options to update
+ * @param {Object} [value];
+ */
+ update: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.update(key, option[key]);
+ }
+ } else {
+ if (!this.changed[this.currentId])
+ this.changed[this.currentId] = {};
+
+ var defaultValue = this.getDefault(option);
+ value = this.convertValueType(defaultValue, value);
+
+ var oldValue = this.get(option);
+ if (oldValue == value) return;
+
+ if (defaultValue == value) {
+ if (this.isDirty(option))
+ delete this.changed[this.currentId][option];
+ this.fireEvent('changed', option, value, oldValue);
+ return;
+ } else {
+ this.changed[this.currentId][option] = value;
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/OptionsManager.js b/deluge/ui/web/js/deluge-all/OptionsManager.js
new file mode 100644
index 0000000..a1c4e65
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/OptionsManager.js
@@ -0,0 +1,279 @@
+/**
+ * Deluge.OptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge');
+
+/**
+ * @class Deluge.OptionsManager
+ * @extends Ext.util.Observable
+ * A class that can be used to manage options throughout the ui.
+ * @constructor
+ * Creates a new OptionsManager
+ * @param {Object} config Configuration options
+ */
+Deluge.OptionsManager = Ext.extend(Ext.util.Observable, {
+ constructor: function(config) {
+ config = config || {};
+ this.binds = {};
+ this.changed = {};
+ this.options = (config && config['options']) || {};
+ this.focused = null;
+
+ this.addEvents({
+ /**
+ * @event add
+ * Fires when an option is added
+ */
+ add: true,
+
+ /**
+ * @event changed
+ * Fires when an option is changed
+ * @param {String} option The changed option
+ * @param {Mixed} value The options new value
+ * @param {Mixed} oldValue The options old value
+ */
+ changed: true,
+
+ /**
+ * @event reset
+ * Fires when the options are reset
+ */
+ reset: true,
+ });
+ this.on('changed', this.onChange, this);
+
+ Deluge.OptionsManager.superclass.constructor.call(this);
+ },
+
+ /**
+ * Add a set of default options and values to the options manager
+ * @param {Object} options The default options.
+ */
+ addOptions: function(options) {
+ this.options = Ext.applyIf(this.options, options);
+ },
+
+ /**
+ * Binds a form field to the specified option.
+ * @param {String} option
+ * @param {Ext.form.Field} field
+ */
+ bind: function(option, field) {
+ this.binds[option] = this.binds[option] || [];
+ this.binds[option].push(field);
+ field._doption = option;
+
+ field.on('focus', this.onFieldFocus, this);
+ field.on('blur', this.onFieldBlur, this);
+ field.on('change', this.onFieldChange, this);
+ field.on('check', this.onFieldChange, this);
+ field.on('spin', this.onFieldChange, this);
+ return field;
+ },
+
+ /**
+ * Changes all the changed values to be the default values
+ */
+ commit: function() {
+ this.options = Ext.apply(this.options, this.changed);
+ this.reset();
+ },
+
+ /**
+ * Converts the value so it matches the originals type
+ * @param {Mixed} oldValue The original value
+ * @param {Mixed} value The new value to convert
+ */
+ convertValueType: function(oldValue, value) {
+ if (Ext.type(oldValue) != Ext.type(value)) {
+ switch (Ext.type(oldValue)) {
+ case 'string':
+ value = String(value);
+ break;
+ case 'number':
+ value = Number(value);
+ break;
+ case 'boolean':
+ if (Ext.type(value) == 'string') {
+ value = value.toLowerCase();
+ value =
+ value == 'true' || value == '1' || value == 'on'
+ ? true
+ : false;
+ } else {
+ value = Boolean(value);
+ }
+ break;
+ }
+ }
+ return value;
+ },
+
+ /**
+ * Get the value for an option or options.
+ * @param {String} [option] A single option or an array of options to return.
+ * @returns {Object} the options value.
+ */
+ get: function() {
+ if (arguments.length == 1) {
+ var option = arguments[0];
+ return this.isDirty(option)
+ ? this.changed[option]
+ : this.options[option];
+ } else {
+ var options = {};
+ Ext.each(
+ arguments,
+ function(option) {
+ if (!this.has(option)) return;
+ options[option] = this.isDirty(option)
+ ? this.changed[option]
+ : this.options[option];
+ },
+ this
+ );
+ return options;
+ }
+ },
+
+ /**
+ * Get the default value for an option or options.
+ * @param {String|Array} [option] A single option or an array of options to return.
+ * @returns {Object} the value of the option
+ */
+ getDefault: function(option) {
+ return this.options[option];
+ },
+
+ /**
+ * Returns the dirty (changed) values.
+ * @returns {Object} the changed options
+ */
+ getDirty: function() {
+ return this.changed;
+ },
+
+ /**
+ * @param {String} [option] The option to check
+ * @returns {Boolean} true if the option has been changed from the default.
+ */
+ isDirty: function(option) {
+ return !Ext.isEmpty(this.changed[option]);
+ },
+
+ /**
+ * Check to see if an option exists in the options manager
+ * @param {String} option
+ * @returns {Boolean} true if the option exists, else false.
+ */
+ has: function(option) {
+ return this.options[option];
+ },
+
+ /**
+ * Reset the options back to the default values.
+ */
+ reset: function() {
+ this.changed = {};
+ },
+
+ /**
+ * Sets the value of specified option(s) for the passed in id.
+ * @param {String} option
+ * @param {Object} value The value for the option
+ */
+ set: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (typeof option == 'object') {
+ var options = option;
+ this.options = Ext.apply(this.options, options);
+ for (var option in options) {
+ this.onChange(option, options[option]);
+ }
+ } else {
+ this.options[option] = value;
+ this.onChange(option, value);
+ }
+ },
+
+ /**
+ * Update the value for the specified option and id.
+ * @param {String/Object} option or options to update
+ * @param {Object} [value];
+ */
+ update: function(option, value) {
+ if (option === undefined) {
+ return;
+ } else if (value === undefined) {
+ for (var key in option) {
+ this.update(key, option[key]);
+ }
+ } else {
+ var defaultValue = this.getDefault(option);
+ value = this.convertValueType(defaultValue, value);
+
+ var oldValue = this.get(option);
+ if (oldValue == value) return;
+
+ if (defaultValue == value) {
+ if (this.isDirty(option)) delete this.changed[option];
+ this.fireEvent('changed', option, value, oldValue);
+ return;
+ }
+
+ this.changed[option] = value;
+ this.fireEvent('changed', option, value, oldValue);
+ }
+ },
+
+ /**
+ * Lets the option manager know when a field is blurred so if a value
+ * so value changing operations can continue on that field.
+ */
+ onFieldBlur: function(field, event) {
+ if (this.focused == field) {
+ this.focused = null;
+ }
+ },
+
+ /**
+ * Stops a form fields value from being blocked by the change functions
+ * @param {Ext.form.Field} field
+ * @private
+ */
+ onFieldChange: function(field, event) {
+ if (field.field) field = field.field; // fix for spinners
+ this.update(field._doption, field.getValue());
+ },
+
+ /**
+ * Lets the option manager know when a field is focused so if a value changing
+ * operation is performed it will not change the value of the field.
+ */
+ onFieldFocus: function(field, event) {
+ this.focused = field;
+ },
+
+ onChange: function(option, newValue, oldValue) {
+ // If we don't have a bind there's nothing to do.
+ if (Ext.isEmpty(this.binds[option])) return;
+ Ext.each(
+ this.binds[option],
+ function(bind) {
+ // The field is currently focused so we do not want to change it.
+ if (bind == this.focused) return;
+ // Set the form field to the new value.
+ bind.setValue(newValue);
+ },
+ this
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/OtherLimitWindow.js b/deluge/ui/web/js/deluge-all/OtherLimitWindow.js
new file mode 100644
index 0000000..3e5880f
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/OtherLimitWindow.js
@@ -0,0 +1,82 @@
+/**
+ * Deluge.OtherLimitWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.OtherLimitWindow
+ * @extends Ext.Window
+ */
+Deluge.OtherLimitWindow = Ext.extend(Ext.Window, {
+ layout: 'fit',
+ width: 210,
+ height: 100,
+ constrainHeader: true,
+ closeAction: 'hide',
+
+ initComponent: function() {
+ Deluge.OtherLimitWindow.superclass.initComponent.call(this);
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ bodyStyle: 'padding: 5px',
+ layout: 'hbox',
+ layoutConfig: {
+ pack: 'start',
+ },
+ items: [
+ {
+ xtype: 'spinnerfield',
+ name: 'limit',
+ },
+ ],
+ });
+ if (this.initialConfig.unit) {
+ this.form.add({
+ border: false,
+ baseCls: 'x-plain',
+ bodyStyle: 'padding: 5px',
+ html: this.initialConfig.unit,
+ });
+ } else {
+ this.setSize(180, 100);
+ }
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('OK'), this.onOkClick, this);
+ this.afterMethod('show', this.doFocusField, this);
+ },
+
+ setValue: function(value) {
+ this.form.getForm().setValues({ limit: value });
+ },
+
+ onCancelClick: function() {
+ this.form.getForm().reset();
+ this.hide();
+ },
+
+ onOkClick: function() {
+ var config = {};
+ config[this.group] = this.form.getForm().getValues().limit;
+ deluge.client.core.set_config(config, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ this.hide();
+ },
+
+ doFocusField: function() {
+ this.form
+ .getForm()
+ .findField('limit')
+ .focus(true, 10);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Plugin.js b/deluge/ui/web/js/deluge-all/Plugin.js
new file mode 100644
index 0000000..af2cda4
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Plugin.js
@@ -0,0 +1,106 @@
+/**
+ * Deluge.Plugin.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * @class Deluge.Plugin
+ * @extends Ext.util.Observable
+ */
+Deluge.Plugin = Ext.extend(Ext.util.Observable, {
+ /**
+ * The plugins name
+ * @property name
+ * @type {String}
+ */
+ name: null,
+
+ constructor: function(config) {
+ this.isDelugePlugin = true;
+ this.addEvents({
+ /**
+ * @event enabled
+ * @param {Plugin} plugin the plugin instance
+ */
+ enabled: true,
+
+ /**
+ * @event disabled
+ * @param {Plugin} plugin the plugin instance
+ */
+ disabled: true,
+ });
+ Deluge.Plugin.superclass.constructor.call(this, config);
+ },
+
+ /**
+ * Disables the plugin, firing the "{@link #disabled}" event and
+ * then executing the plugins clean up method onDisabled.
+ */
+ disable: function() {
+ this.fireEvent('disabled', this);
+ if (this.onDisable) this.onDisable();
+ },
+
+ /**
+ * Enables the plugin, firing the "{@link #enabled}" event and
+ * then executes the plugins setup method, onEnabled.
+ */
+ enable: function() {
+ deluge.client.reloadMethods();
+ this.fireEvent('enable', this);
+ if (this.onEnable) this.onEnable();
+ },
+
+ registerTorrentStatus: function(key, header, options) {
+ options = options || {};
+ var cc = options.colCfg || {},
+ sc = options.storeCfg || {};
+ sc = Ext.apply(sc, { name: key });
+ deluge.torrents.meta.fields.push(sc);
+ deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
+
+ cc = Ext.apply(cc, {
+ header: header,
+ dataIndex: key,
+ });
+ var cols = deluge.torrents.columns.slice(0);
+ cols.push(cc);
+ deluge.torrents.colModel.setConfig(cols);
+ deluge.torrents.columns = cols;
+
+ Deluge.Keys.Grid.push(key);
+ deluge.torrents.getView().refresh(true);
+ },
+
+ deregisterTorrentStatus: function(key) {
+ var fields = [];
+ Ext.each(deluge.torrents.meta.fields, function(field) {
+ if (field.name != key) fields.push(field);
+ });
+ deluge.torrents.meta.fields = fields;
+ deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);
+
+ var cols = [];
+ Ext.each(deluge.torrents.columns, function(col) {
+ if (col.dataIndex != key) cols.push(col);
+ });
+ deluge.torrents.colModel.setConfig(cols);
+ deluge.torrents.columns = cols;
+
+ var keys = [];
+ Ext.each(Deluge.Keys.Grid, function(k) {
+ if (k == key) keys.push(k);
+ });
+ Deluge.Keys.Grid = keys;
+ deluge.torrents.getView().refresh(true);
+ },
+});
+
+Ext.ns('Deluge.plugins');
diff --git a/deluge/ui/web/js/deluge-all/RemoveWindow.js b/deluge/ui/web/js/deluge-all/RemoveWindow.js
new file mode 100644
index 0000000..a629008
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/RemoveWindow.js
@@ -0,0 +1,77 @@
+/**
+ * Deluge.RemoveWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * @class Deluge.RemoveWindow
+ * @extends Ext.Window
+ */
+Deluge.RemoveWindow = Ext.extend(Ext.Window, {
+ title: _('Remove Torrent'),
+ layout: 'fit',
+ width: 350,
+ height: 100,
+ constrainHeader: true,
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-remove-window-icon',
+ plain: true,
+
+ bodyStyle: 'padding: 5px; padding-left: 10px;',
+ html: 'Are you sure you wish to remove the torrent (s)?',
+
+ initComponent: function() {
+ Deluge.RemoveWindow.superclass.initComponent.call(this);
+ this.addButton(_('Cancel'), this.onCancel, this);
+ this.addButton(_('Remove With Data'), this.onRemoveData, this);
+ this.addButton(_('Remove Torrent'), this.onRemove, this);
+ },
+
+ remove: function(removeData) {
+ deluge.client.core.remove_torrents(this.torrentIds, removeData, {
+ success: function(result) {
+ if (result == true) {
+ console.log(
+ 'Error(s) occured when trying to delete torrent(s).'
+ );
+ }
+ this.onRemoved(this.torrentIds);
+ },
+ scope: this,
+ torrentIds: this.torrentIds,
+ });
+ },
+
+ show: function(ids) {
+ Deluge.RemoveWindow.superclass.show.call(this);
+ this.torrentIds = ids;
+ },
+
+ onCancel: function() {
+ this.hide();
+ this.torrentIds = null;
+ },
+
+ onRemove: function() {
+ this.remove(false);
+ },
+
+ onRemoveData: function() {
+ this.remove(true);
+ },
+
+ onRemoved: function(torrentIds) {
+ deluge.events.fire('torrentsRemoved', torrentIds);
+ this.hide();
+ deluge.ui.update();
+ },
+});
+
+deluge.removeWindow = new Deluge.RemoveWindow();
diff --git a/deluge/ui/web/js/deluge-all/Sidebar.js b/deluge/ui/web/js/deluge-all/Sidebar.js
new file mode 100644
index 0000000..74c3ecb
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Sidebar.js
@@ -0,0 +1,144 @@
+/**
+ * Deluge.Sidebar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// These are just so gen_gettext.py will pick up the strings
+// _('State')
+// _('Tracker Host')
+
+/**
+ * @class Deluge.Sidebar
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ */
+Deluge.Sidebar = Ext.extend(Ext.Panel, {
+ // private
+ panels: {},
+
+ // private
+ selected: null,
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'sidebar',
+ region: 'west',
+ cls: 'deluge-sidebar',
+ title: _('Filters'),
+ layout: 'accordion',
+ split: true,
+ width: 200,
+ minSize: 100,
+ collapsible: true,
+ },
+ config
+ );
+ Deluge.Sidebar.superclass.constructor.call(this, config);
+ },
+
+ // private
+ initComponent: function() {
+ Deluge.Sidebar.superclass.initComponent.call(this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ },
+
+ createFilter: function(filter, states) {
+ var panel = new Deluge.FilterPanel({
+ filter: filter,
+ });
+ panel.on('selectionchange', function(view, nodes) {
+ deluge.ui.update();
+ });
+ this.add(panel);
+
+ this.doLayout();
+ this.panels[filter] = panel;
+
+ panel.header.on('click', function(header) {
+ if (!deluge.config.sidebar_multiple_filters) {
+ deluge.ui.update();
+ }
+ if (!panel.list.getSelectionCount()) {
+ panel.list.select(0);
+ }
+ });
+ this.fireEvent('filtercreate', this, panel);
+
+ panel.updateStates(states);
+ this.fireEvent('afterfiltercreate', this, panel);
+ },
+
+ getFilter: function(filter) {
+ return this.panels[filter];
+ },
+
+ getFilterStates: function() {
+ var states = {};
+
+ if (deluge.config.sidebar_multiple_filters) {
+ // Grab the filters from each of the filter panels
+ this.items.each(function(panel) {
+ var state = panel.getState();
+ if (state == null) return;
+ states[panel.filterType] = state;
+ }, this);
+ } else {
+ var panel = this.getLayout().activeItem;
+ if (panel) {
+ var state = panel.getState();
+ if (!state == null) return;
+ states[panel.filterType] = state;
+ }
+ }
+
+ return states;
+ },
+
+ hasFilter: function(filter) {
+ return this.panels[filter] ? true : false;
+ },
+
+ // private
+ onDisconnect: function() {
+ for (var filter in this.panels) {
+ this.remove(this.panels[filter]);
+ }
+ this.panels = {};
+ this.selected = null;
+ },
+
+ onFilterSelect: function(selModel, rowIndex, record) {
+ deluge.ui.update();
+ },
+
+ update: function(filters) {
+ for (var filter in filters) {
+ var states = filters[filter];
+ if (Ext.getKeys(this.panels).indexOf(filter) > -1) {
+ this.panels[filter].updateStates(states);
+ } else {
+ this.createFilter(filter, states);
+ }
+ }
+
+ // Perform a cleanup of fitlers that are not enabled any more.
+ Ext.each(
+ Ext.keys(this.panels),
+ function(filter) {
+ if (Ext.keys(filters).indexOf(filter) == -1) {
+ // We need to remove the panel
+ this.remove(this.panels[filter]);
+ this.doLayout();
+ delete this.panels[filter];
+ }
+ },
+ this
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Statusbar.js b/deluge/ui/web/js/deluge-all/Statusbar.js
new file mode 100644
index 0000000..c2327be
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Statusbar.js
@@ -0,0 +1,362 @@
+/**
+ * Deluge.Statusbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge');
+
+Deluge.Statusbar = Ext.extend(Ext.ux.StatusBar, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'deluge-statusbar',
+ defaultIconCls: 'x-deluge-statusbar x-not-connected',
+ defaultText: _('Not Connected'),
+ },
+ config
+ );
+ Deluge.Statusbar.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.Statusbar.superclass.initComponent.call(this);
+
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ },
+
+ createButtons: function() {
+ this.buttons = this.add(
+ {
+ id: 'statusbar-connections',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-connections',
+ tooltip: _('Connections'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ text: '50',
+ value: '50',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '100',
+ value: '100',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '200',
+ value: '200',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '300',
+ value: '300',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: '500',
+ value: '500',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ {
+ text: _('Unlimited'),
+ value: '-1',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ '-',
+ {
+ text: _('Other'),
+ value: 'other',
+ group: 'max_connections_global',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Connections'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-downspeed',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-downloading',
+ tooltip: _('Download Speed'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ value: '5',
+ text: _('5 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '10',
+ text: _('10 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '30',
+ text: _('30 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '80',
+ text: _('80 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '300',
+ text: _('300 KiB/s'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ {
+ value: '-1',
+ text: _('Unlimited'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ '-',
+ {
+ value: 'other',
+ text: _('Other'),
+ group: 'max_download_speed',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Download Speed'),
+ unit: _('KiB/s'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-upspeed',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-seeding',
+ tooltip: _('Upload Speed'),
+ menu: new Deluge.StatusbarMenu({
+ items: [
+ {
+ value: '5',
+ text: _('5 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '10',
+ text: _('10 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '30',
+ text: _('30 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '80',
+ text: _('80 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '300',
+ text: _('300 KiB/s'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ {
+ value: '-1',
+ text: _('Unlimited'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ '-',
+ {
+ value: 'other',
+ text: _('Other'),
+ group: 'max_upload_speed',
+ checked: false,
+ },
+ ],
+ otherWin: {
+ title: _('Set Maximum Upload Speed'),
+ unit: _('KiB/s'),
+ },
+ }),
+ },
+ '-',
+ {
+ id: 'statusbar-traffic',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-traffic',
+ tooltip: _('Protocol Traffic Download/Upload'),
+ handler: function() {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Network');
+ },
+ },
+ '-',
+ {
+ id: 'statusbar-externalip',
+ text: ' ',
+ cls: 'x-btn-text',
+ tooltip: _('External IP Address'),
+ },
+ '-',
+ {
+ id: 'statusbar-dht',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-dht',
+ tooltip: _('DHT Nodes'),
+ },
+ '-',
+ {
+ id: 'statusbar-freespace',
+ text: ' ',
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-freespace',
+ tooltip: _('Freespace in download folder'),
+ handler: function() {
+ deluge.preferences.show();
+ deluge.preferences.selectPage('Downloads');
+ },
+ }
+ );
+ this.created = true;
+ },
+
+ onConnect: function() {
+ this.setStatus({
+ iconCls: 'x-connected',
+ text: '',
+ });
+ if (!this.created) {
+ this.createButtons();
+ } else {
+ Ext.each(this.buttons, function(item) {
+ item.show();
+ item.enable();
+ });
+ }
+ this.doLayout();
+ },
+
+ onDisconnect: function() {
+ this.clearStatus({ useDefaults: true });
+ Ext.each(this.buttons, function(item) {
+ item.hide();
+ item.disable();
+ });
+ this.doLayout();
+ },
+
+ update: function(stats) {
+ if (!stats) return;
+
+ function addSpeed(val) {
+ return val + ' KiB/s';
+ }
+
+ var updateStat = function(name, config) {
+ var item = this.items.get('statusbar-' + name);
+ if (config.limit.value > 0) {
+ var value = config.value.formatter
+ ? config.value.formatter(config.value.value, true)
+ : config.value.value;
+ var limit = config.limit.formatter
+ ? config.limit.formatter(config.limit.value, true)
+ : config.limit.value;
+ var str = String.format(config.format, value, limit);
+ } else {
+ var str = config.value.formatter
+ ? config.value.formatter(config.value.value, true)
+ : config.value.value;
+ }
+ item.setText(str);
+
+ if (!item.menu) return;
+ item.menu.setValue(config.limit.value);
+ }.createDelegate(this);
+
+ updateStat('connections', {
+ value: { value: stats.num_connections },
+ limit: { value: stats.max_num_connections },
+ format: '{0} ({1})',
+ });
+
+ updateStat('downspeed', {
+ value: {
+ value: stats.download_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.max_download,
+ formatter: addSpeed,
+ },
+ format: '{0} ({1})',
+ });
+
+ updateStat('upspeed', {
+ value: {
+ value: stats.upload_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.max_upload,
+ formatter: addSpeed,
+ },
+ format: '{0} ({1})',
+ });
+
+ updateStat('traffic', {
+ value: {
+ value: stats.download_protocol_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ limit: {
+ value: stats.upload_protocol_rate,
+ formatter: Deluge.Formatters.speed,
+ },
+ format: '{0}/{1}',
+ });
+
+ this.items.get('statusbar-dht').setText(stats.dht_nodes);
+ this.items
+ .get('statusbar-freespace')
+ .setText(
+ stats.free_space >= 0 ? fsize(stats.free_space) : _('Error')
+ );
+ this.items
+ .get('statusbar-externalip')
+ .setText(
+ String.format(
+ _('<b>IP</b> {0}'),
+ stats.external_ip ? stats.external_ip : _('n/a')
+ )
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/StatusbarMenu.js b/deluge/ui/web/js/deluge-all/StatusbarMenu.js
new file mode 100644
index 0000000..b988253
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/StatusbarMenu.js
@@ -0,0 +1,79 @@
+/**
+ * Deluge.StatusbarMenu.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge');
+
+/**
+ * Menu that handles setting the statusbar limits correctly.
+ * @class Deluge.StatusbarMenu
+ * @extends Ext.menu.Menu
+ */
+Deluge.StatusbarMenu = Ext.extend(Ext.menu.Menu, {
+ initComponent: function() {
+ Deluge.StatusbarMenu.superclass.initComponent.call(this);
+ this.otherWin = new Deluge.OtherLimitWindow(
+ this.initialConfig.otherWin || {}
+ );
+
+ this.items.each(function(item) {
+ if (item.getXType() != 'menucheckitem') return;
+ if (item.value == 'other') {
+ item.on('click', this.onOtherClicked, this);
+ } else {
+ item.on('checkchange', this.onLimitChanged, this);
+ }
+ }, this);
+ },
+
+ setValue: function(value) {
+ var beenSet = false;
+ // set the new value
+ this.value = value = value == 0 ? -1 : value;
+
+ var other = null;
+ // uncheck all items
+ this.items.each(function(item) {
+ if (item.setChecked) {
+ item.suspendEvents();
+ if (item.value == value) {
+ item.setChecked(true);
+ beenSet = true;
+ } else {
+ item.setChecked(false);
+ }
+ item.resumeEvents();
+ }
+
+ if (item.value == 'other') other = item;
+ });
+
+ if (beenSet) return;
+
+ other.suspendEvents();
+ other.setChecked(true);
+ other.resumeEvents();
+ },
+
+ onLimitChanged: function(item, checked) {
+ if (!checked || item.value == 'other') return; // We do not care about unchecked or other.
+ var config = {};
+ config[item.group] = item.value;
+ deluge.client.core.set_config(config, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ },
+
+ onOtherClicked: function(item, e) {
+ this.otherWin.group = item.group;
+ this.otherWin.setValue(this.value);
+ this.otherWin.show();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/Toolbar.js b/deluge/ui/web/js/deluge-all/Toolbar.js
new file mode 100644
index 0000000..d51818b
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/Toolbar.js
@@ -0,0 +1,206 @@
+/**
+ * Deluge.Toolbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * An extension of the <tt>Ext.Toolbar</tt> class that provides an extensible toolbar for Deluge.
+ * @class Deluge.Toolbar
+ * @extends Ext.Toolbar
+ */
+Deluge.Toolbar = Ext.extend(Ext.Toolbar, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ items: [
+ {
+ id: 'tbar-deluge-text',
+ text: _('Deluge'),
+ iconCls: 'x-deluge-main-panel',
+ handler: this.onAboutClick,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'create',
+ disabled: true,
+ hidden: true,
+ text: _('Create'),
+ iconCls: 'icon-create',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'add',
+ disabled: true,
+ text: _('Add'),
+ iconCls: 'icon-add',
+ handler: this.onTorrentAdd,
+ },
+ {
+ id: 'remove',
+ disabled: true,
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'pause',
+ disabled: true,
+ text: _('Pause'),
+ iconCls: 'icon-pause',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'resume',
+ disabled: true,
+ text: _('Resume'),
+ iconCls: 'icon-resume',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'up',
+ cls: 'x-btn-text-icon',
+ disabled: true,
+ text: _('Up'),
+ iconCls: 'icon-up',
+ handler: this.onTorrentAction,
+ },
+ {
+ id: 'down',
+ disabled: true,
+ text: _('Down'),
+ iconCls: 'icon-down',
+ handler: this.onTorrentAction,
+ },
+ new Ext.Toolbar.Separator(),
+ {
+ id: 'preferences',
+ text: _('Preferences'),
+ iconCls: 'x-deluge-preferences',
+ handler: this.onPreferencesClick,
+ scope: this,
+ },
+ {
+ id: 'connectionman',
+ text: _('Connection Manager'),
+ iconCls: 'x-deluge-connection-manager',
+ handler: this.onConnectionManagerClick,
+ scope: this,
+ },
+ '->',
+ {
+ id: 'help',
+ iconCls: 'icon-help',
+ text: _('Help'),
+ handler: this.onHelpClick,
+ scope: this,
+ },
+ {
+ id: 'logout',
+ iconCls: 'icon-logout',
+ disabled: true,
+ text: _('Logout'),
+ handler: this.onLogout,
+ scope: this,
+ },
+ ],
+ },
+ config
+ );
+ Deluge.Toolbar.superclass.constructor.call(this, config);
+ },
+
+ connectedButtons: ['add', 'remove', 'pause', 'resume', 'up', 'down'],
+
+ initComponent: function() {
+ Deluge.Toolbar.superclass.initComponent.call(this);
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('login', this.onLogin, this);
+ },
+
+ onConnect: function() {
+ Ext.each(
+ this.connectedButtons,
+ function(buttonId) {
+ this.items.get(buttonId).enable();
+ },
+ this
+ );
+ },
+
+ onDisconnect: function() {
+ Ext.each(
+ this.connectedButtons,
+ function(buttonId) {
+ this.items.get(buttonId).disable();
+ },
+ this
+ );
+ },
+
+ onLogin: function() {
+ this.items.get('logout').enable();
+ },
+
+ onLogout: function() {
+ this.items.get('logout').disable();
+ deluge.login.logout();
+ },
+
+ onConnectionManagerClick: function() {
+ deluge.connectionManager.show();
+ },
+
+ onHelpClick: function() {
+ window.open('http://dev.deluge-torrent.org/wiki/UserGuide');
+ },
+
+ onAboutClick: function() {
+ var about = new Deluge.about.AboutWindow();
+ about.show();
+ },
+
+ onPreferencesClick: function() {
+ deluge.preferences.show();
+ },
+
+ onTorrentAction: function(item) {
+ var selection = deluge.torrents.getSelections();
+ var ids = [];
+ Ext.each(selection, function(record) {
+ ids.push(record.id);
+ });
+
+ switch (item.id) {
+ case 'remove':
+ deluge.removeWindow.show(ids);
+ break;
+ case 'pause':
+ case 'resume':
+ deluge.client.core[item.id + '_torrent'](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ break;
+ case 'up':
+ case 'down':
+ deluge.client.core['queue_' + item.id](ids, {
+ success: function() {
+ deluge.ui.update();
+ },
+ });
+ break;
+ }
+ },
+
+ onTorrentAdd: function() {
+ deluge.add.show();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/TorrentGrid.js b/deluge/ui/web/js/deluge-all/TorrentGrid.js
new file mode 100644
index 0000000..b0e0c5e
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/TorrentGrid.js
@@ -0,0 +1,510 @@
+/**
+ * Deluge.TorrentGrid.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+(function() {
+ /* Renderers for the Torrent Grid */
+ function queueRenderer(value) {
+ return value == -1 ? '' : value + 1;
+ }
+ function torrentNameRenderer(value, p, r) {
+ return String.format(
+ '<div class="torrent-name x-deluge-{0}">{1}</div>',
+ r.data['state'].toLowerCase(),
+ value
+ );
+ }
+ function torrentSpeedRenderer(value) {
+ if (!value) return;
+ return fspeed(value);
+ }
+ function torrentLimitRenderer(value) {
+ if (value == -1) return '';
+ return fspeed(value * 1024.0);
+ }
+ function torrentProgressRenderer(value, p, r) {
+ value = new Number(value);
+ var progress = value;
+ var text = _(r.data['state']) + ' ' + value.toFixed(2) + '%';
+ if (this.style) {
+ var style = this.style;
+ } else {
+ var style = p.style;
+ }
+ var width = new Number(style.match(/\w+:\s*(\d+)\w+/)[1]);
+ return Deluge.progressBar(value, width - 8, text);
+ }
+ function seedsRenderer(value, p, r) {
+ if (r.data['total_seeds'] > -1) {
+ return String.format('{0} ({1})', value, r.data['total_seeds']);
+ } else {
+ return value;
+ }
+ }
+ function peersRenderer(value, p, r) {
+ if (r.data['total_peers'] > -1) {
+ return String.format('{0} ({1})', value, r.data['total_peers']);
+ } else {
+ return value;
+ }
+ }
+ function availRenderer(value, p, r) {
+ return value < 0 ? '&infin;' : parseFloat(new Number(value).toFixed(3));
+ }
+ function trackerRenderer(value, p, r) {
+ return String.format(
+ '<div style="background: url(' +
+ deluge.config.base +
+ 'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',
+ value
+ );
+ }
+
+ function etaSorter(eta) {
+ return eta * -1;
+ }
+
+ function dateOrNever(date) {
+ return date > 0.0 ? fdate(date) : _('Never');
+ }
+
+ function timeOrInf(time) {
+ return time < 0 ? '&infin;' : ftime(time);
+ }
+
+ /**
+ * Deluge.TorrentGrid Class
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.TorrentGrid
+ * @extends Ext.grid.GridPanel
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+ Deluge.TorrentGrid = Ext.extend(Ext.grid.GridPanel, {
+ // object to store contained torrent ids
+ torrents: {},
+
+ columns: [
+ {
+ id: 'queue',
+ header: '#',
+ width: 30,
+ sortable: true,
+ renderer: queueRenderer,
+ dataIndex: 'queue',
+ },
+ {
+ id: 'name',
+ header: _('Name'),
+ width: 150,
+ sortable: true,
+ renderer: torrentNameRenderer,
+ dataIndex: 'name',
+ },
+ {
+ header: _('Size'),
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_wanted',
+ },
+ {
+ header: _('Progress'),
+ width: 150,
+ sortable: true,
+ renderer: torrentProgressRenderer,
+ dataIndex: 'progress',
+ },
+ {
+ header: _('Seeds'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: seedsRenderer,
+ dataIndex: 'num_seeds',
+ },
+ {
+ header: _('Peers'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: peersRenderer,
+ dataIndex: 'num_peers',
+ },
+ {
+ header: _('Down Speed'),
+ width: 80,
+ sortable: true,
+ renderer: torrentSpeedRenderer,
+ dataIndex: 'download_payload_rate',
+ },
+ {
+ header: _('Up Speed'),
+ width: 80,
+ sortable: true,
+ renderer: torrentSpeedRenderer,
+ dataIndex: 'upload_payload_rate',
+ },
+ {
+ header: _('ETA'),
+ width: 60,
+ sortable: true,
+ renderer: timeOrInf,
+ dataIndex: 'eta',
+ },
+ {
+ header: _('Ratio'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'ratio',
+ },
+ {
+ header: _('Avail'),
+ hidden: true,
+ width: 60,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'distributed_copies',
+ },
+ {
+ header: _('Added'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fdate,
+ dataIndex: 'time_added',
+ },
+ {
+ header: _('Complete Seen'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: dateOrNever,
+ dataIndex: 'last_seen_complete',
+ },
+ {
+ header: _('Completed'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: dateOrNever,
+ dataIndex: 'completed_time',
+ },
+ {
+ header: _('Tracker'),
+ hidden: true,
+ width: 120,
+ sortable: true,
+ renderer: trackerRenderer,
+ dataIndex: 'tracker_host',
+ },
+ {
+ header: _('Download Folder'),
+ hidden: true,
+ width: 120,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'download_location',
+ },
+ {
+ header: _('Owner'),
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'owner',
+ },
+ {
+ header: _('Public'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'public',
+ },
+ {
+ header: _('Shared'),
+ hidden: true,
+ width: 80,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'shared',
+ },
+ {
+ header: _('Downloaded'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_done',
+ },
+ {
+ header: _('Uploaded'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_uploaded',
+ },
+ {
+ header: _('Remaining'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: fsize,
+ dataIndex: 'total_remaining',
+ },
+ {
+ header: _('Down Limit'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: torrentLimitRenderer,
+ dataIndex: 'max_download_speed',
+ },
+ {
+ header: _('Up Limit'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: torrentLimitRenderer,
+ dataIndex: 'max_upload_speed',
+ },
+ {
+ header: _('Seeds:Peers'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: availRenderer,
+ dataIndex: 'seeds_peers_ratio',
+ },
+ {
+ header: _('Last Transfer'),
+ hidden: true,
+ width: 75,
+ sortable: true,
+ renderer: ftime,
+ dataIndex: 'time_since_transfer',
+ },
+ ],
+
+ meta: {
+ root: 'torrents',
+ idProperty: 'id',
+ fields: [
+ {
+ name: 'queue',
+ sortType: Deluge.data.SortTypes.asQueuePosition,
+ },
+ { name: 'name', sortType: Deluge.data.SortTypes.asName },
+ { name: 'total_wanted', type: 'int' },
+ { name: 'state' },
+ { name: 'progress', type: 'float' },
+ { name: 'num_seeds', type: 'int' },
+ { name: 'total_seeds', type: 'int' },
+ { name: 'num_peers', type: 'int' },
+ { name: 'total_peers', type: 'int' },
+ { name: 'download_payload_rate', type: 'int' },
+ { name: 'upload_payload_rate', type: 'int' },
+ { name: 'eta', type: 'int', sortType: etaSorter },
+ { name: 'ratio', type: 'float' },
+ { name: 'distributed_copies', type: 'float' },
+ { name: 'time_added', type: 'int' },
+ { name: 'tracker_host' },
+ { name: 'download_location' },
+ { name: 'total_done', type: 'int' },
+ { name: 'total_uploaded', type: 'int' },
+ { name: 'total_remaining', type: 'int' },
+ { name: 'max_download_speed', type: 'int' },
+ { name: 'max_upload_speed', type: 'int' },
+ { name: 'seeds_peers_ratio', type: 'float' },
+ { name: 'time_since_transfer', type: 'int' },
+ ],
+ },
+
+ keys: [
+ {
+ key: 'a',
+ ctrl: true,
+ stopEvent: true,
+ handler: function() {
+ deluge.torrents.getSelectionModel().selectAll();
+ },
+ },
+ {
+ key: [46],
+ stopEvent: true,
+ handler: function() {
+ ids = deluge.torrents.getSelectedIds();
+ deluge.removeWindow.show(ids);
+ },
+ },
+ ],
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ id: 'torrentGrid',
+ store: new Ext.data.JsonStore(this.meta),
+ columns: this.columns,
+ keys: this.keys,
+ region: 'center',
+ cls: 'deluge-torrents',
+ stripeRows: true,
+ autoExpandColumn: 'name',
+ autoExpandMin: 150,
+ deferredRender: false,
+ autoScroll: true,
+ stateful: true,
+ view: new Ext.ux.grid.BufferView({
+ rowHeight: 26,
+ scrollDelay: false,
+ }),
+ },
+ config
+ );
+ Deluge.TorrentGrid.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.TorrentGrid.superclass.initComponent.call(this);
+ deluge.events.on('torrentsRemoved', this.onTorrentsRemoved, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+
+ this.on('rowcontextmenu', function(grid, rowIndex, e) {
+ e.stopEvent();
+ var selection = grid.getSelectionModel();
+ if (!selection.isSelected(rowIndex)) {
+ selection.selectRow(rowIndex);
+ }
+ deluge.menus.torrent.showAt(e.getPoint());
+ });
+ },
+
+ /**
+ * Returns the record representing the torrent at the specified index.
+ *
+ * @param index {int} The row index of the torrent you wish to retrieve.
+ * @return {Ext.data.Record} The record representing the torrent.
+ */
+ getTorrent: function(index) {
+ return this.getStore().getAt(index);
+ },
+
+ /**
+ * Returns the currently selected record.
+ * @ return {Array/Ext.data.Record} The record(s) representing the rows
+ */
+ getSelected: function() {
+ return this.getSelectionModel().getSelected();
+ },
+
+ /**
+ * Returns the currently selected records.
+ */
+ getSelections: function() {
+ return this.getSelectionModel().getSelections();
+ },
+
+ /**
+ * Return the currently selected torrent id.
+ * @return {String} The currently selected id.
+ */
+ getSelectedId: function() {
+ return this.getSelectionModel().getSelected().id;
+ },
+
+ /**
+ * Return the currently selected torrent ids.
+ * @return {Array} The currently selected ids.
+ */
+ getSelectedIds: function() {
+ var ids = [];
+ Ext.each(this.getSelectionModel().getSelections(), function(r) {
+ ids.push(r.id);
+ });
+ return ids;
+ },
+
+ update: function(torrents, wipe) {
+ var store = this.getStore();
+
+ // Need to perform a complete reload of the torrent grid.
+ if (wipe) {
+ store.removeAll();
+ this.torrents = {};
+ }
+
+ var newTorrents = [];
+
+ // Update and add any new torrents.
+ for (var t in torrents) {
+ var torrent = torrents[t];
+
+ if (this.torrents[t]) {
+ var record = store.getById(t);
+ record.beginEdit();
+ for (var k in torrent) {
+ if (record.get(k) != torrent[k]) {
+ record.set(k, torrent[k]);
+ }
+ }
+ record.endEdit();
+ } else {
+ var record = new Deluge.data.Torrent(torrent);
+ record.id = t;
+ this.torrents[t] = 1;
+ newTorrents.push(record);
+ }
+ }
+ store.add(newTorrents);
+
+ // Remove any torrents that should not be in the store.
+ store.each(function(record) {
+ if (!torrents[record.id]) {
+ store.remove(record);
+ delete this.torrents[record.id];
+ }
+ }, this);
+ store.commitChanges();
+
+ var sortState = store.getSortState();
+ if (!sortState) return;
+ store.sort(sortState.field, sortState.direction);
+ },
+
+ // private
+ onDisconnect: function() {
+ this.getStore().removeAll();
+ this.torrents = {};
+ },
+
+ // private
+ onTorrentsRemoved: function(torrentIds) {
+ var selModel = this.getSelectionModel();
+ Ext.each(
+ torrentIds,
+ function(torrentId) {
+ var record = this.getStore().getById(torrentId);
+ if (selModel.isSelected(record)) {
+ selModel.deselectRow(this.getStore().indexOf(record));
+ }
+ this.getStore().remove(record);
+ delete this.torrents[torrentId];
+ },
+ this
+ );
+ },
+ });
+ deluge.torrents = new Deluge.TorrentGrid();
+})();
diff --git a/deluge/ui/web/js/deluge-all/UI.js b/deluge/ui/web/js/deluge-all/UI.js
new file mode 100644
index 0000000..dec4850
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/UI.js
@@ -0,0 +1,292 @@
+/**
+ * Deluge.UI.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/** Dummy translation arrays so Torrent states are available for gettext.js and Translators.
+ *
+ * All entries in deluge.common.TORRENT_STATE should be added here.
+ *
+ * No need to import these, just simply use the `_()` function around a status variable.
+ */
+var TORRENT_STATE_TRANSLATION = [
+ _('All'),
+ _('Active'),
+ _('Allocating'),
+ _('Checking'),
+ _('Downloading'),
+ _('Seeding'),
+ _('Paused'),
+ _('Checking'),
+ _('Queued'),
+ _('Error'),
+];
+
+/**
+ * @static
+ * @class Deluge.UI
+ * The controller for the whole interface, that ties all the components
+ * together and handles the 2 second poll.
+ */
+deluge.ui = {
+ errorCount: 0,
+
+ filters: null,
+
+ /**
+ * @description Create all the interface components, the json-rpc client
+ * and set up various events that the UI will utilise.
+ */
+ initialize: function() {
+ deluge.add = new Deluge.add.AddWindow();
+ deluge.details = new Deluge.details.DetailsPanel();
+ deluge.connectionManager = new Deluge.ConnectionManager();
+ deluge.editTrackers = new Deluge.EditTrackersWindow();
+ deluge.login = new Deluge.LoginWindow();
+ deluge.preferences = new Deluge.preferences.PreferencesWindow();
+ deluge.sidebar = new Deluge.Sidebar();
+ deluge.statusbar = new Deluge.Statusbar();
+ deluge.toolbar = new Deluge.Toolbar();
+
+ this.detailsPanel = new Ext.Panel({
+ id: 'detailsPanel',
+ cls: 'detailsPanel',
+ region: 'south',
+ split: true,
+ height: 215,
+ minSize: 100,
+ collapsible: true,
+ layout: 'fit',
+ items: [deluge.details],
+ });
+
+ this.MainPanel = new Ext.Panel({
+ id: 'mainPanel',
+ iconCls: 'x-deluge-main-panel',
+ layout: 'border',
+ border: false,
+ tbar: deluge.toolbar,
+ items: [deluge.sidebar, this.detailsPanel, deluge.torrents],
+ bbar: deluge.statusbar,
+ });
+
+ this.Viewport = new Ext.Viewport({
+ layout: 'fit',
+ items: [this.MainPanel],
+ });
+
+ deluge.events.on('connect', this.onConnect, this);
+ deluge.events.on('disconnect', this.onDisconnect, this);
+ deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
+ deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
+ deluge.client = new Ext.ux.util.RpcClient({
+ url: deluge.config.base + 'json',
+ });
+
+ // enable all the already active plugins
+ for (var plugin in Deluge.pluginStore) {
+ plugin = Deluge.createPlugin(plugin);
+ plugin.enable();
+ deluge.plugins[plugin.name] = plugin;
+ }
+
+ // Initialize quicktips so all the tooltip configs start working.
+ Ext.QuickTips.init();
+
+ deluge.client.on(
+ 'connected',
+ function(e) {
+ deluge.login.show();
+ },
+ this,
+ { single: true }
+ );
+
+ this.update = this.update.createDelegate(this);
+ this.checkConnection = this.checkConnection.createDelegate(this);
+
+ this.originalTitle = document.title;
+ },
+
+ checkConnection: function() {
+ deluge.client.web.connected({
+ success: this.onConnectionSuccess,
+ failure: this.onConnectionError,
+ scope: this,
+ });
+ },
+
+ update: function() {
+ var filters = deluge.sidebar.getFilterStates();
+ this.oldFilters = this.filters;
+ this.filters = filters;
+
+ deluge.client.web.update_ui(Deluge.Keys.Grid, filters, {
+ success: this.onUpdate,
+ failure: this.onUpdateError,
+ scope: this,
+ });
+ deluge.details.update();
+ },
+
+ onConnectionError: function(error) {},
+
+ onConnectionSuccess: function(result) {
+ deluge.statusbar.setStatus({
+ iconCls: 'x-deluge-statusbar icon-ok',
+ text: _('Connection restored'),
+ });
+ clearInterval(this.checking);
+ if (!result) {
+ deluge.connectionManager.show();
+ }
+ },
+
+ onUpdateError: function(error) {
+ if (this.errorCount == 2) {
+ Ext.MessageBox.show({
+ title: _('Lost Connection'),
+ msg: _('The connection to the webserver has been lost!'),
+ buttons: Ext.MessageBox.OK,
+ icon: Ext.MessageBox.ERROR,
+ });
+ deluge.events.fire('disconnect');
+ deluge.statusbar.setStatus({
+ text: _('Lost connection to webserver'),
+ });
+ this.checking = setInterval(this.checkConnection, 2000);
+ }
+ this.errorCount++;
+ },
+
+ /**
+ * @static
+ * @private
+ * Updates the various components in the interface.
+ */
+ onUpdate: function(data) {
+ if (!data['connected']) {
+ deluge.connectionManager.disconnect(true);
+ return;
+ }
+
+ if (deluge.config.show_session_speed) {
+ document.title =
+ 'D: ' +
+ fsize_short(data['stats'].download_rate, true) +
+ ' U: ' +
+ fsize_short(data['stats'].upload_rate, true) +
+ ' - ' +
+ this.originalTitle;
+ }
+ if (Ext.areObjectsEqual(this.filters, this.oldFilters)) {
+ deluge.torrents.update(data['torrents']);
+ } else {
+ deluge.torrents.update(data['torrents'], true);
+ }
+ deluge.statusbar.update(data['stats']);
+ deluge.sidebar.update(data['filters']);
+ this.errorCount = 0;
+ },
+
+ /**
+ * @static
+ * @private
+ * Start the Deluge UI polling the server and update the interface.
+ */
+ onConnect: function() {
+ if (!this.running) {
+ this.running = setInterval(this.update, 2000);
+ this.update();
+ }
+ deluge.client.web.get_plugins({
+ success: this.onGotPlugins,
+ scope: this,
+ });
+ },
+
+ /**
+ * @static
+ * @private
+ */
+ onDisconnect: function() {
+ this.stop();
+ },
+
+ onGotPlugins: function(plugins) {
+ Ext.each(
+ plugins.enabled_plugins,
+ function(plugin) {
+ if (deluge.plugins[plugin]) return;
+ deluge.client.web.get_plugin_resources(plugin, {
+ success: this.onGotPluginResources,
+ scope: this,
+ });
+ },
+ this
+ );
+ },
+
+ onPluginEnabled: function(pluginName) {
+ if (deluge.plugins[pluginName]) {
+ deluge.plugins[pluginName].enable();
+ } else {
+ deluge.client.web.get_plugin_resources(pluginName, {
+ success: this.onGotPluginResources,
+ scope: this,
+ });
+ }
+ },
+
+ onGotPluginResources: function(resources) {
+ var scripts = Deluge.debug
+ ? resources.debug_scripts
+ : resources.scripts;
+ Ext.each(
+ scripts,
+ function(script) {
+ Ext.ux.JSLoader({
+ url: deluge.config.base + script,
+ onLoad: this.onPluginLoaded,
+ pluginName: resources.name,
+ });
+ },
+ this
+ );
+ },
+
+ onPluginDisabled: function(pluginName) {
+ if (deluge.plugins[pluginName]) deluge.plugins[pluginName].disable();
+ },
+
+ onPluginLoaded: function(options) {
+ // This could happen if the plugin has multiple scripts
+ if (!Deluge.hasPlugin(options.pluginName)) return;
+
+ // Enable the plugin
+ plugin = Deluge.createPlugin(options.pluginName);
+ plugin.enable();
+ deluge.plugins[plugin.name] = plugin;
+ },
+
+ /**
+ * @static
+ * Stop the Deluge UI polling the server and clear the interface.
+ */
+ stop: function() {
+ if (this.running) {
+ clearInterval(this.running);
+ this.running = false;
+ deluge.torrents.getStore().removeAll();
+ }
+ },
+};
+
+Ext.onReady(function(e) {
+ deluge.ui.initialize();
+});
diff --git a/deluge/ui/web/js/deluge-all/add/.order b/deluge/ui/web/js/deluge-all/add/.order
new file mode 100644
index 0000000..dbd1ab9
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/.order
@@ -0,0 +1 @@
++ Window.js
diff --git a/deluge/ui/web/js/deluge-all/add/AddWindow.js b/deluge/ui/web/js/deluge-all/add/AddWindow.js
new file mode 100644
index 0000000..89803f3
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/AddWindow.js
@@ -0,0 +1,321 @@
+/**
+ * Deluge.add.AddWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.add');
+
+// This override allows file upload buttons to contain icons
+Ext.override(Ext.ux.form.FileUploadField, {
+ onRender: function(ct, position) {
+ Ext.ux.form.FileUploadField.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+
+ this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
+ this.el.addClass('x-form-file-text');
+ this.el.dom.removeAttribute('name');
+ this.createFileInput();
+
+ var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
+ text: this.buttonText,
+ });
+ this.button = new Ext.Button(
+ Ext.apply(btnCfg, {
+ renderTo: this.wrap,
+ cls:
+ 'x-form-file-btn' +
+ (btnCfg.iconCls ? ' x-btn-text-icon' : ''),
+ })
+ );
+
+ if (this.buttonOnly) {
+ this.el.hide();
+ this.wrap.setWidth(this.button.getEl().getWidth());
+ }
+
+ this.bindListeners();
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+});
+
+Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, {
+ title: _('Add Torrents'),
+ layout: 'border',
+ width: 470,
+ height: 450,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ plain: true,
+ iconCls: 'x-deluge-add-window-icon',
+
+ initComponent: function() {
+ Deluge.add.AddWindow.superclass.initComponent.call(this);
+
+ this.addButton(_('Cancel'), this.onCancelClick, this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ function torrentRenderer(value, p, r) {
+ if (r.data['info_hash']) {
+ return String.format(
+ '<div class="x-deluge-add-torrent-name">{0}</div>',
+ value
+ );
+ } else {
+ return String.format(
+ '<div class="x-deluge-add-torrent-name-loading">{0}</div>',
+ value
+ );
+ }
+ }
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.SimpleStore({
+ fields: [
+ { name: 'info_hash', mapping: 1 },
+ { name: 'text', mapping: 2 },
+ ],
+ id: 0,
+ }),
+ columns: [
+ {
+ id: 'torrent',
+ width: 150,
+ sortable: true,
+ renderer: torrentRenderer,
+ dataIndex: 'text',
+ },
+ ],
+ stripeRows: true,
+ singleSelect: true,
+ listeners: {
+ selectionchange: {
+ fn: this.onSelect,
+ scope: this,
+ },
+ },
+ hideHeaders: true,
+ autoExpandColumn: 'torrent',
+ height: '100%',
+ autoScroll: true,
+ });
+
+ this.add({
+ region: 'center',
+ items: [this.list],
+ border: false,
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ id: 'fileUploadForm',
+ xtype: 'form',
+ layout: 'fit',
+ baseCls: 'x-plain',
+ fileUpload: true,
+ items: [
+ {
+ buttonOnly: true,
+ xtype: 'fileuploadfield',
+ id: 'torrentFile',
+ name: 'file',
+ multiple: true,
+ buttonCfg: {
+ iconCls: 'x-deluge-add-file',
+ text: _('File'),
+ },
+ listeners: {
+ scope: this,
+ fileselected: this.onFileSelected,
+ },
+ },
+ ],
+ },
+ {
+ text: _('Url'),
+ iconCls: 'icon-add-url',
+ handler: this.onUrl,
+ scope: this,
+ },
+ {
+ text: _('Infohash'),
+ iconCls: 'icon-add-magnet',
+ hidden: true,
+ disabled: true,
+ },
+ '->',
+ {
+ text: _('Remove'),
+ iconCls: 'icon-remove',
+ handler: this.onRemove,
+ scope: this,
+ },
+ ],
+ }),
+ });
+
+ this.fileUploadForm = Ext.getCmp('fileUploadForm').getForm();
+ this.optionsPanel = this.add(new Deluge.add.OptionsPanel());
+ this.on('hide', this.onHide, this);
+ this.on('show', this.onShow, this);
+ },
+
+ clear: function() {
+ this.list.getStore().removeAll();
+ this.optionsPanel.clear();
+ // Reset upload form so handler fires when a canceled file is reselected
+ this.fileUploadForm.reset();
+ },
+
+ onAddClick: function() {
+ var torrents = [];
+ if (!this.list) return;
+ this.list.getStore().each(function(r) {
+ var id = r.get('info_hash');
+ torrents.push({
+ path: this.optionsPanel.getFilename(id),
+ options: this.optionsPanel.getOptions(id),
+ });
+ }, this);
+
+ deluge.client.web.add_torrents(torrents, {
+ success: function(result) {},
+ });
+ this.clear();
+ this.hide();
+ },
+
+ onCancelClick: function() {
+ this.clear();
+ this.hide();
+ },
+
+ onFile: function() {
+ if (!this.file) this.file = new Deluge.add.FileWindow();
+ this.file.show();
+ },
+
+ onHide: function() {
+ this.optionsPanel.setActiveTab(0);
+ this.optionsPanel.files.setDisabled(true);
+ this.optionsPanel.form.setDisabled(true);
+ },
+
+ onRemove: function() {
+ if (!this.list.getSelectionCount()) return;
+ var torrent = this.list.getSelectedRecords()[0];
+ if (!torrent) return;
+ this.list.getStore().remove(torrent);
+ this.optionsPanel.clear();
+
+ if (this.torrents && this.torrents[torrent.id])
+ delete this.torrents[torrent.id];
+ },
+
+ onSelect: function(list, selections) {
+ if (selections.length) {
+ var record = this.list.getRecord(selections[0]);
+ this.optionsPanel.setTorrent(record.get('info_hash'));
+ } else {
+ this.optionsPanel.files.setDisabled(true);
+ this.optionsPanel.form.setDisabled(true);
+ }
+ },
+
+ onShow: function() {
+ if (!this.url) {
+ this.url = new Deluge.add.UrlWindow();
+ this.url.on('beforeadd', this.onTorrentBeforeAdd, this);
+ this.url.on('add', this.onTorrentAdd, this);
+ }
+
+ this.optionsPanel.form.getDefaults();
+ },
+
+ onFileSelected: function() {
+ if (this.fileUploadForm.isValid()) {
+ var torrentIds = [];
+ var files = this.fileUploadForm.findField('torrentFile').value;
+ var randomId = this.createTorrentId();
+ Array.prototype.forEach.call(
+ files,
+ function(file, i) {
+ // Append index for batch of unique torrentIds.
+ var torrentId = randomId + i.toString();
+ torrentIds.push(torrentId);
+ this.onTorrentBeforeAdd(torrentId, file.name);
+ }.bind(this)
+ );
+ this.fileUploadForm.submit({
+ url: deluge.config.base + 'upload',
+ waitMsg: _('Uploading your torrent...'),
+ success: this.onUploadSuccess,
+ scope: this,
+ torrentIds: torrentIds,
+ });
+ }
+ },
+
+ onUploadSuccess: function(fp, upload) {
+ if (!upload.result.success) {
+ this.clear();
+ return;
+ }
+
+ upload.result.files.forEach(
+ function(filename, i) {
+ deluge.client.web.get_torrent_info(filename, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: filename,
+ torrentId: upload.options.torrentIds[i],
+ });
+ }.bind(this)
+ );
+ this.fileUploadForm.reset();
+ },
+
+ onGotInfo: function(info, obj, response, request) {
+ info.filename = request.options.filename;
+ torrentId = request.options.torrentId;
+ this.onTorrentAdd(torrentId, info);
+ },
+
+ onTorrentBeforeAdd: function(torrentId, text) {
+ var store = this.list.getStore();
+ store.loadData([[torrentId, null, text]], true);
+ },
+
+ onTorrentAdd: function(torrentId, info) {
+ var r = this.list.getStore().getById(torrentId);
+ if (!info) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: _('Not a valid torrent'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ this.list.getStore().remove(r);
+ } else {
+ r.set('info_hash', info['info_hash']);
+ r.set('text', info['name']);
+ this.list.getStore().commitChanges();
+ this.optionsPanel.addTorrent(info);
+ this.list.select(r);
+ }
+ },
+
+ onUrl: function(button, event) {
+ this.url.show();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/add/FilesTab.js b/deluge/ui/web/js/deluge-all/add/FilesTab.js
new file mode 100644
index 0000000..a433ad6
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/FilesTab.js
@@ -0,0 +1,99 @@
+/**
+ * Deluge.add.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.FilesTab
+ * @extends Ext.ux.tree.TreeGrid
+ */
+Deluge.add.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
+ layout: 'fit',
+ title: _('Files'),
+
+ autoScroll: false,
+ animate: false,
+ border: false,
+ disabled: true,
+ rootVisible: false,
+
+ columns: [
+ {
+ header: _('Filename'),
+ width: 295,
+ dataIndex: 'filename',
+ },
+ {
+ header: _('Size'),
+ width: 60,
+ dataIndex: 'size',
+ tpl: new Ext.XTemplate('{size:this.fsize}', {
+ fsize: function(v) {
+ return fsize(v);
+ },
+ }),
+ },
+ {
+ header: _('Download'),
+ width: 65,
+ dataIndex: 'download',
+ tpl: new Ext.XTemplate('{download:this.format}', {
+ format: function(v) {
+ return (
+ '<div rel="chkbox" class="x-grid3-check-col' +
+ (v ? '-on' : '') +
+ '"> </div>'
+ );
+ },
+ }),
+ },
+ ],
+
+ initComponent: function() {
+ Deluge.add.FilesTab.superclass.initComponent.call(this);
+ this.on('click', this.onNodeClick, this);
+ },
+
+ clearFiles: function() {
+ var root = this.getRootNode();
+ if (!root.hasChildNodes()) return;
+ root.cascade(function(node) {
+ if (!node.parentNode || !node.getOwnerTree()) return;
+ node.remove();
+ });
+ },
+
+ setDownload: function(node, value, suppress) {
+ node.attributes.download = value;
+ node.ui.updateColumns();
+
+ if (node.isLeaf()) {
+ if (!suppress) {
+ return this.fireEvent('fileschecked', [node], value, !value);
+ }
+ } else {
+ var nodes = [node];
+ node.cascade(function(n) {
+ n.attributes.download = value;
+ n.ui.updateColumns();
+ nodes.push(n);
+ }, this);
+ if (!suppress) {
+ return this.fireEvent('fileschecked', nodes, value, !value);
+ }
+ }
+ },
+
+ onNodeClick: function(node, e) {
+ var el = new Ext.Element(e.target);
+ if (el.getAttribute('rel') == 'chkbox') {
+ this.setDownload(node, !node.attributes.download);
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/add/Infohash.js b/deluge/ui/web/js/deluge-all/add/Infohash.js
new file mode 100644
index 0000000..0105e02
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/Infohash.js
@@ -0,0 +1,10 @@
+/**
+ * Deluge.add.Infohash.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.deluge.add');
diff --git a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js
new file mode 100644
index 0000000..3dfb6f8
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js
@@ -0,0 +1,146 @@
+/**
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
+ torrents: {},
+
+ // layout options
+ region: 'south',
+ border: false,
+ activeTab: 0,
+ height: 265,
+
+ initComponent: function() {
+ Deluge.add.OptionsPanel.superclass.initComponent.call(this);
+ this.files = this.add(new Deluge.add.FilesTab());
+ this.form = this.add(new Deluge.add.OptionsTab());
+
+ this.files.on('fileschecked', this.onFilesChecked, this);
+ },
+
+ addTorrent: function(torrent) {
+ this.torrents[torrent['info_hash']] = torrent;
+ var fileIndexes = {};
+ this.walkFileTree(
+ torrent['files_tree'],
+ function(filename, type, entry, parent) {
+ if (type != 'file') return;
+ fileIndexes[entry.index] = entry.download;
+ },
+ this
+ );
+
+ var priorities = [];
+ Ext.each(Ext.keys(fileIndexes), function(index) {
+ priorities[index] = fileIndexes[index];
+ });
+
+ var oldId = this.form.optionsManager.changeId(
+ torrent['info_hash'],
+ true
+ );
+ this.form.optionsManager.setDefault('file_priorities', priorities);
+ this.form.optionsManager.changeId(oldId, true);
+ },
+
+ clear: function() {
+ this.files.clearFiles();
+ this.form.optionsManager.resetAll();
+ },
+
+ getFilename: function(torrentId) {
+ return this.torrents[torrentId]['filename'];
+ },
+
+ getOptions: function(torrentId) {
+ var oldId = this.form.optionsManager.changeId(torrentId, true);
+ var options = this.form.optionsManager.get();
+ this.form.optionsManager.changeId(oldId, true);
+ Ext.each(options['file_priorities'], function(priority, index) {
+ options['file_priorities'][index] = priority ? 1 : 0;
+ });
+ return options;
+ },
+
+ setTorrent: function(torrentId) {
+ if (!torrentId) return;
+
+ this.torrentId = torrentId;
+ this.form.optionsManager.changeId(torrentId);
+
+ this.files.clearFiles();
+ var root = this.files.getRootNode();
+ var priorities = this.form.optionsManager.get('file_priorities');
+
+ this.form.setDisabled(false);
+
+ if (this.torrents[torrentId]['files_tree']) {
+ this.walkFileTree(
+ this.torrents[torrentId]['files_tree'],
+ function(filename, type, entry, parentNode) {
+ var node = new Ext.tree.TreeNode({
+ download: entry.index ? priorities[entry.index] : true,
+ filename: filename,
+ fileindex: entry.index,
+ leaf: type != 'dir',
+ size: entry.length,
+ });
+ parentNode.appendChild(node);
+ if (type == 'dir') return node;
+ },
+ this,
+ root
+ );
+ root.firstChild.expand();
+ this.files.setDisabled(false);
+ this.files.show();
+ } else {
+ // Files tab is empty so show options tab
+ this.form.show();
+ this.files.setDisabled(true);
+ }
+ },
+
+ walkFileTree: function(files, callback, scope, parentNode) {
+ for (var filename in files.contents) {
+ var entry = files.contents[filename];
+ var type = entry.type;
+
+ if (scope) {
+ var ret = callback.apply(scope, [
+ filename,
+ type,
+ entry,
+ parentNode,
+ ]);
+ } else {
+ var ret = callback(filename, type, entry, parentNode);
+ }
+
+ if (type == 'dir') this.walkFileTree(entry, callback, scope, ret);
+ }
+ },
+
+ onFilesChecked: function(nodes, newValue, oldValue) {
+ Ext.each(
+ nodes,
+ function(node) {
+ if (node.attributes.fileindex < 0) return;
+ var priorities = this.form.optionsManager.get(
+ 'file_priorities'
+ );
+ priorities[node.attributes.fileindex] = newValue;
+ this.form.optionsManager.update('file_priorities', priorities);
+ },
+ this
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/add/OptionsTab.js b/deluge/ui/web/js/deluge-all/add/OptionsTab.js
new file mode 100644
index 0000000..e897b17
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/OptionsTab.js
@@ -0,0 +1,217 @@
+/**
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.OptionsTab
+ * @extends Ext.form.FormPanel
+ */
+Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
+ title: _('Options'),
+ height: 170,
+ border: false,
+ bodyStyle: 'padding: 5px',
+ disabled: true,
+ labelWidth: 1,
+
+ initComponent: function() {
+ Deluge.add.OptionsTab.superclass.initComponent.call(this);
+
+ this.optionsManager = new Deluge.MultiOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Download Folder'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'textfield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding: 5px 0; margin-bottom: 0;',
+ });
+ this.optionsManager.bind(
+ 'download_location',
+ fieldset.add({
+ fieldLabel: '',
+ name: 'download_location',
+ anchor: '95%',
+ labelSeparator: '',
+ })
+ );
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Move Completed Folder'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'togglefield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding: 5px 0; margin-bottom: 0;',
+ });
+ var field = fieldset.add({
+ fieldLabel: '',
+ name: 'move_completed_path',
+ anchor: '98%',
+ });
+ this.optionsManager.bind('move_completed', field.toggle);
+ this.optionsManager.bind('move_completed_path', field.input);
+
+ var panel = this.add({
+ border: false,
+ layout: 'column',
+ defaultType: 'fieldset',
+ });
+
+ fieldset = panel.add({
+ title: _('Bandwidth'),
+ border: false,
+ autoHeight: true,
+ bodyStyle: 'padding: 2px 5px',
+ labelWidth: 105,
+ width: 200,
+ defaultType: 'spinnerfield',
+ style: 'padding-right: 10px;',
+ });
+ this.optionsManager.bind(
+ 'max_download_speed',
+ fieldset.add({
+ fieldLabel: _('Max Down Speed'),
+ name: 'max_download_speed',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_upload_speed',
+ fieldset.add({
+ fieldLabel: _('Max Up Speed'),
+ name: 'max_upload_speed',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_connections',
+ fieldset.add({
+ fieldLabel: _('Max Connections'),
+ name: 'max_connections',
+ width: 60,
+ })
+ );
+ this.optionsManager.bind(
+ 'max_upload_slots',
+ fieldset.add({
+ fieldLabel: _('Max Upload Slots'),
+ name: 'max_upload_slots',
+ width: 60,
+ })
+ );
+
+ fieldset = panel.add({
+ // title: _('General'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'checkbox',
+ });
+ this.optionsManager.bind(
+ 'add_paused',
+ fieldset.add({
+ name: 'add_paused',
+ boxLabel: _('Add In Paused State'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'prioritize_first_last_pieces',
+ fieldset.add({
+ name: 'prioritize_first_last_pieces',
+ boxLabel: _('Prioritize First/Last Pieces'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'sequential_download',
+ fieldset.add({
+ name: 'sequential_download',
+ boxLabel: _('Sequential Download'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'seed_mode',
+ fieldset.add({
+ name: 'seed_mode',
+ boxLabel: _('Skip File Hash Check'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'super_seeding',
+ fieldset.add({
+ name: 'super_seeding',
+ boxLabel: _('Super Seed'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ this.optionsManager.bind(
+ 'pre_allocate_storage',
+ fieldset.add({
+ name: 'pre_allocate_storage',
+ boxLabel: _('Preallocate Disk Space'),
+ fieldLabel: '',
+ labelSeparator: '',
+ })
+ );
+ },
+
+ getDefaults: function() {
+ var keys = [
+ 'add_paused',
+ 'pre_allocate_storage',
+ 'download_location',
+ 'max_connections_per_torrent',
+ 'max_download_speed_per_torrent',
+ 'move_completed',
+ 'move_completed_path',
+ 'max_upload_slots_per_torrent',
+ 'max_upload_speed_per_torrent',
+ 'prioritize_first_last_pieces',
+ 'sequential_download',
+ ];
+
+ deluge.client.core.get_config_values(keys, {
+ success: function(config) {
+ var options = {
+ file_priorities: [],
+ add_paused: config.add_paused,
+ sequential_download: config.sequential_download,
+ pre_allocate_storage: config.pre_allocate_storage,
+ download_location: config.download_location,
+ move_completed: config.move_completed,
+ move_completed_path: config.move_completed_path,
+ max_connections: config.max_connections_per_torrent,
+ max_download_speed: config.max_download_speed_per_torrent,
+ max_upload_slots: config.max_upload_slots_per_torrent,
+ max_upload_speed: config.max_upload_speed_per_torrent,
+ prioritize_first_last_pieces:
+ config.prioritize_first_last_pieces,
+ seed_mode: false,
+ super_seeding: false,
+ };
+ this.optionsManager.options = options;
+ this.optionsManager.resetAll();
+ },
+ scope: this,
+ });
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/add/UrlWindow.js b/deluge/ui/web/js/deluge-all/add/UrlWindow.js
new file mode 100644
index 0000000..d3a9a69
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/UrlWindow.js
@@ -0,0 +1,98 @@
+/**
+ * Deluge.add.UrlWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.namespace('Deluge.add');
+Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, {
+ title: _('Add from Url'),
+ modal: true,
+ plain: true,
+ layout: 'fit',
+ width: 350,
+ height: 155,
+
+ buttonAlign: 'center',
+ closeAction: 'hide',
+ bodyStyle: 'padding: 10px 5px;',
+ iconCls: 'x-deluge-add-url-window-icon',
+
+ initComponent: function() {
+ Deluge.add.UrlWindow.superclass.initComponent.call(this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ var form = this.add({
+ xtype: 'form',
+ defaultType: 'textfield',
+ baseCls: 'x-plain',
+ labelWidth: 55,
+ });
+
+ this.urlField = form.add({
+ fieldLabel: _('Url'),
+ id: 'url',
+ name: 'url',
+ width: '97%',
+ });
+ this.urlField.on('specialkey', this.onAdd, this);
+
+ this.cookieField = form.add({
+ fieldLabel: _('Cookies'),
+ id: 'cookies',
+ name: 'cookies',
+ width: '97%',
+ });
+ this.cookieField.on('specialkey', this.onAdd, this);
+ },
+
+ onAddClick: function(field, e) {
+ if (
+ (field.id == 'url' || field.id == 'cookies') &&
+ e.getKey() != e.ENTER
+ )
+ return;
+
+ var field = this.urlField;
+ var url = field.getValue();
+ var cookies = this.cookieField.getValue();
+ var torrentId = this.createTorrentId();
+
+ if (url.indexOf('magnet:?') == 0 && url.indexOf('xt=urn:btih') > -1) {
+ deluge.client.web.get_magnet_info(url, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: url,
+ torrentId: torrentId,
+ });
+ } else {
+ deluge.client.web.download_torrent_from_url(url, cookies, {
+ success: this.onDownload,
+ scope: this,
+ torrentId: torrentId,
+ });
+ }
+
+ this.hide();
+ this.urlField.setValue('');
+ this.fireEvent('beforeadd', torrentId, url);
+ },
+
+ onDownload: function(filename, obj, resp, req) {
+ deluge.client.web.get_torrent_info(filename, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: filename,
+ torrentId: req.options.torrentId,
+ });
+ },
+
+ onGotInfo: function(info, obj, response, request) {
+ info['filename'] = request.options.filename;
+ this.fireEvent('add', request.options.torrentId, info);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/add/Window.js b/deluge/ui/web/js/deluge-all/add/Window.js
new file mode 100644
index 0000000..206b3ee
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/add/Window.js
@@ -0,0 +1,29 @@
+/**
+ * Deluge.add.Window.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.Window
+ * @extends Ext.Window
+ * Base class for an add Window
+ */
+Deluge.add.Window = Ext.extend(Ext.Window, {
+ initComponent: function() {
+ Deluge.add.Window.superclass.initComponent.call(this);
+ this.addEvents('beforeadd', 'add');
+ },
+
+ /**
+ * Create an id for the torrent before we have any info about it.
+ */
+ createTorrentId: function() {
+ return new Date().getTime().toString();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/data/.order b/deluge/ui/web/js/deluge-all/data/.order
new file mode 100644
index 0000000..f9befc4
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/data/.order
@@ -0,0 +1 @@
++ SortTypes.js
diff --git a/deluge/ui/web/js/deluge-all/data/PeerRecord.js b/deluge/ui/web/js/deluge-all/data/PeerRecord.js
new file mode 100644
index 0000000..7f33769
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/data/PeerRecord.js
@@ -0,0 +1,53 @@
+/**
+ * Deluge.data.PeerRecord.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Deluge.data.Peer record
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.Peer
+ * @extends Ext.data.Record
+ * @constructor
+ * @param {Object} data The peer data
+ */
+Deluge.data.Peer = Ext.data.Record.create([
+ {
+ name: 'country',
+ type: 'string',
+ },
+ {
+ name: 'ip',
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asIPAddress,
+ },
+ {
+ name: 'client',
+ type: 'string',
+ },
+ {
+ name: 'progress',
+ type: 'float',
+ },
+ {
+ name: 'down_speed',
+ type: 'int',
+ },
+ {
+ name: 'up_speed',
+ type: 'int',
+ },
+ {
+ name: 'seed',
+ type: 'int',
+ },
+]);
diff --git a/deluge/ui/web/js/deluge-all/data/SortTypes.js b/deluge/ui/web/js/deluge-all/data/SortTypes.js
new file mode 100644
index 0000000..199f895
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/data/SortTypes.js
@@ -0,0 +1,37 @@
+/**
+ * Deluge.data.SortTypes.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Common sort functions that can be used for data Stores.
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.SortTypes
+ * @singleton
+ */
+Deluge.data.SortTypes = {
+ // prettier-ignore
+ asIPAddress: function(value) {
+ var d = value.match(
+ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/
+ );
+ return ((+d[1] * 256 + (+d[2])) * 256 + (+d[3])) * 256 + (+d[4]);
+ },
+
+ asQueuePosition: function(value) {
+ return value > -1 ? value : Number.MAX_VALUE;
+ },
+
+ asName: function(value) {
+ return String(value).toLowerCase();
+ },
+};
diff --git a/deluge/ui/web/js/deluge-all/data/TorrentRecord.js b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js
new file mode 100644
index 0000000..e510234
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/data/TorrentRecord.js
@@ -0,0 +1,121 @@
+/**
+ * Deluge.data.TorrentRecord.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.data');
+
+/**
+ * Deluge.data.Torrent record
+ *
+ * @author Damien Churchill <damoxc@gmail.com>
+ * @version 1.3
+ *
+ * @class Deluge.data.Torrent
+ * @extends Ext.data.Record
+ * @constructor
+ * @param {Object} data The torrents data
+ */
+Deluge.data.Torrent = Ext.data.Record.create([
+ {
+ name: 'queue',
+ type: 'int',
+ },
+ {
+ name: 'name',
+ type: 'string',
+ sortType: Deluge.data.SortTypes.asName,
+ },
+ {
+ name: 'total_wanted',
+ type: 'int',
+ },
+ {
+ name: 'state',
+ type: 'string',
+ },
+ {
+ name: 'progress',
+ type: 'int',
+ },
+ {
+ name: 'num_seeds',
+ type: 'int',
+ },
+ {
+ name: 'total_seeds',
+ type: 'int',
+ },
+ {
+ name: 'num_peers',
+ type: 'int',
+ },
+ {
+ name: 'total_peers',
+ type: 'int',
+ },
+ {
+ name: 'download_payload_rate',
+ type: 'int',
+ },
+ {
+ name: 'upload_payload_rate',
+ type: 'int',
+ },
+ {
+ name: 'eta',
+ type: 'int',
+ },
+ {
+ name: 'ratio',
+ type: 'float',
+ },
+ {
+ name: 'distributed_copies',
+ type: 'float',
+ },
+ {
+ name: 'time_added',
+ type: 'int',
+ },
+ {
+ name: 'tracker_host',
+ type: 'string',
+ },
+ {
+ name: 'save_path',
+ type: 'string',
+ },
+ {
+ name: 'total_done',
+ type: 'int',
+ },
+ {
+ name: 'total_uploaded',
+ type: 'int',
+ },
+ {
+ name: 'total_remaining',
+ type: 'int',
+ },
+ {
+ name: 'max_download_speed',
+ type: 'int',
+ },
+ {
+ name: 'max_upload_speed',
+ type: 'int',
+ },
+ {
+ name: 'seeds_peers_ratio',
+ type: 'float',
+ },
+ {
+ name: 'time_since_transfer',
+ type: 'int',
+ },
+]);
diff --git a/deluge/ui/web/js/deluge-all/details/DetailsPanel.js b/deluge/ui/web/js/deluge-all/details/DetailsPanel.js
new file mode 100644
index 0000000..1c51de4
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/DetailsPanel.js
@@ -0,0 +1,81 @@
+/**
+ * Deluge.details.DetailsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.details');
+
+/**
+ * @class Deluge.details.DetailsPanel
+ */
+Deluge.details.DetailsPanel = Ext.extend(Ext.TabPanel, {
+ id: 'torrentDetails',
+ activeTab: 0,
+
+ initComponent: function() {
+ Deluge.details.DetailsPanel.superclass.initComponent.call(this);
+ this.add(new Deluge.details.StatusTab());
+ this.add(new Deluge.details.DetailsTab());
+ this.add(new Deluge.details.FilesTab());
+ this.add(new Deluge.details.PeersTab());
+ this.add(new Deluge.details.OptionsTab());
+ },
+
+ clear: function() {
+ this.items.each(function(panel) {
+ if (panel.clear) {
+ panel.clear.defer(100, panel);
+ panel.disable();
+ }
+ });
+ },
+
+ update: function(tab) {
+ var torrent = deluge.torrents.getSelected();
+ if (!torrent) {
+ this.clear();
+ return;
+ }
+
+ this.items.each(function(tab) {
+ if (tab.disabled) tab.enable();
+ });
+
+ tab = tab || this.getActiveTab();
+ if (tab.update) tab.update(torrent.id);
+ },
+
+ /* Event Handlers */
+
+ // We need to add the events in onRender since Deluge.Torrents has not been created yet.
+ onRender: function(ct, position) {
+ Deluge.details.DetailsPanel.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+ deluge.events.on('disconnect', this.clear, this);
+ deluge.torrents.on('rowclick', this.onTorrentsClick, this);
+ this.on('tabchange', this.onTabChange, this);
+
+ deluge.torrents.getSelectionModel().on(
+ 'selectionchange',
+ function(selModel) {
+ if (!selModel.hasSelection()) this.clear();
+ },
+ this
+ );
+ },
+
+ onTabChange: function(panel, tab) {
+ this.update(tab);
+ },
+
+ onTorrentsClick: function(grid, rowIndex, e) {
+ this.update();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/details/DetailsTab.js b/deluge/ui/web/js/deluge-all/details/DetailsTab.js
new file mode 100644
index 0000000..84929ae
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/DetailsTab.js
@@ -0,0 +1,98 @@
+/**
+ * Deluge.Details.Details.js
+ * The details tab displayed in the details panel.
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.DetailsTab = Ext.extend(Ext.Panel, {
+ title: _('Details'),
+
+ fields: {},
+ autoScroll: true,
+ queuedItems: {},
+
+ oldData: {},
+
+ initComponent: function() {
+ Deluge.details.DetailsTab.superclass.initComponent.call(this);
+ this.addItem('torrent_name', _('Name:'));
+ this.addItem('hash', _('Hash:'));
+ this.addItem('path', _('Download Folder:'));
+ this.addItem('size', _('Total Size:'));
+ this.addItem('files', _('Total Files:'));
+ this.addItem('comment', _('Comment:'));
+ this.addItem('status', _('Status:'));
+ this.addItem('tracker', _('Tracker:'));
+ this.addItem('creator', _('Created By:'));
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.DetailsTab.superclass.onRender.call(this, ct, position);
+ this.body.setStyle('padding', '10px');
+ this.dl = Ext.DomHelper.append(this.body, { tag: 'dl' }, true);
+
+ for (var id in this.queuedItems) {
+ this.doAddItem(id, this.queuedItems[id]);
+ }
+ },
+
+ addItem: function(id, label) {
+ if (!this.rendered) {
+ this.queuedItems[id] = label;
+ } else {
+ this.doAddItem(id, label);
+ }
+ },
+
+ // private
+ doAddItem: function(id, label) {
+ Ext.DomHelper.append(this.dl, { tag: 'dt', cls: id, html: label });
+ this.fields[id] = Ext.DomHelper.append(
+ this.dl,
+ { tag: 'dd', cls: id, html: '' },
+ true
+ );
+ },
+
+ clear: function() {
+ if (!this.fields) return;
+ for (var k in this.fields) {
+ this.fields[k].dom.innerHTML = '';
+ }
+ this.oldData = {};
+ },
+
+ update: function(torrentId) {
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Details, {
+ success: this.onRequestComplete,
+ scope: this,
+ torrentId: torrentId,
+ });
+ },
+
+ onRequestComplete: function(torrent, request, response, options) {
+ var data = {
+ torrent_name: torrent.name,
+ hash: options.options.torrentId,
+ path: torrent.download_location,
+ size: fsize(torrent.total_size),
+ files: torrent.num_files,
+ status: torrent.message,
+ tracker: torrent.tracker_host,
+ comment: torrent.comment,
+ creator: torrent.creator,
+ };
+
+ for (var field in this.fields) {
+ if (!Ext.isDefined(data[field])) continue; // This is a field we are not responsible for.
+ if (data[field] == this.oldData[field]) continue;
+ this.fields[field].dom.innerHTML = Ext.escapeHTML(data[field]);
+ }
+ this.oldData = data;
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/details/FilesTab.js b/deluge/ui/web/js/deluge-all/details/FilesTab.js
new file mode 100644
index 0000000..3a212fa
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/FilesTab.js
@@ -0,0 +1,233 @@
+/**
+ * Deluge.details.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.FilesTab = Ext.extend(Ext.ux.tree.TreeGrid, {
+ title: _('Files'),
+
+ rootVisible: false,
+
+ columns: [
+ {
+ header: _('Filename'),
+ width: 330,
+ dataIndex: 'filename',
+ },
+ {
+ header: _('Size'),
+ width: 150,
+ dataIndex: 'size',
+ tpl: new Ext.XTemplate('{size:this.fsize}', {
+ fsize: function(v) {
+ return fsize(v);
+ },
+ }),
+ },
+ {
+ xtype: 'tgrendercolumn',
+ header: _('Progress'),
+ width: 150,
+ dataIndex: 'progress',
+ renderer: function(v) {
+ var progress = v * 100;
+ return Deluge.progressBar(
+ progress,
+ this.col.width,
+ progress.toFixed(2) + '%',
+ 0
+ );
+ },
+ },
+ {
+ header: _('Priority'),
+ width: 150,
+ dataIndex: 'priority',
+ tpl: new Ext.XTemplate(
+ '<tpl if="!isNaN(priority)">' +
+ '<div class="{priority:this.getClass}">' +
+ '{priority:this.getName}' +
+ '</div></tpl>',
+ {
+ getClass: function(v) {
+ return FILE_PRIORITY_CSS[v];
+ },
+
+ getName: function(v) {
+ return _(FILE_PRIORITY[v]);
+ },
+ }
+ ),
+ },
+ ],
+
+ selModel: new Ext.tree.MultiSelectionModel(),
+
+ initComponent: function() {
+ Deluge.details.FilesTab.superclass.initComponent.call(this);
+ this.setRootNode(new Ext.tree.TreeNode({ text: _('Files') }));
+ },
+
+ clear: function() {
+ var root = this.getRootNode();
+ if (!root.hasChildNodes()) return;
+ root.cascade(function(node) {
+ var parentNode = node.parentNode;
+ if (!parentNode) return;
+ if (!parentNode.ownerTree) return;
+ parentNode.removeChild(node);
+ });
+ },
+
+ createFileTree: function(files) {
+ function walk(files, parentNode) {
+ for (var file in files.contents) {
+ var item = files.contents[file];
+ if (item.type == 'dir') {
+ walk(
+ item,
+ parentNode.appendChild(
+ new Ext.tree.TreeNode({
+ text: file,
+ filename: file,
+ size: item.size,
+ progress: item.progress,
+ priority: item.priority,
+ })
+ )
+ );
+ } else {
+ parentNode.appendChild(
+ new Ext.tree.TreeNode({
+ text: file,
+ filename: file,
+ fileIndex: item.index,
+ size: item.size,
+ progress: item.progress,
+ priority: item.priority,
+ leaf: true,
+ iconCls: 'x-deluge-file',
+ uiProvider: Ext.ux.tree.TreeGridNodeUI,
+ })
+ );
+ }
+ }
+ }
+ var root = this.getRootNode();
+ walk(files, root);
+ root.firstChild.expand();
+ },
+
+ update: function(torrentId) {
+ if (this.torrentId != torrentId) {
+ this.clear();
+ this.torrentId = torrentId;
+ }
+
+ deluge.client.web.get_torrent_files(torrentId, {
+ success: this.onRequestComplete,
+ scope: this,
+ torrentId: torrentId,
+ });
+ },
+
+ updateFileTree: function(files) {
+ function walk(files, parentNode) {
+ for (var file in files.contents) {
+ var item = files.contents[file];
+ var node = parentNode.findChild('filename', file);
+ node.attributes.size = item.size;
+ node.attributes.progress = item.progress;
+ node.attributes.priority = item.priority;
+ node.ui.updateColumns();
+ if (item.type == 'dir') {
+ walk(item, node);
+ }
+ }
+ }
+ walk(files, this.getRootNode());
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.FilesTab.superclass.onRender.call(this, ct, position);
+ deluge.menus.filePriorities.on('itemclick', this.onItemClick, this);
+ this.on('contextmenu', this.onContextMenu, this);
+ this.sorter = new Ext.tree.TreeSorter(this, {
+ folderSort: true,
+ });
+ },
+
+ onContextMenu: function(node, e) {
+ e.stopEvent();
+ var selModel = this.getSelectionModel();
+ if (selModel.getSelectedNodes().length < 2) {
+ selModel.clearSelections();
+ node.select();
+ }
+ deluge.menus.filePriorities.showAt(e.getPoint());
+ },
+
+ onItemClick: function(baseItem, e) {
+ switch (baseItem.id) {
+ case 'expandAll':
+ this.expandAll();
+ break;
+ default:
+ var indexes = {};
+ var walk = function(node) {
+ if (Ext.isEmpty(node.attributes.fileIndex)) return;
+ indexes[node.attributes.fileIndex] =
+ node.attributes.priority;
+ };
+ this.getRootNode().cascade(walk);
+
+ var nodes = this.getSelectionModel().getSelectedNodes();
+ Ext.each(nodes, function(node) {
+ if (!node.isLeaf()) {
+ var setPriorities = function(node) {
+ if (Ext.isEmpty(node.attributes.fileIndex)) return;
+ indexes[node.attributes.fileIndex] =
+ baseItem.filePriority;
+ };
+ node.cascade(setPriorities);
+ } else if (!Ext.isEmpty(node.attributes.fileIndex)) {
+ indexes[node.attributes.fileIndex] =
+ baseItem.filePriority;
+ return;
+ }
+ });
+
+ var priorities = new Array(Ext.keys(indexes).length);
+ for (var index in indexes) {
+ priorities[index] = indexes[index];
+ }
+
+ deluge.client.core.set_torrent_options(
+ [this.torrentId],
+ { file_priorities: priorities },
+ {
+ success: function() {
+ Ext.each(nodes, function(node) {
+ node.setColumnValue(3, baseItem.filePriority);
+ });
+ },
+ scope: this,
+ }
+ );
+ break;
+ }
+ },
+
+ onRequestComplete: function(files, options) {
+ if (!this.getRootNode().hasChildNodes()) {
+ this.createFileTree(files);
+ } else {
+ this.updateFileTree(files);
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/details/OptionsTab.js b/deluge/ui/web/js/deluge-all/details/OptionsTab.js
new file mode 100644
index 0000000..b11486b
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/OptionsTab.js
@@ -0,0 +1,417 @@
+/**
+ * Deluge.details.OptionsTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ autoScroll: true,
+ bodyStyle: 'padding: 5px;',
+ border: false,
+ cls: 'x-deluge-options',
+ defaults: {
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ },
+ deferredRender: false,
+ layout: 'column',
+ title: _('Options'),
+ },
+ config
+ );
+ Deluge.details.OptionsTab.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.details.OptionsTab.superclass.initComponent.call(this);
+
+ (this.fieldsets = {}), (this.fields = {});
+ this.optionsManager = new Deluge.MultiOptionsManager({
+ options: {
+ max_download_speed: -1,
+ max_upload_speed: -1,
+ max_connections: -1,
+ max_upload_slots: -1,
+ auto_managed: false,
+ stop_at_ratio: false,
+ stop_ratio: 2.0,
+ remove_at_ratio: false,
+ move_completed: false,
+ move_completed_path: '',
+ private: false,
+ prioritize_first_last: false,
+ super_seeding: false,
+ },
+ });
+
+ /*
+ * Bandwidth Options
+ */
+ this.fieldsets.bandwidth = this.add({
+ xtype: 'fieldset',
+ defaultType: 'spinnerfield',
+ bodyStyle: 'padding: 5px',
+
+ layout: 'table',
+ layoutConfig: { columns: 3 },
+ labelWidth: 150,
+
+ style: 'margin-left: 10px; margin-right: 5px; padding: 5px',
+ title: _('Bandwidth'),
+ width: 250,
+ });
+
+ /*
+ * Max Download Speed
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Download Speed:'),
+ forId: 'max_download_speed',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_download_speed = this.fieldsets.bandwidth.add({
+ id: 'max_download_speed',
+ name: 'max_download_speed',
+ width: 70,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 1,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ });
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('KiB/s'),
+ style: 'margin-left: 10px',
+ });
+
+ /*
+ * Max Upload Speed
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Upload Speed:'),
+ forId: 'max_upload_speed',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_upload_speed = this.fieldsets.bandwidth.add({
+ id: 'max_upload_speed',
+ name: 'max_upload_speed',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 1,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ });
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('KiB/s'),
+ style: 'margin-left: 10px',
+ });
+
+ /*
+ * Max Connections
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Connections:'),
+ forId: 'max_connections',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_connections = this.fieldsets.bandwidth.add({
+ id: 'max_connections',
+ name: 'max_connections',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ colspan: 2,
+ });
+
+ /*
+ * Max Upload Slots
+ */
+ this.fieldsets.bandwidth.add({
+ xtype: 'label',
+ text: _('Max Upload Slots:'),
+ forId: 'max_upload_slots',
+ cls: 'x-deluge-options-label',
+ });
+ this.fields.max_upload_slots = this.fieldsets.bandwidth.add({
+ id: 'max_upload_slots',
+ name: 'max_upload_slots',
+ width: 70,
+ value: -1,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ },
+ colspan: 2,
+ });
+
+ /*
+ * Queue Options
+ */
+ this.fieldsets.queue = this.add({
+ xtype: 'fieldset',
+ title: _('Queue'),
+ style: 'margin-left: 5px; margin-right: 5px; padding: 5px',
+ width: 210,
+
+ layout: 'table',
+ layoutConfig: { columns: 2 },
+ labelWidth: 0,
+
+ defaults: {
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+
+ this.fields.auto_managed = this.fieldsets.queue.add({
+ xtype: 'checkbox',
+ fieldLabel: '',
+ labelSeparator: '',
+ name: 'is_auto_managed',
+ boxLabel: _('Auto Managed'),
+ width: 200,
+ colspan: 2,
+ });
+
+ this.fields.stop_at_ratio = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'stop_at_ratio',
+ width: 120,
+ boxLabel: _('Stop seed at ratio:'),
+ handler: this.onStopRatioChecked,
+ scope: this,
+ });
+
+ this.fields.stop_ratio = this.fieldsets.queue.add({
+ xtype: 'spinnerfield',
+ id: 'stop_ratio',
+ name: 'stop_ratio',
+ disabled: true,
+ width: 50,
+ value: 2.0,
+ strategy: {
+ xtype: 'number',
+ minValue: -1,
+ maxValue: 99999,
+ incrementValue: 0.1,
+ alternateIncrementValue: 1,
+ decimalPrecision: 1,
+ },
+ });
+
+ this.fields.remove_at_ratio = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'remove_at_ratio',
+ ctCls: 'x-deluge-indent-checkbox',
+ bodyStyle: 'padding-left: 10px',
+ boxLabel: _('Remove at ratio'),
+ disabled: true,
+ colspan: 2,
+ });
+
+ this.fields.move_completed = this.fieldsets.queue.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ id: 'move_completed',
+ boxLabel: _('Move Completed:'),
+ colspan: 2,
+ handler: this.onMoveCompletedChecked,
+ scope: this,
+ });
+
+ this.fields.move_completed_path = this.fieldsets.queue.add({
+ xtype: 'textfield',
+ fieldLabel: '',
+ id: 'move_completed_path',
+ colspan: 3,
+ bodyStyle: 'margin-left: 20px',
+ width: 180,
+ disabled: true,
+ });
+
+ /*
+ * General Options
+ */
+ this.rightColumn = this.add({
+ border: false,
+ autoHeight: true,
+ style: 'margin-left: 5px',
+ width: 210,
+ });
+
+ this.fieldsets.general = this.rightColumn.add({
+ xtype: 'fieldset',
+ autoHeight: true,
+ defaultType: 'checkbox',
+ title: _('General'),
+ layout: 'form',
+ });
+
+ this.fields['private'] = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Private'),
+ id: 'private',
+ disabled: true,
+ });
+
+ this.fields.prioritize_first_last = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Prioritize First/Last'),
+ id: 'prioritize_first_last',
+ });
+
+ this.fields.super_seeding = this.fieldsets.general.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Super Seeding'),
+ id: 'super_seeding',
+ });
+
+ // Bind the fields so the options manager can manage them.
+ for (var id in this.fields) {
+ this.optionsManager.bind(id, this.fields[id]);
+ }
+
+ /*
+ * Buttons
+ */
+ this.buttonPanel = this.rightColumn.add({
+ layout: 'hbox',
+ xtype: 'panel',
+ border: false,
+ });
+
+ /*
+ * Edit Trackers button
+ */
+ this.buttonPanel.add({
+ id: 'edit_trackers',
+ xtype: 'button',
+ text: _('Edit Trackers'),
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-edit-trackers',
+ border: false,
+ width: 100,
+ handler: this.onEditTrackers,
+ scope: this,
+ });
+
+ /*
+ * Apply button
+ */
+ this.buttonPanel.add({
+ id: 'apply',
+ xtype: 'button',
+ text: _('Apply'),
+ style: 'margin-left: 10px;',
+ border: false,
+ width: 100,
+ handler: this.onApply,
+ scope: this,
+ });
+ },
+
+ onRender: function(ct, position) {
+ Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position);
+
+ // This is another hack I think, so keep an eye out here when upgrading.
+ this.layout = new Ext.layout.ColumnLayout();
+ this.layout.setContainer(this);
+ this.doLayout();
+ },
+
+ clear: function() {
+ if (this.torrentId == null) return;
+ this.torrentId = null;
+ this.optionsManager.changeId(null);
+ },
+
+ reset: function() {
+ if (this.torrentId) this.optionsManager.reset();
+ },
+
+ update: function(torrentId) {
+ if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds
+
+ if (!torrentId) return; // We do not care about null torrentIds.
+
+ if (this.torrentId != torrentId) {
+ this.torrentId = torrentId;
+ this.optionsManager.changeId(torrentId);
+ }
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Options, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onApply: function() {
+ var changed = this.optionsManager.getDirty();
+ deluge.client.core.set_torrent_options([this.torrentId], changed, {
+ success: function() {
+ this.optionsManager.commit();
+ },
+ scope: this,
+ });
+ },
+
+ onEditTrackers: function() {
+ deluge.editTrackers.show();
+ },
+
+ onMoveCompletedChecked: function(checkbox, checked) {
+ this.fields.move_completed_path.setDisabled(!checked);
+
+ if (!checked) return;
+ this.fields.move_completed_path.focus();
+ },
+
+ onStopRatioChecked: function(checkbox, checked) {
+ this.fields.remove_at_ratio.setDisabled(!checked);
+ this.fields.stop_ratio.setDisabled(!checked);
+ },
+
+ onRequestComplete: function(torrent, options) {
+ this.fields['private'].setValue(torrent['private']);
+ this.fields['private'].setDisabled(true);
+ delete torrent['private'];
+ torrent['auto_managed'] = torrent['is_auto_managed'];
+ torrent['prioritize_first_last_pieces'] =
+ torrent['prioritize_first_last'];
+ this.optionsManager.setDefault(torrent);
+ var stop_at_ratio = this.optionsManager.get('stop_at_ratio');
+ this.fields.remove_at_ratio.setDisabled(!stop_at_ratio);
+ this.fields.stop_ratio.setDisabled(!stop_at_ratio);
+ this.fields.move_completed_path.setDisabled(
+ !this.optionsManager.get('move_completed')
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/details/PeersTab.js b/deluge/ui/web/js/deluge-all/details/PeersTab.js
new file mode 100644
index 0000000..515e533
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/PeersTab.js
@@ -0,0 +1,166 @@
+/**
+ * Deluge.details.PeersTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+(function() {
+ function flagRenderer(value) {
+ if (!value.replace(' ', '').replace(' ', '')) {
+ return '';
+ }
+ return String.format(
+ '<img src="{0}flag/{1}" />',
+ deluge.config.base,
+ value
+ );
+ }
+ function peerAddressRenderer(value, p, record) {
+ var seed =
+ record.data['seed'] == 1024 ? 'x-deluge-seed' : 'x-deluge-peer';
+ // Modify display of IPv6 to include brackets
+ var peer_ip = value.split(':');
+ if (peer_ip.length > 2) {
+ var port = peer_ip.pop();
+ var ip = peer_ip.join(':');
+ value = '[' + ip + ']:' + port;
+ }
+ return String.format('<div class="{0}">{1}</div>', seed, value);
+ }
+ function peerProgressRenderer(value) {
+ var progress = (value * 100).toFixed(0);
+ return Deluge.progressBar(progress, this.width - 8, progress + '%');
+ }
+
+ Deluge.details.PeersTab = Ext.extend(Ext.grid.GridPanel, {
+ // fast way to figure out if we have a peer already.
+ peers: {},
+
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ title: _('Peers'),
+ cls: 'x-deluge-peers',
+ store: new Ext.data.Store({
+ reader: new Ext.data.JsonReader(
+ {
+ idProperty: 'ip',
+ root: 'peers',
+ },
+ Deluge.data.Peer
+ ),
+ }),
+ columns: [
+ {
+ header: '&nbsp;',
+ width: 30,
+ sortable: true,
+ renderer: flagRenderer,
+ dataIndex: 'country',
+ },
+ {
+ header: _('Address'),
+ width: 125,
+ sortable: true,
+ renderer: peerAddressRenderer,
+ dataIndex: 'ip',
+ },
+ {
+ header: _('Client'),
+ width: 125,
+ sortable: true,
+ renderer: fplain,
+ dataIndex: 'client',
+ },
+ {
+ header: _('Progress'),
+ width: 150,
+ sortable: true,
+ renderer: peerProgressRenderer,
+ dataIndex: 'progress',
+ },
+ {
+ header: _('Down Speed'),
+ width: 100,
+ sortable: true,
+ renderer: fspeed,
+ dataIndex: 'down_speed',
+ },
+ {
+ header: _('Up Speed'),
+ width: 100,
+ sortable: true,
+ renderer: fspeed,
+ dataIndex: 'up_speed',
+ },
+ ],
+ stripeRows: true,
+ deferredRender: false,
+ autoScroll: true,
+ },
+ config
+ );
+ Deluge.details.PeersTab.superclass.constructor.call(this, config);
+ },
+
+ clear: function() {
+ this.getStore().removeAll();
+ this.peers = {};
+ },
+
+ update: function(torrentId) {
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Peers, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onRequestComplete: function(torrent, options) {
+ if (!torrent) return;
+
+ var store = this.getStore();
+ var newPeers = [];
+ var addresses = {};
+
+ // Go through the peers updating and creating peer records
+ Ext.each(
+ torrent.peers,
+ function(peer) {
+ if (this.peers[peer.ip]) {
+ var record = store.getById(peer.ip);
+ record.beginEdit();
+ for (var k in peer) {
+ if (record.get(k) != peer[k]) {
+ record.set(k, peer[k]);
+ }
+ }
+ record.endEdit();
+ } else {
+ this.peers[peer.ip] = 1;
+ newPeers.push(new Deluge.data.Peer(peer, peer.ip));
+ }
+ addresses[peer.ip] = 1;
+ },
+ this
+ );
+ store.add(newPeers);
+
+ // Remove any peers that should not be left in the store.
+ store.each(function(record) {
+ if (!addresses[record.id]) {
+ store.remove(record);
+ delete this.peers[record.id];
+ }
+ }, this);
+ store.commitChanges();
+
+ var sortState = store.getSortState();
+ if (!sortState) return;
+ store.sort(sortState.field, sortState.direction);
+ },
+ });
+})();
diff --git a/deluge/ui/web/js/deluge-all/details/StatusTab.js b/deluge/ui/web/js/deluge-all/details/StatusTab.js
new file mode 100644
index 0000000..a8753bb
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/details/StatusTab.js
@@ -0,0 +1,155 @@
+/**
+ * Deluge.details.StatusTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.details');
+
+/**
+ * @class Deluge.details.StatusTab
+ * @extends Ext.Panel
+ */
+Deluge.details.StatusTab = Ext.extend(Ext.Panel, {
+ title: _('Status'),
+ autoScroll: true,
+
+ onRender: function(ct, position) {
+ Deluge.details.StatusTab.superclass.onRender.call(this, ct, position);
+
+ this.progressBar = this.add({
+ xtype: 'progress',
+ cls: 'x-deluge-status-progressbar',
+ });
+
+ this.status = this.add({
+ cls: 'x-deluge-status',
+ id: 'deluge-details-status',
+
+ border: false,
+ width: 1000,
+ listeners: {
+ render: {
+ fn: function(panel) {
+ panel.load({
+ url: deluge.config.base + 'render/tab_status.html',
+ text: _('Loading') + '...',
+ });
+ panel
+ .getUpdater()
+ .on('update', this.onPanelUpdate, this);
+ },
+ scope: this,
+ },
+ },
+ });
+ },
+
+ clear: function() {
+ this.progressBar.updateProgress(0, ' ');
+ for (var k in this.fields) {
+ this.fields[k].innerHTML = '';
+ }
+ },
+
+ update: function(torrentId) {
+ if (!this.fields) this.getFields();
+ deluge.client.web.get_torrent_status(torrentId, Deluge.Keys.Status, {
+ success: this.onRequestComplete,
+ scope: this,
+ });
+ },
+
+ onPanelUpdate: function(el, response) {
+ this.fields = {};
+ Ext.each(
+ Ext.query('dd', this.status.body.dom),
+ function(field) {
+ this.fields[field.className] = field;
+ },
+ this
+ );
+ },
+
+ onRequestComplete: function(status) {
+ seeds =
+ status.total_seeds > -1
+ ? status.num_seeds + ' (' + status.total_seeds + ')'
+ : status.num_seeds;
+ peers =
+ status.total_peers > -1
+ ? status.num_peers + ' (' + status.total_peers + ')'
+ : status.num_peers;
+ last_seen_complete =
+ status.last_seen_complete > 0.0
+ ? fdate(status.last_seen_complete)
+ : 'Never';
+ completed_time =
+ status.completed_time > 0.0 ? fdate(status.completed_time) : '';
+
+ var data = {
+ downloaded: fsize(status.total_done, true),
+ uploaded: fsize(status.total_uploaded, true),
+ share: status.ratio == -1 ? '&infin;' : status.ratio.toFixed(3),
+ announce: ftime(status.next_announce),
+ tracker_status: status.tracker_status,
+ downspeed: status.download_payload_rate
+ ? fspeed(status.download_payload_rate)
+ : '0.0 KiB/s',
+ upspeed: status.upload_payload_rate
+ ? fspeed(status.upload_payload_rate)
+ : '0.0 KiB/s',
+ eta: status.eta < 0 ? '&infin;' : ftime(status.eta),
+ pieces: status.num_pieces + ' (' + fsize(status.piece_length) + ')',
+ seeds: seeds,
+ peers: peers,
+ avail: status.distributed_copies.toFixed(3),
+ active_time: ftime(status.active_time),
+ seeding_time: ftime(status.seeding_time),
+ seed_rank: status.seed_rank,
+ time_added: fdate(status.time_added),
+ last_seen_complete: last_seen_complete,
+ completed_time: completed_time,
+ time_since_transfer: ftime(status.time_since_transfer),
+ };
+ data.auto_managed = _(status.is_auto_managed ? 'True' : 'False');
+
+ var translate_tracker_status = {
+ Error: _('Error'),
+ Warning: _('Warning'),
+ 'Announce OK': _('Announce OK'),
+ 'Announce Sent': _('Announce Sent'),
+ };
+ for (var key in translate_tracker_status) {
+ if (data.tracker_status.indexOf(key) != -1) {
+ data.tracker_status = data.tracker_status.replace(
+ key,
+ translate_tracker_status[key]
+ );
+ break;
+ }
+ }
+
+ data.downloaded +=
+ ' (' +
+ (status.total_payload_download
+ ? fsize(status.total_payload_download)
+ : '0.0 KiB') +
+ ')';
+ data.uploaded +=
+ ' (' +
+ (status.total_payload_upload
+ ? fsize(status.total_payload_upload)
+ : '0.0 KiB') +
+ ')';
+
+ for (var field in this.fields) {
+ this.fields[field].innerHTML = data[field];
+ }
+ var text = status.state + ' ' + status.progress.toFixed(2) + '%';
+ this.progressBar.updateProgress(status.progress / 100.0, text);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js
new file mode 100644
index 0000000..031104c
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/BandwidthPage.js
@@ -0,0 +1,203 @@
+/**
+ * Deluge.preferences.BandwidthPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Bandwidth
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Bandwidth = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Bandwidth'),
+ header: false,
+ layout: 'form',
+ labelWidth: 10,
+ },
+ config
+ );
+ Deluge.preferences.Bandwidth.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Bandwidth.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Global Bandwidth Usage'),
+ labelWidth: 200,
+ defaultType: 'spinnerfield',
+ defaults: {
+ minValue: -1,
+ maxValue: 99999,
+ },
+ style: 'margin-bottom: 0px; padding-bottom: 0px;',
+ autoHeight: true,
+ });
+ om.bind(
+ 'max_connections_global',
+ fieldset.add({
+ name: 'max_connections_global',
+ fieldLabel: _('Maximum Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_slots_global',
+ fieldset.add({
+ name: 'max_upload_slots_global',
+ fieldLabel: _('Maximum Upload Slots'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_download_speed',
+ fieldset.add({
+ name: 'max_download_speed',
+ fieldLabel: _('Maximum Download Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1.0,
+ decimalPrecision: 1,
+ })
+ );
+ om.bind(
+ 'max_upload_speed',
+ fieldset.add({
+ name: 'max_upload_speed',
+ fieldLabel: _('Maximum Upload Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1.0,
+ decimalPrecision: 1,
+ })
+ );
+ om.bind(
+ 'max_half_open_connections',
+ fieldset.add({
+ name: 'max_half_open_connections',
+ fieldLabel: _('Maximum Half-Open Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_connections_per_second',
+ fieldset.add({
+ name: 'max_connections_per_second',
+ fieldLabel: _('Maximum Connection Attempts per Second:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: '',
+ defaultType: 'checkbox',
+ style:
+ 'padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;',
+ autoHeight: true,
+ });
+ om.bind(
+ 'ignore_limits_on_local_network',
+ fieldset.add({
+ name: 'ignore_limits_on_local_network',
+ height: 22,
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Ignore limits on local network'),
+ })
+ );
+ om.bind(
+ 'rate_limit_ip_overhead',
+ fieldset.add({
+ name: 'rate_limit_ip_overhead',
+ height: 22,
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Rate limit IP overhead'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Per Torrent Bandwidth Usage'),
+ style: 'margin-bottom: 0px; padding-bottom: 0px;',
+ defaultType: 'spinnerfield',
+ labelWidth: 200,
+ defaults: {
+ minValue: -1,
+ maxValue: 99999,
+ },
+ autoHeight: true,
+ });
+ om.bind(
+ 'max_connections_per_torrent',
+ fieldset.add({
+ name: 'max_connections_per_torrent',
+ fieldLabel: _('Maximum Connections:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_slots_per_torrent',
+ fieldset.add({
+ name: 'max_upload_slots_per_torrent',
+ fieldLabel: _('Maximum Upload Slots:'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_download_speed_per_torrent',
+ fieldset.add({
+ name: 'max_download_speed_per_torrent',
+ fieldLabel: _('Maximum Download Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ om.bind(
+ 'max_upload_speed_per_torrent',
+ fieldset.add({
+ name: 'max_upload_speed_per_torrent',
+ fieldLabel: _('Maximum Upload Speed (KiB/s):'),
+ labelSeparator: '',
+ width: 80,
+ value: -1,
+ decimalPrecision: 0,
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/CachePage.js b/deluge/ui/web/js/deluge-all/preferences/CachePage.js
new file mode 100644
index 0000000..2c84c7b
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/CachePage.js
@@ -0,0 +1,61 @@
+/**
+ * Deluge.preferences.CachePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Cache
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Cache = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Cache'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Cache.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Settings'),
+ autoHeight: true,
+ labelWidth: 180,
+ defaultType: 'spinnerfield',
+ defaults: {
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 999999,
+ },
+ });
+ om.bind(
+ 'cache_size',
+ fieldset.add({
+ fieldLabel: _('Cache Size (16 KiB Blocks):'),
+ labelSeparator: '',
+ name: 'cache_size',
+ width: 60,
+ value: 512,
+ })
+ );
+ om.bind(
+ 'cache_expiry',
+ fieldset.add({
+ fieldLabel: _('Cache Expiry (seconds):'),
+ labelSeparator: '',
+ name: 'cache_expiry',
+ width: 60,
+ value: 60,
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js
new file mode 100644
index 0000000..38f5750
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/DaemonPage.js
@@ -0,0 +1,85 @@
+/**
+ * Deluge.preferences.DaemonPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Daemon
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Daemon = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Daemon'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Daemon.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Port'),
+ autoHeight: true,
+ defaultType: 'spinnerfield',
+ });
+ om.bind(
+ 'daemon_port',
+ fieldset.add({
+ fieldLabel: _('Daemon port:'),
+ labelSeparator: '',
+ name: 'daemon_port',
+ value: 58846,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Connections'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'allow_remote',
+ fieldset.add({
+ fieldLabel: '',
+ height: 22,
+ labelSeparator: '',
+ boxLabel: _('Allow Remote Connections'),
+ name: 'allow_remote',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Other'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'new_release_check',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 40,
+ boxLabel: _('Periodically check the website for new releases'),
+ id: 'new_release_check',
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js b/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js
new file mode 100644
index 0000000..bba5e47
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/DownloadsPage.js
@@ -0,0 +1,124 @@
+/**
+ * Deluge.preferences.DownloadsPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Downloads
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Downloads = Ext.extend(Ext.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Downloads'),
+ header: false,
+ layout: 'form',
+ autoHeight: true,
+ width: 320,
+ },
+ config
+ );
+ Deluge.preferences.Downloads.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Downloads.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Folders'),
+ labelWidth: 150,
+ defaultType: 'togglefield',
+ autoHeight: true,
+ labelAlign: 'top',
+ width: 300,
+ style: 'margin-bottom: 5px; padding-bottom: 5px;',
+ });
+
+ optMan.bind(
+ 'download_location',
+ fieldset.add({
+ xtype: 'textfield',
+ name: 'download_location',
+ fieldLabel: _('Download to:'),
+ labelSeparator: '',
+ width: 280,
+ })
+ );
+
+ var field = fieldset.add({
+ name: 'move_completed_path',
+ fieldLabel: _('Move completed to:'),
+ labelSeparator: '',
+ width: 280,
+ });
+ optMan.bind('move_completed', field.toggle);
+ optMan.bind('move_completed_path', field.input);
+
+ field = fieldset.add({
+ name: 'torrentfiles_location',
+ fieldLabel: _('Copy of .torrent files to:'),
+ labelSeparator: '',
+ width: 280,
+ });
+ optMan.bind('copy_torrent_file', field.toggle);
+ optMan.bind('torrentfiles_location', field.input);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Options'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ style: 'margin-bottom: 0; padding-bottom: 0;',
+ width: 280,
+ });
+ optMan.bind(
+ 'prioritize_first_last_pieces',
+ fieldset.add({
+ name: 'prioritize_first_last_pieces',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Prioritize first and last pieces of torrent'),
+ })
+ );
+ optMan.bind(
+ 'sequential_download',
+ fieldset.add({
+ name: 'sequential_download',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Sequential download'),
+ })
+ );
+ optMan.bind(
+ 'add_paused',
+ fieldset.add({
+ name: 'add_paused',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Add torrents in Paused state'),
+ })
+ );
+ optMan.bind(
+ 'pre_allocate_storage',
+ fieldset.add({
+ name: 'pre_allocate_storage',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Pre-allocate disk space'),
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js b/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js
new file mode 100644
index 0000000..af5ad51
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/EncryptionPage.js
@@ -0,0 +1,99 @@
+/**
+ * Deluge.preferences.EncryptionPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Encryption
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Encryption = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Encryption'),
+ header: false,
+
+ initComponent: function() {
+ Deluge.preferences.Encryption.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Settings'),
+ header: false,
+ autoHeight: true,
+ defaultType: 'combo',
+ width: 300,
+ });
+ optMan.bind(
+ 'enc_in_policy',
+ fieldset.add({
+ fieldLabel: _('Incoming:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Forced')],
+ [1, _('Enabled')],
+ [2, _('Disabled')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ optMan.bind(
+ 'enc_out_policy',
+ fieldset.add({
+ fieldLabel: _('Outgoing:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.SimpleStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Forced')],
+ [1, _('Enabled')],
+ [2, _('Disabled')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ optMan.bind(
+ 'enc_level',
+ fieldset.add({
+ fieldLabel: _('Level:'),
+ labelSeparator: '',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.SimpleStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('Handshake')],
+ [1, _('Full Stream')],
+ [2, _('Either')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js b/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js
new file mode 100644
index 0000000..c394664
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/InstallPluginWindow.js
@@ -0,0 +1,83 @@
+/**
+ * Deluge.preferences.InstallPluginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.InstallPluginWindow
+ * @extends Ext.Window
+ */
+Deluge.preferences.InstallPluginWindow = Ext.extend(Ext.Window, {
+ title: _('Install Plugin'),
+ layout: 'fit',
+ height: 115,
+ width: 350,
+ constrainHeader: true,
+ bodyStyle: 'padding: 10px 5px;',
+ buttonAlign: 'center',
+ closeAction: 'hide',
+ iconCls: 'x-deluge-install-plugin',
+ modal: true,
+ plain: true,
+
+ initComponent: function() {
+ Deluge.preferences.InstallPluginWindow.superclass.initComponent.call(
+ this
+ );
+ this.addButton(_('Install'), this.onInstall, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ labelWidth: 70,
+ autoHeight: true,
+ fileUpload: true,
+ items: [
+ {
+ xtype: 'fileuploadfield',
+ width: 240,
+ emptyText: _('Select an egg'),
+ fieldLabel: _('Plugin Egg'),
+ name: 'file',
+ buttonCfg: {
+ text: _('Browse...'),
+ },
+ },
+ ],
+ });
+ },
+
+ onInstall: function(field, e) {
+ this.form.getForm().submit({
+ url: deluge.config.base + 'upload',
+ waitMsg: _('Uploading your plugin...'),
+ success: this.onUploadSuccess,
+ scope: this,
+ });
+ },
+
+ onUploadPlugin: function(info, obj, response, request) {
+ this.fireEvent('pluginadded');
+ },
+
+ onUploadSuccess: function(fp, upload) {
+ this.hide();
+ if (upload.result.success) {
+ var filename = this.form.getForm().getFieldValues().file;
+ filename = filename.split('\\').slice(-1)[0];
+ var path = upload.result.files[0];
+ this.form.getForm().setValues({ file: '' });
+ deluge.client.web.upload_plugin(filename, path, {
+ success: this.onUploadPlugin,
+ scope: this,
+ filename: filename,
+ });
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js
new file mode 100644
index 0000000..f5b0290
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/InterfacePage.js
@@ -0,0 +1,304 @@
+/**
+ * Deluge.preferences.InterfacePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Interface
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Interface = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Interface'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Interface.superclass.initComponent.call(this);
+
+ var om = (this.optionsManager = new Deluge.OptionsManager());
+ this.on('show', this.onPageShow, this);
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Interface'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ defaults: {
+ height: 17,
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+ om.bind(
+ 'show_session_speed',
+ fieldset.add({
+ name: 'show_session_speed',
+ boxLabel: _('Show session speed in titlebar'),
+ })
+ );
+ om.bind(
+ 'sidebar_show_zero',
+ fieldset.add({
+ name: 'sidebar_show_zero',
+ boxLabel: _('Show filters with zero torrents'),
+ })
+ );
+ om.bind(
+ 'sidebar_multiple_filters',
+ fieldset.add({
+ name: 'sidebar_multiple_filters',
+ boxLabel: _('Allow the use of multiple filters at once'),
+ })
+ );
+
+ var languagePanel = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Language'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ this.language = om.bind(
+ 'language',
+ languagePanel.add({
+ xtype: 'combo',
+ labelSeparator: '',
+ name: 'language',
+ mode: 'local',
+ width: 200,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('WebUI Password'),
+ style: 'margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px',
+ autoHeight: true,
+ labelWidth: 100,
+ defaultType: 'textfield',
+ defaults: {
+ width: 100,
+ inputType: 'password',
+ labelStyle: 'padding-left: 5px',
+ height: 20,
+ labelSeparator: '',
+ },
+ });
+
+ this.oldPassword = fieldset.add({
+ name: 'old_password',
+ fieldLabel: _('Old:'),
+ });
+ this.newPassword = fieldset.add({
+ name: 'new_password',
+ fieldLabel: _('New:'),
+ });
+ this.confirmPassword = fieldset.add({
+ name: 'confirm_password',
+ fieldLabel: _('Confirm:'),
+ });
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Server'),
+ style: 'padding-top: 5px; margin-bottom: 0px; padding-bottom: 5px',
+ autoHeight: true,
+ labelWidth: 100,
+ defaultType: 'spinnerfield',
+ defaults: {
+ labelSeparator: '',
+ labelStyle: 'padding-left: 5px',
+ height: 20,
+ width: 80,
+ },
+ });
+ om.bind(
+ 'session_timeout',
+ fieldset.add({
+ name: 'session_timeout',
+ fieldLabel: _('Session Timeout:'),
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'port',
+ fieldset.add({
+ name: 'port',
+ fieldLabel: _('Port:'),
+ decimalPrecision: 0,
+ minValue: 1,
+ maxValue: 65535,
+ })
+ );
+ this.httpsField = om.bind(
+ 'https',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'https',
+ hideLabel: true,
+ width: 300,
+ style: 'margin-left: 5px',
+ boxLabel: _(
+ 'Enable SSL (paths relative to Deluge config folder)'
+ ),
+ })
+ );
+ this.httpsField.on('check', this.onSSLCheck, this);
+ this.pkeyField = om.bind(
+ 'pkey',
+ fieldset.add({
+ xtype: 'textfield',
+ disabled: true,
+ name: 'pkey',
+ width: 180,
+ fieldLabel: _('Private Key:'),
+ })
+ );
+ this.certField = om.bind(
+ 'cert',
+ fieldset.add({
+ xtype: 'textfield',
+ disabled: true,
+ name: 'cert',
+ width: 180,
+ fieldLabel: _('Certificate:'),
+ })
+ );
+ },
+
+ onApply: function() {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ deluge.client.web.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+
+ for (var key in deluge.config) {
+ deluge.config[key] = this.optionsManager.get(key);
+ }
+ if ('language' in changed) {
+ Ext.Msg.show({
+ title: _('WebUI Language Changed'),
+ msg: _(
+ 'Do you want to refresh the page now to use the new language?'
+ ),
+ buttons: {
+ yes: _('Refresh'),
+ no: _('Close'),
+ },
+ multiline: false,
+ fn: function(btnText) {
+ if (btnText === 'yes') location.reload();
+ },
+ icon: Ext.MessageBox.QUESTION,
+ });
+ }
+ }
+ if (this.oldPassword.getValue() || this.newPassword.getValue()) {
+ this.onPasswordChange();
+ }
+ },
+
+ onOk: function() {
+ this.onApply();
+ },
+
+ onGotConfig: function(config) {
+ this.optionsManager.set(config);
+ },
+
+ onGotLanguages: function(info, obj, response, request) {
+ info.unshift(['', _('System Default')]);
+ this.language.store.loadData(info);
+ this.language.setValue(this.optionsManager.get('language'));
+ },
+
+ onPasswordChange: function() {
+ var newPassword = this.newPassword.getValue();
+ if (newPassword != this.confirmPassword.getValue()) {
+ Ext.MessageBox.show({
+ title: _('Invalid Password'),
+ msg: _("Your passwords don't match!"),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ return;
+ }
+
+ var oldPassword = this.oldPassword.getValue();
+ deluge.client.auth.change_password(oldPassword, newPassword, {
+ success: function(result) {
+ if (!result) {
+ Ext.MessageBox.show({
+ title: _('Password'),
+ msg: _('Your old password was incorrect!'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error',
+ });
+ this.oldPassword.setValue('');
+ } else {
+ Ext.MessageBox.show({
+ title: _('Change Successful'),
+ msg: _('Your password was successfully changed!'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.INFO,
+ iconCls: 'x-deluge-icon-info',
+ });
+ this.oldPassword.setValue('');
+ this.newPassword.setValue('');
+ this.confirmPassword.setValue('');
+ }
+ },
+ scope: this,
+ });
+ },
+
+ onSetConfig: function() {
+ this.optionsManager.commit();
+ },
+
+ onPageShow: function() {
+ deluge.client.web.get_config({
+ success: this.onGotConfig,
+ scope: this,
+ });
+ deluge.client.webutils.get_languages({
+ success: this.onGotLanguages,
+ scope: this,
+ });
+ },
+
+ onSSLCheck: function(e, checked) {
+ this.pkeyField.setDisabled(!checked);
+ this.certField.setDisabled(!checked);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js b/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js
new file mode 100644
index 0000000..651ba4f
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/NetworkPage.js
@@ -0,0 +1,257 @@
+/**
+ * Deluge.preferences.NetworkPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+// custom Vtype for vtype:'IPAddress'
+Ext.apply(Ext.form.VTypes, {
+ IPAddress: function(v) {
+ return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(v);
+ },
+ IPAddressText: 'Must be a numeric IP address',
+ IPAddressMask: /[\d\.]/i,
+});
+
+/**
+ * @class Deluge.preferences.Network
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ layout: 'form',
+ title: _('Network'),
+ header: false,
+
+ initComponent: function() {
+ Deluge.preferences.Network.superclass.initComponent.call(this);
+ var optMan = deluge.preferences.getOptionsManager();
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Incoming Address'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'listen_interface',
+ fieldset.add({
+ name: 'listen_interface',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 200,
+ vtype: 'IPAddress',
+ })
+ );
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Incoming Port'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'random_port',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Use Random Port'),
+ name: 'random_port',
+ height: 22,
+ listeners: {
+ check: {
+ fn: function(e, checked) {
+ this.listenPort.setDisabled(checked);
+ },
+ scope: this,
+ },
+ },
+ })
+ );
+
+ this.listenPort = fieldset.add({
+ xtype: 'spinnerfield',
+ name: 'listen_port',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 75,
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ });
+ optMan.bind('listen_ports', this.listenPort);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Outgoing Interface'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'outgoing_interface',
+ fieldset.add({
+ name: 'outgoing_interface',
+ fieldLabel: '',
+ labelSeparator: '',
+ width: 40,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Outgoing Ports'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'random_outgoing_ports',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Use Random Ports'),
+ name: 'random_outgoing_ports',
+ height: 22,
+ listeners: {
+ check: {
+ fn: function(e, checked) {
+ this.outgoingPorts.setDisabled(checked);
+ },
+ scope: this,
+ },
+ },
+ })
+ );
+ this.outgoingPorts = fieldset.add({
+ xtype: 'spinnergroup',
+ name: 'outgoing_ports',
+ fieldLabel: '',
+ labelSeparator: '',
+ colCfg: {
+ labelWidth: 40,
+ style: 'margin-right: 10px;',
+ },
+ items: [
+ {
+ fieldLabel: _('From:'),
+ labelSeparator: '',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ },
+ {
+ fieldLabel: _('To:'),
+ labelSeparator: '',
+ strategy: {
+ xtype: 'number',
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ },
+ },
+ ],
+ });
+ optMan.bind('outgoing_ports', this.outgoingPorts);
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Network Extras'),
+ autoHeight: true,
+ layout: 'table',
+ layoutConfig: {
+ columns: 3,
+ },
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'upnp',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('UPnP'),
+ name: 'upnp',
+ })
+ );
+ optMan.bind(
+ 'natpmp',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('NAT-PMP'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'natpmp',
+ })
+ );
+ optMan.bind(
+ 'utpex',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('Peer Exchange'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'utpex',
+ })
+ );
+ optMan.bind(
+ 'lsd',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('LSD'),
+ name: 'lsd',
+ })
+ );
+ optMan.bind(
+ 'dht',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ boxLabel: _('DHT'),
+ ctCls: 'x-deluge-indent-checkbox',
+ name: 'dht',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Type Of Service'),
+ style: 'margin-bottom: 5px; padding-bottom: 0px;',
+ bodyStyle: 'margin: 0px; padding: 0px',
+ autoHeight: true,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'peer_tos',
+ fieldset.add({
+ name: 'peer_tos',
+ fieldLabel: _('Peer TOS Byte:'),
+ labelSeparator: '',
+ width: 40,
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/OtherPage.js b/deluge/ui/web/js/deluge-all/preferences/OtherPage.js
new file mode 100644
index 0000000..1538203
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/OtherPage.js
@@ -0,0 +1,100 @@
+/**
+ * Deluge.preferences.OtherPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Other
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Other = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Other'),
+ header: false,
+ layout: 'form',
+ },
+ config
+ );
+ Deluge.preferences.Other.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Other.superclass.initComponent.call(this);
+
+ var optMan = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Updates'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ optMan.bind(
+ 'new_release_check',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ name: 'new_release_check',
+ boxLabel: _('Be alerted about new releases'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('System Information'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ fieldset.add({
+ xtype: 'panel',
+ border: false,
+ bodyCfg: {
+ html: _(
+ 'Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.'
+ ),
+ },
+ });
+ optMan.bind(
+ 'send_info',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Yes, please send anonymous statistics'),
+ name: 'send_info',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('GeoIP Database'),
+ autoHeight: true,
+ labelWidth: 80,
+ defaultType: 'textfield',
+ });
+ optMan.bind(
+ 'geoip_db_location',
+ fieldset.add({
+ name: 'geoip_db_location',
+ fieldLabel: _('Path:'),
+ labelSeparator: '',
+ width: 200,
+ })
+ );
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js b/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js
new file mode 100644
index 0000000..e22fc7f
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/PluginsPage.js
@@ -0,0 +1,277 @@
+/**
+ * Deluge.preferences.PluginsPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Plugins
+ * @extends Ext.Panel
+ */
+Deluge.preferences.Plugins = Ext.extend(Ext.Panel, {
+ layout: 'border',
+ title: _('Plugins'),
+ header: false,
+ border: false,
+ cls: 'x-deluge-plugins',
+
+ pluginTemplate: new Ext.Template(
+ '<dl class="singleline">' +
+ '<dt>' +
+ _('Author:') +
+ '</dt><dd>{author}</dd>' +
+ '<dt>' +
+ _('Version:') +
+ '</dt><dd>{version}</dd>' +
+ '<dt>' +
+ _('Author Email:') +
+ '</dt><dd>{email}</dd>' +
+ '<dt>' +
+ _('Homepage:') +
+ '</dt><dd>{homepage}</dd>' +
+ '<dt>' +
+ _('Details:') +
+ '</dt><dd style="white-space:normal">{details}</dd>' +
+ '</dl>'
+ ),
+
+ initComponent: function() {
+ Deluge.preferences.Plugins.superclass.initComponent.call(this);
+ this.defaultValues = {
+ version: '',
+ email: '',
+ homepage: '',
+ details: '',
+ };
+ this.pluginTemplate.compile();
+
+ var checkboxRenderer = function(v, p, record) {
+ p.css += ' x-grid3-check-col-td';
+ return (
+ '<div class="x-grid3-check-col' + (v ? '-on' : '') + '"> </div>'
+ );
+ };
+
+ this.list = this.add({
+ xtype: 'listview',
+ store: new Ext.data.ArrayStore({
+ fields: [
+ { name: 'enabled', mapping: 0 },
+ { name: 'plugin', mapping: 1, sortType: 'asUCString' },
+ ],
+ }),
+ columns: [
+ {
+ id: 'enabled',
+ header: _('Enabled'),
+ width: 0.2,
+ sortable: true,
+ tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', {
+ getCheckbox: function(v) {
+ return (
+ '<div class="x-grid3-check-col' +
+ (v ? '-on' : '') +
+ '" rel="chkbox"> </div>'
+ );
+ },
+ }),
+ dataIndex: 'enabled',
+ },
+ {
+ id: 'plugin',
+ header: _('Plugin'),
+ width: 0.8,
+ sortable: true,
+ dataIndex: 'plugin',
+ },
+ ],
+ singleSelect: true,
+ autoExpandColumn: 'plugin',
+ listeners: {
+ selectionchange: { fn: this.onPluginSelect, scope: this },
+ },
+ });
+
+ this.panel = this.add({
+ region: 'center',
+ autoScroll: true,
+ items: [this.list],
+ bbar: new Ext.Toolbar({
+ items: [
+ {
+ cls: 'x-btn-text-icon',
+ iconCls: 'x-deluge-install-plugin',
+ text: _('Install'),
+ handler: this.onInstallPluginWindow,
+ scope: this,
+ },
+ '->',
+ {
+ cls: 'x-btn-text-icon',
+ text: _('Find More'),
+ iconCls: 'x-deluge-find-more',
+ handler: this.onFindMorePlugins,
+ scope: this,
+ },
+ ],
+ }),
+ });
+
+ var pp = (this.pluginInfo = this.add({
+ xtype: 'panel',
+ border: false,
+ height: 100,
+ region: 'south',
+ padding: '5',
+ autoScroll: true,
+ bodyCfg: {
+ style: 'white-space: nowrap',
+ },
+ }));
+
+ this.pluginInfo.on('render', this.onPluginInfoRender, this);
+ this.list.on('click', this.onNodeClick, this);
+ deluge.preferences.on('show', this.onPreferencesShow, this);
+ deluge.events.on('PluginDisabledEvent', this.onPluginDisabled, this);
+ deluge.events.on('PluginEnabledEvent', this.onPluginEnabled, this);
+ },
+
+ disablePlugin: function(plugin) {
+ deluge.client.core.disable_plugin(plugin);
+ },
+
+ enablePlugin: function(plugin) {
+ deluge.client.core.enable_plugin(plugin);
+ },
+
+ setInfo: function(plugin) {
+ if (!this.pluginInfo.rendered) return;
+ var values = plugin || this.defaultValues;
+ this.pluginInfo.body.dom.innerHTML = this.pluginTemplate.apply(values);
+ },
+
+ updatePlugins: function() {
+ var onGotAvailablePlugins = function(plugins) {
+ this.availablePlugins = plugins.sort(function(a, b) {
+ return a.toLowerCase().localeCompare(b.toLowerCase());
+ });
+
+ deluge.client.core.get_enabled_plugins({
+ success: onGotEnabledPlugins,
+ scope: this,
+ });
+ };
+
+ var onGotEnabledPlugins = function(plugins) {
+ this.enabledPlugins = plugins;
+ this.onGotPlugins();
+ };
+
+ deluge.client.core.get_available_plugins({
+ success: onGotAvailablePlugins,
+ scope: this,
+ });
+ },
+
+ updatePluginsGrid: function() {
+ var plugins = [];
+ Ext.each(
+ this.availablePlugins,
+ function(plugin) {
+ if (this.enabledPlugins.indexOf(plugin) > -1) {
+ plugins.push([true, plugin]);
+ } else {
+ plugins.push([false, plugin]);
+ }
+ },
+ this
+ );
+ this.list.getStore().loadData(plugins);
+ },
+
+ onNodeClick: function(dv, index, node, e) {
+ var el = new Ext.Element(e.target);
+ if (el.getAttribute('rel') != 'chkbox') return;
+
+ var r = dv.getStore().getAt(index);
+ if (r.get('plugin') == 'WebUi') return;
+ r.set('enabled', !r.get('enabled'));
+ r.commit();
+ if (r.get('enabled')) {
+ this.enablePlugin(r.get('plugin'));
+ } else {
+ this.disablePlugin(r.get('plugin'));
+ }
+ },
+
+ onFindMorePlugins: function() {
+ window.open('http://dev.deluge-torrent.org/wiki/Plugins');
+ },
+
+ onGotPlugins: function() {
+ this.setInfo();
+ this.updatePluginsGrid();
+ },
+
+ onGotPluginInfo: function(info) {
+ var values = {
+ author: info['Author'],
+ version: info['Version'],
+ email: info['Author-email'],
+ homepage: info['Home-page'],
+ details: info['Description'],
+ };
+ this.setInfo(values);
+ delete info;
+ },
+
+ onInstallPluginWindow: function() {
+ if (!this.installWindow) {
+ this.installWindow = new Deluge.preferences.InstallPluginWindow();
+ this.installWindow.on('pluginadded', this.onPluginInstall, this);
+ }
+ this.installWindow.show();
+ },
+
+ onPluginEnabled: function(pluginName) {
+ var index = this.list.getStore().find('plugin', pluginName);
+ if (index == -1) return;
+ var plugin = this.list.getStore().getAt(index);
+ plugin.set('enabled', true);
+ plugin.commit();
+ },
+
+ onPluginDisabled: function(pluginName) {
+ var index = this.list.getStore().find('plugin', pluginName);
+ if (index == -1) return;
+ var plugin = this.list.getStore().getAt(index);
+ plugin.set('enabled', false);
+ plugin.commit();
+ },
+
+ onPluginInstall: function() {
+ this.updatePlugins();
+ },
+
+ onPluginSelect: function(dv, selections) {
+ if (selections.length == 0) return;
+ var r = dv.getRecords(selections)[0];
+ deluge.client.web.get_plugin_info(r.get('plugin'), {
+ success: this.onGotPluginInfo,
+ scope: this,
+ });
+ },
+
+ onPreferencesShow: function() {
+ this.updatePlugins();
+ },
+
+ onPluginInfoRender: function(ct, position) {
+ this.setInfo();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js b/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js
new file mode 100644
index 0000000..1bc98a8
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/PreferencesWindow.js
@@ -0,0 +1,246 @@
+/**
+ * Deluge.preferences.PreferencesWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+PreferencesRecord = Ext.data.Record.create([{ name: 'name', type: 'string' }]);
+
+/**
+ * @class Deluge.preferences.PreferencesWindow
+ * @extends Ext.Window
+ */
+Deluge.preferences.PreferencesWindow = Ext.extend(Ext.Window, {
+ /**
+ * @property {String} currentPage The currently selected page.
+ */
+ currentPage: null,
+
+ title: _('Preferences'),
+ layout: 'border',
+ width: 485,
+ height: 500,
+ border: false,
+ constrainHeader: true,
+ buttonAlign: 'right',
+ closeAction: 'hide',
+ closable: true,
+ iconCls: 'x-deluge-preferences',
+ plain: true,
+ resizable: false,
+
+ pages: {},
+
+ initComponent: function() {
+ Deluge.preferences.PreferencesWindow.superclass.initComponent.call(
+ this
+ );
+
+ this.list = new Ext.list.ListView({
+ store: new Ext.data.Store(),
+ columns: [
+ {
+ id: 'name',
+ renderer: fplain,
+ dataIndex: 'name',
+ },
+ ],
+ singleSelect: true,
+ listeners: {
+ selectionchange: {
+ fn: this.onPageSelect,
+ scope: this,
+ },
+ },
+ hideHeaders: true,
+ autoExpandColumn: 'name',
+ deferredRender: false,
+ autoScroll: true,
+ collapsible: true,
+ });
+ this.add({
+ region: 'west',
+ items: [this.list],
+ width: 120,
+ margins: '0 5 0 0',
+ cmargins: '0 5 0 0',
+ });
+
+ this.configPanel = this.add({
+ type: 'container',
+ autoDestroy: false,
+ region: 'center',
+ layout: 'card',
+ layoutConfig: {
+ deferredRender: true,
+ },
+ autoScroll: true,
+ width: 300,
+ });
+
+ this.addButton(_('Close'), this.onClose, this);
+ this.addButton(_('Apply'), this.onApply, this);
+ this.addButton(_('OK'), this.onOk, this);
+
+ this.optionsManager = new Deluge.OptionsManager();
+ this.on('afterrender', this.onAfterRender, this);
+ this.on('show', this.onShow, this);
+
+ this.initPages();
+ },
+
+ initPages: function() {
+ deluge.preferences = this;
+ this.addPage(new Deluge.preferences.Downloads());
+ this.addPage(new Deluge.preferences.Network());
+ this.addPage(new Deluge.preferences.Encryption());
+ this.addPage(new Deluge.preferences.Bandwidth());
+ this.addPage(new Deluge.preferences.Interface());
+ this.addPage(new Deluge.preferences.Other());
+ this.addPage(new Deluge.preferences.Daemon());
+ this.addPage(new Deluge.preferences.Queue());
+ this.addPage(new Deluge.preferences.Proxy());
+ this.addPage(new Deluge.preferences.Cache());
+ this.addPage(new Deluge.preferences.Plugins());
+ },
+
+ onApply: function(e) {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ // Workaround for only displaying single listen port but still pass array to core.
+ if ('listen_ports' in changed) {
+ changed.listen_ports = [
+ changed.listen_ports,
+ changed.listen_ports,
+ ];
+ }
+ deluge.client.core.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+ }
+
+ for (var page in this.pages) {
+ if (this.pages[page].onApply) this.pages[page].onApply();
+ }
+ },
+
+ /**
+ * Return the options manager for the preferences window.
+ * @returns {Deluge.OptionsManager} the options manager
+ */
+ getOptionsManager: function() {
+ return this.optionsManager;
+ },
+
+ /**
+ * Adds a page to the preferences window.
+ * @param {Mixed} page
+ */
+ addPage: function(page) {
+ var store = this.list.getStore();
+ var name = page.title;
+ store.add([new PreferencesRecord({ name: name })]);
+ page['bodyStyle'] = 'padding: 5px';
+ page.preferences = this;
+ this.pages[name] = this.configPanel.add(page);
+ this.pages[name].index = -1;
+ return this.pages[name];
+ },
+
+ /**
+ * Removes a preferences page from the window.
+ * @param {mixed} name
+ */
+ removePage: function(page) {
+ var name = page.title;
+ var store = this.list.getStore();
+ store.removeAt(store.find('name', name));
+ this.configPanel.remove(page);
+ delete this.pages[page.title];
+ },
+
+ /**
+ * Select which preferences page is displayed.
+ * @param {String} page The page name to change to
+ */
+ selectPage: function(page) {
+ if (this.pages[page].index < 0) {
+ this.pages[page].index = this.configPanel.items.indexOf(
+ this.pages[page]
+ );
+ }
+ this.list.select(this.pages[page].index);
+ },
+
+ // private
+ doSelectPage: function(page) {
+ if (this.pages[page].index < 0) {
+ this.pages[page].index = this.configPanel.items.indexOf(
+ this.pages[page]
+ );
+ }
+ this.configPanel.getLayout().setActiveItem(this.pages[page].index);
+ this.currentPage = page;
+ },
+
+ // private
+ onGotConfig: function(config) {
+ this.getOptionsManager().set(config);
+ },
+
+ // private
+ onPageSelect: function(list, selections) {
+ var r = list.getRecord(selections[0]);
+ this.doSelectPage(r.get('name'));
+ },
+
+ // private
+ onSetConfig: function() {
+ this.getOptionsManager().commit();
+ },
+
+ // private
+ onAfterRender: function() {
+ if (!this.list.getSelectionCount()) {
+ this.list.select(0);
+ }
+ this.configPanel.getLayout().setActiveItem(0);
+ },
+
+ // private
+ onShow: function() {
+ if (!deluge.client.core) return;
+ deluge.client.core.get_config({
+ success: this.onGotConfig,
+ scope: this,
+ });
+ },
+
+ // private
+ onClose: function() {
+ this.hide();
+ },
+
+ // private
+ onOk: function() {
+ var changed = this.optionsManager.getDirty();
+ if (!Ext.isObjectEmpty(changed)) {
+ deluge.client.core.set_config(changed, {
+ success: this.onSetConfig,
+ scope: this,
+ });
+ }
+
+ for (var page in this.pages) {
+ if (this.pages[page].onOk) this.pages[page].onOk();
+ }
+
+ this.hide();
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyField.js b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
new file mode 100644
index 0000000..6d500ba
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/ProxyField.js
@@ -0,0 +1,225 @@
+/**
+ * Deluge.preferences.ProxyField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.ProxyField
+ * @extends Ext.form.FieldSet
+ */
+Deluge.preferences.ProxyField = Ext.extend(Ext.form.FieldSet, {
+ border: false,
+ autoHeight: true,
+ labelWidth: 70,
+
+ initComponent: function() {
+ Deluge.preferences.ProxyField.superclass.initComponent.call(this);
+ this.proxyType = this.add({
+ xtype: 'combo',
+ fieldLabel: _('Type:'),
+ labelSeparator: '',
+ name: 'proxytype',
+ mode: 'local',
+ width: 150,
+ store: new Ext.data.ArrayStore({
+ fields: ['id', 'text'],
+ data: [
+ [0, _('None')],
+ [1, _('Socks4')],
+ [2, _('Socks5')],
+ [3, _('Socks5 Auth')],
+ [4, _('HTTP')],
+ [5, _('HTTP Auth')],
+ [6, _('I2P')],
+ ],
+ }),
+ editable: false,
+ triggerAction: 'all',
+ valueField: 'id',
+ displayField: 'text',
+ });
+ this.proxyType.on('change', this.onFieldChange, this);
+ this.proxyType.on('select', this.onTypeSelect, this);
+
+ this.hostname = this.add({
+ xtype: 'textfield',
+ name: 'hostname',
+ fieldLabel: _('Host:'),
+ labelSeparator: '',
+ width: 220,
+ });
+ this.hostname.on('change', this.onFieldChange, this);
+
+ this.port = this.add({
+ xtype: 'spinnerfield',
+ name: 'port',
+ fieldLabel: _('Port:'),
+ labelSeparator: '',
+ width: 80,
+ decimalPrecision: 0,
+ minValue: 0,
+ maxValue: 65535,
+ });
+ this.port.on('change', this.onFieldChange, this);
+
+ this.username = this.add({
+ xtype: 'textfield',
+ name: 'username',
+ fieldLabel: _('Username:'),
+ labelSeparator: '',
+ width: 220,
+ });
+ this.username.on('change', this.onFieldChange, this);
+
+ this.password = this.add({
+ xtype: 'textfield',
+ name: 'password',
+ fieldLabel: _('Password:'),
+ labelSeparator: '',
+ inputType: 'password',
+ width: 220,
+ });
+ this.password.on('change', this.onFieldChange, this);
+
+ this.proxy_host_resolve = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_host_resolve',
+ fieldLabel: '',
+ boxLabel: _('Proxy Hostnames'),
+ width: 220,
+ });
+ this.proxy_host_resolve.on('change', this.onFieldChange, this);
+
+ this.proxy_peer_conn = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_peer_conn',
+ fieldLabel: '',
+ boxLabel: _('Proxy Peers'),
+ width: 220,
+ });
+ this.proxy_peer_conn.on('change', this.onFieldChange, this);
+
+ this.proxy_tracker_conn = this.add({
+ xtype: 'checkbox',
+ name: 'proxy_tracker_conn',
+ fieldLabel: '',
+ boxLabel: _('Proxy Trackers'),
+ width: 220,
+ });
+ this.proxy_tracker_conn.on('change', this.onFieldChange, this);
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Force Proxy'),
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ style: 'padding-left: 0px; margin-top: 10px',
+ });
+
+ this.force_proxy = fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 20,
+ name: 'force_proxy',
+ boxLabel: _('Force Use of Proxy'),
+ });
+ this.force_proxy.on('change', this.onFieldChange, this);
+
+ this.anonymous_mode = fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 20,
+ name: 'anonymous_mode',
+ boxLabel: _('Hide Client Identity'),
+ });
+ this.anonymous_mode.on('change', this.onFieldChange, this);
+
+ this.setting = false;
+ },
+
+ getName: function() {
+ return this.initialConfig.name;
+ },
+
+ getValue: function() {
+ return {
+ type: this.proxyType.getValue(),
+ hostname: this.hostname.getValue(),
+ port: Number(this.port.getValue()),
+ username: this.username.getValue(),
+ password: this.password.getValue(),
+ proxy_hostnames: this.proxy_host_resolve.getValue(),
+ proxy_peer_connections: this.proxy_peer_conn.getValue(),
+ proxy_tracker_connections: this.proxy_tracker_conn.getValue(),
+ force_proxy: this.force_proxy.getValue(),
+ anonymous_mode: this.anonymous_mode.getValue(),
+ };
+ },
+
+ // Set the values of the proxies
+ setValue: function(value) {
+ this.setting = true;
+ this.proxyType.setValue(value['type']);
+ var index = this.proxyType.getStore().find('id', value['type']);
+ var record = this.proxyType.getStore().getAt(index);
+
+ this.hostname.setValue(value['hostname']);
+ this.port.setValue(value['port']);
+ this.username.setValue(value['username']);
+ this.password.setValue(value['password']);
+ this.proxy_host_resolve.setValue(value['proxy_hostnames']);
+ this.proxy_peer_conn.setValue(value['proxy_peer_connections']);
+ this.proxy_tracker_conn.setValue(value['proxy_tracker_connections']);
+ this.force_proxy.setValue(value['force_proxy']);
+ this.anonymous_mode.setValue(value['anonymous_mode']);
+
+ this.onTypeSelect(this.type, record, index);
+ this.setting = false;
+ },
+
+ onFieldChange: function(field, newValue, oldValue) {
+ if (this.setting) return;
+ var newValues = this.getValue();
+ var oldValues = Ext.apply({}, newValues);
+ oldValues[field.getName()] = oldValue;
+
+ this.fireEvent('change', this, newValues, oldValues);
+ },
+
+ onTypeSelect: function(combo, record, index) {
+ var typeId = record.get('id');
+ if (typeId > 0) {
+ this.hostname.show();
+ this.port.show();
+ this.proxy_peer_conn.show();
+ this.proxy_tracker_conn.show();
+ if (typeId > 1 && typeId < 6) {
+ this.proxy_host_resolve.show();
+ } else {
+ this.proxy_host_resolve.hide();
+ }
+ } else {
+ this.hostname.hide();
+ this.port.hide();
+ this.proxy_host_resolve.hide();
+ this.proxy_peer_conn.hide();
+ this.proxy_tracker_conn.hide();
+ }
+
+ if (typeId == 3 || typeId == 5) {
+ this.username.show();
+ this.password.show();
+ } else {
+ this.username.hide();
+ this.password.hide();
+ }
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js
new file mode 100644
index 0000000..4d3c402
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/ProxyPage.js
@@ -0,0 +1,62 @@
+/**
+ * Deluge.preferences.ProxyPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Proxy
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Proxy = Ext.extend(Ext.form.FormPanel, {
+ constructor: function(config) {
+ config = Ext.apply(
+ {
+ border: false,
+ title: _('Proxy'),
+ header: false,
+ layout: 'form',
+ autoScroll: true,
+ },
+ config
+ );
+ Deluge.preferences.Proxy.superclass.constructor.call(this, config);
+ },
+
+ initComponent: function() {
+ Deluge.preferences.Proxy.superclass.initComponent.call(this);
+ this.proxy = this.add(
+ new Deluge.preferences.ProxyField({
+ title: _('Proxy'),
+ name: 'proxy',
+ })
+ );
+ this.proxy.on('change', this.onProxyChange, this);
+ deluge.preferences.getOptionsManager().bind('proxy', this.proxy);
+ },
+
+ getValue: function() {
+ return {
+ proxy: this.proxy.getValue(),
+ };
+ },
+
+ setValue: function(value) {
+ for (var proxy in value) {
+ this[proxy].setValue(value[proxy]);
+ }
+ },
+
+ onProxyChange: function(field, newValue, oldValue) {
+ var newValues = this.getValue();
+ var oldValues = Ext.apply({}, newValues);
+ oldValues[field.getName()] = oldValue;
+
+ this.fireEvent('change', this, newValues, oldValues);
+ },
+});
diff --git a/deluge/ui/web/js/deluge-all/preferences/QueuePage.js b/deluge/ui/web/js/deluge-all/preferences/QueuePage.js
new file mode 100644
index 0000000..db2da7c
--- /dev/null
+++ b/deluge/ui/web/js/deluge-all/preferences/QueuePage.js
@@ -0,0 +1,234 @@
+/**
+ * Deluge.preferences.QueuePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Deluge.preferences');
+
+/**
+ * @class Deluge.preferences.Queue
+ * @extends Ext.form.FormPanel
+ */
+Deluge.preferences.Queue = Ext.extend(Ext.form.FormPanel, {
+ border: false,
+ title: _('Queue'),
+ header: false,
+ layout: 'form',
+
+ initComponent: function() {
+ Deluge.preferences.Queue.superclass.initComponent.call(this);
+
+ var om = deluge.preferences.getOptionsManager();
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('New Torrents'),
+ style: 'padding-top: 5px; margin-bottom: 0px;',
+ autoHeight: true,
+ labelWidth: 1,
+ defaultType: 'checkbox',
+ });
+ om.bind(
+ 'queue_new_to_top',
+ fieldset.add({
+ fieldLabel: '',
+ labelSeparator: '',
+ height: 22,
+ boxLabel: _('Queue to top'),
+ name: 'queue_new_to_top',
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Active Torrents'),
+ autoHeight: true,
+ labelWidth: 150,
+ defaultType: 'spinnerfield',
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ });
+ om.bind(
+ 'max_active_limit',
+ fieldset.add({
+ fieldLabel: _('Total:'),
+ labelSeparator: '',
+ name: 'max_active_limit',
+ value: 8,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'max_active_downloading',
+ fieldset.add({
+ fieldLabel: _('Downloading:'),
+ labelSeparator: '',
+ name: 'max_active_downloading',
+ value: 3,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'max_active_seeding',
+ fieldset.add({
+ fieldLabel: _('Seeding:'),
+ labelSeparator: '',
+ name: 'max_active_seeding',
+ value: 5,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+ om.bind(
+ 'dont_count_slow_torrents',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'dont_count_slow_torrents',
+ height: 22,
+ hideLabel: true,
+ boxLabel: _('Ignore slow torrents'),
+ })
+ );
+ om.bind(
+ 'auto_manage_prefer_seeds',
+ fieldset.add({
+ xtype: 'checkbox',
+ name: 'auto_manage_prefer_seeds',
+ hideLabel: true,
+ boxLabel: _('Prefer seeding torrents'),
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ title: _('Seeding Rotation'),
+ autoHeight: true,
+ labelWidth: 150,
+ defaultType: 'spinnerfield',
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ });
+ om.bind(
+ 'share_ratio_limit',
+ fieldset.add({
+ fieldLabel: _('Share Ratio:'),
+ labelSeparator: '',
+ name: 'share_ratio_limit',
+ value: 8,
+ width: 80,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ })
+ );
+ om.bind(
+ 'seed_time_ratio_limit',
+ fieldset.add({
+ fieldLabel: _('Time Ratio:'),
+ labelSeparator: '',
+ name: 'seed_time_ratio_limit',
+ value: 3,
+ width: 80,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ })
+ );
+ om.bind(
+ 'seed_time_limit',
+ fieldset.add({
+ fieldLabel: _('Time (m):'),
+ labelSeparator: '',
+ name: 'seed_time_limit',
+ value: 5,
+ width: 80,
+ decimalPrecision: 0,
+ minValue: -1,
+ maxValue: 99999,
+ })
+ );
+
+ fieldset = this.add({
+ xtype: 'fieldset',
+ border: false,
+ autoHeight: true,
+ style: 'padding-top: 5px; margin-bottom: 0px',
+ title: _('Share Ratio Reached'),
+
+ layout: 'table',
+ layoutConfig: { columns: 2 },
+ labelWidth: 0,
+ defaultType: 'checkbox',
+
+ defaults: {
+ fieldLabel: '',
+ labelSeparator: '',
+ },
+ });
+ this.stopAtRatio = fieldset.add({
+ name: 'stop_seed_at_ratio',
+ boxLabel: _('Share Ratio:'),
+ });
+ this.stopAtRatio.on('check', this.onStopRatioCheck, this);
+ om.bind('stop_seed_at_ratio', this.stopAtRatio);
+
+ this.stopRatio = fieldset.add({
+ xtype: 'spinnerfield',
+ name: 'stop_seed_ratio',
+ ctCls: 'x-deluge-indent-checkbox',
+ disabled: true,
+ value: '2.0',
+ width: 60,
+ incrementValue: 0.1,
+ minValue: -1,
+ maxValue: 99999,
+ alternateIncrementValue: 1,
+ decimalPrecision: 2,
+ });
+ om.bind('stop_seed_ratio', this.stopRatio);
+
+ this.removeAtRatio = fieldset.add({
+ xtype: 'radiogroup',
+ columns: 1,
+ colspan: 2,
+ disabled: true,
+ style: 'margin-left: 10px',
+ items: [
+ {
+ boxLabel: _('Pause torrent'),
+ name: 'at_ratio',
+ inputValue: false,
+ checked: true,
+ },
+ {
+ boxLabel: _('Remove torrent'),
+ name: 'at_ratio',
+ inputValue: true,
+ },
+ ],
+ });
+ om.bind('remove_seed_at_ratio', this.removeAtRatio);
+ },
+
+ onStopRatioCheck: function(e, checked) {
+ this.stopRatio.setDisabled(!checked);
+ this.removeAtRatio.setDisabled(!checked);
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-all-debug.js b/deluge/ui/web/js/extjs/ext-all-debug.js
new file mode 100644
index 0000000..0b15e6e
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-all-debug.js
@@ -0,0 +1,52270 @@
+/*
+This file is part of Ext JS 3.4
+
+Copyright (c) 2011-2013 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as
+published by the Free Software Foundation and appearing in the file LICENSE included in the
+packaging of this file.
+
+Please review the following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department
+at http://www.sencha.com/contact.
+
+Build date: 2013-04-03 15:07:25
+*/
+(function(){
+
+var EXTUTIL = Ext.util,
+ EACH = Ext.each,
+ TRUE = true,
+ FALSE = false;
+
+EXTUTIL.Observable = function(){
+
+ var me = this, e = me.events;
+ if(me.listeners){
+ me.on(me.listeners);
+ delete me.listeners;
+ }
+ me.events = e || {};
+};
+
+EXTUTIL.Observable.prototype = {
+
+ filterOptRe : /^(?:scope|delay|buffer|single)$/,
+
+
+ fireEvent : function(){
+ var a = Array.prototype.slice.call(arguments, 0),
+ ename = a[0].toLowerCase(),
+ me = this,
+ ret = TRUE,
+ ce = me.events[ename],
+ cc,
+ q,
+ c;
+ if (me.eventsSuspended === TRUE) {
+ if (q = me.eventQueue) {
+ q.push(a);
+ }
+ }
+ else if(typeof ce == 'object') {
+ if (ce.bubble){
+ if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
+ return FALSE;
+ }
+ c = me.getBubbleTarget && me.getBubbleTarget();
+ if(c && c.enableBubble) {
+ cc = c.events[ename];
+ if(!cc || typeof cc != 'object' || !cc.bubble) {
+ c.enableBubble(ename);
+ }
+ return c.fireEvent.apply(c, a);
+ }
+ }
+ else {
+ a.shift();
+ ret = ce.fire.apply(ce, a);
+ }
+ }
+ return ret;
+ },
+
+
+ addListener : function(eventName, fn, scope, o){
+ var me = this,
+ e,
+ oe,
+ ce;
+
+ if (typeof eventName == 'object') {
+ o = eventName;
+ for (e in o) {
+ oe = o[e];
+ if (!me.filterOptRe.test(e)) {
+ me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
+ }
+ }
+ } else {
+ eventName = eventName.toLowerCase();
+ ce = me.events[eventName] || TRUE;
+ if (typeof ce == 'boolean') {
+ me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
+ }
+ ce.addListener(fn, scope, typeof o == 'object' ? o : {});
+ }
+ },
+
+
+ removeListener : function(eventName, fn, scope){
+ var ce = this.events[eventName.toLowerCase()];
+ if (typeof ce == 'object') {
+ ce.removeListener(fn, scope);
+ }
+ },
+
+
+ purgeListeners : function(){
+ var events = this.events,
+ evt,
+ key;
+ for(key in events){
+ evt = events[key];
+ if(typeof evt == 'object'){
+ evt.clearListeners();
+ }
+ }
+ },
+
+
+ addEvents : function(o){
+ var me = this;
+ me.events = me.events || {};
+ if (typeof o == 'string') {
+ var a = arguments,
+ i = a.length;
+ while(i--) {
+ me.events[a[i]] = me.events[a[i]] || TRUE;
+ }
+ } else {
+ Ext.applyIf(me.events, o);
+ }
+ },
+
+
+ hasListener : function(eventName){
+ var e = this.events[eventName.toLowerCase()];
+ return typeof e == 'object' && e.listeners.length > 0;
+ },
+
+
+ suspendEvents : function(queueSuspended){
+ this.eventsSuspended = TRUE;
+ if(queueSuspended && !this.eventQueue){
+ this.eventQueue = [];
+ }
+ },
+
+
+ resumeEvents : function(){
+ var me = this,
+ queued = me.eventQueue || [];
+ me.eventsSuspended = FALSE;
+ delete me.eventQueue;
+ EACH(queued, function(e) {
+ me.fireEvent.apply(me, e);
+ });
+ }
+};
+
+var OBSERVABLE = EXTUTIL.Observable.prototype;
+
+OBSERVABLE.on = OBSERVABLE.addListener;
+
+OBSERVABLE.un = OBSERVABLE.removeListener;
+
+
+EXTUTIL.Observable.releaseCapture = function(o){
+ o.fireEvent = OBSERVABLE.fireEvent;
+};
+
+function createTargeted(h, o, scope){
+ return function(){
+ if(o.target == arguments[0]){
+ h.apply(scope, Array.prototype.slice.call(arguments, 0));
+ }
+ };
+};
+
+function createBuffered(h, o, l, scope){
+ l.task = new EXTUTIL.DelayedTask();
+ return function(){
+ l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
+ };
+};
+
+function createSingle(h, e, fn, scope){
+ return function(){
+ e.removeListener(fn, scope);
+ return h.apply(scope, arguments);
+ };
+};
+
+function createDelayed(h, o, l, scope){
+ return function(){
+ var task = new EXTUTIL.DelayedTask(),
+ args = Array.prototype.slice.call(arguments, 0);
+ if(!l.tasks) {
+ l.tasks = [];
+ }
+ l.tasks.push(task);
+ task.delay(o.delay || 10, function(){
+ l.tasks.remove(task);
+ h.apply(scope, args);
+ }, scope);
+ };
+};
+
+EXTUTIL.Event = function(obj, name){
+ this.name = name;
+ this.obj = obj;
+ this.listeners = [];
+};
+
+EXTUTIL.Event.prototype = {
+ addListener : function(fn, scope, options){
+ var me = this,
+ l;
+ scope = scope || me.obj;
+ if(!me.isListening(fn, scope)){
+ l = me.createListener(fn, scope, options);
+ if(me.firing){
+ me.listeners = me.listeners.slice(0);
+ }
+ me.listeners.push(l);
+ }
+ },
+
+ createListener: function(fn, scope, o){
+ o = o || {};
+ scope = scope || this.obj;
+ var l = {
+ fn: fn,
+ scope: scope,
+ options: o
+ }, h = fn;
+ if(o.target){
+ h = createTargeted(h, o, scope);
+ }
+ if(o.delay){
+ h = createDelayed(h, o, l, scope);
+ }
+ if(o.single){
+ h = createSingle(h, this, fn, scope);
+ }
+ if(o.buffer){
+ h = createBuffered(h, o, l, scope);
+ }
+ l.fireFn = h;
+ return l;
+ },
+
+ findListener : function(fn, scope){
+ var list = this.listeners,
+ i = list.length,
+ l;
+
+ scope = scope || this.obj;
+ while(i--){
+ l = list[i];
+ if(l){
+ if(l.fn == fn && l.scope == scope){
+ return i;
+ }
+ }
+ }
+ return -1;
+ },
+
+ isListening : function(fn, scope){
+ return this.findListener(fn, scope) != -1;
+ },
+
+ removeListener : function(fn, scope){
+ var index,
+ l,
+ k,
+ me = this,
+ ret = FALSE;
+ if((index = me.findListener(fn, scope)) != -1){
+ if (me.firing) {
+ me.listeners = me.listeners.slice(0);
+ }
+ l = me.listeners[index];
+ if(l.task) {
+ l.task.cancel();
+ delete l.task;
+ }
+ k = l.tasks && l.tasks.length;
+ if(k) {
+ while(k--) {
+ l.tasks[k].cancel();
+ }
+ delete l.tasks;
+ }
+ me.listeners.splice(index, 1);
+ ret = TRUE;
+ }
+ return ret;
+ },
+
+
+ clearListeners : function(){
+ var me = this,
+ l = me.listeners,
+ i = l.length;
+ while(i--) {
+ me.removeListener(l[i].fn, l[i].scope);
+ }
+ },
+
+ fire : function(){
+ var me = this,
+ listeners = me.listeners,
+ len = listeners.length,
+ i = 0,
+ l;
+
+ if(len > 0){
+ me.firing = TRUE;
+ var args = Array.prototype.slice.call(arguments, 0);
+ for (; i < len; i++) {
+ l = listeners[i];
+ if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
+ return (me.firing = FALSE);
+ }
+ }
+ }
+ me.firing = FALSE;
+ return TRUE;
+ }
+
+};
+})();
+
+Ext.DomHelper = function(){
+ var tempTableEl = null,
+ emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
+ tableRe = /^table|tbody|tr|td$/i,
+ confRe = /tag|children|cn|html$/i,
+ tableElRe = /td|tr|tbody/i,
+ cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
+ endRe = /end/i,
+ pub,
+
+ afterbegin = 'afterbegin',
+ afterend = 'afterend',
+ beforebegin = 'beforebegin',
+ beforeend = 'beforeend',
+ ts = '<table>',
+ te = '</table>',
+ tbs = ts+'<tbody>',
+ tbe = '</tbody>'+te,
+ trs = tbs + '<tr>',
+ tre = '</tr>'+tbe;
+
+
+ function doInsert(el, o, returnElement, pos, sibling, append){
+ var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
+ return returnElement ? Ext.get(newNode, true) : newNode;
+ }
+
+
+ function createHtml(o){
+ var b = '',
+ attr,
+ val,
+ key,
+ cn;
+
+ if(typeof o == "string"){
+ b = o;
+ } else if (Ext.isArray(o)) {
+ for (var i=0; i < o.length; i++) {
+ if(o[i]) {
+ b += createHtml(o[i]);
+ }
+ };
+ } else {
+ b += '<' + (o.tag = o.tag || 'div');
+ for (attr in o) {
+ val = o[attr];
+ if(!confRe.test(attr)){
+ if (typeof val == "object") {
+ b += ' ' + attr + '="';
+ for (key in val) {
+ b += key + ':' + val[key] + ';';
+ };
+ b += '"';
+ }else{
+ b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
+ }
+ }
+ };
+
+ if (emptyTags.test(o.tag)) {
+ b += '/>';
+ } else {
+ b += '>';
+ if ((cn = o.children || o.cn)) {
+ b += createHtml(cn);
+ } else if(o.html){
+ b += o.html;
+ }
+ b += '</' + o.tag + '>';
+ }
+ }
+ return b;
+ }
+
+ function ieTable(depth, s, h, e){
+ tempTableEl.innerHTML = [s, h, e].join('');
+ var i = -1,
+ el = tempTableEl,
+ ns;
+ while(++i < depth){
+ el = el.firstChild;
+ }
+
+ if(ns = el.nextSibling){
+ var df = document.createDocumentFragment();
+ while(el){
+ ns = el.nextSibling;
+ df.appendChild(el);
+ el = ns;
+ }
+ el = df;
+ }
+ return el;
+ }
+
+
+ function insertIntoTable(tag, where, el, html) {
+ var node,
+ before;
+
+ tempTableEl = tempTableEl || document.createElement('div');
+
+ if(tag == 'td' && (where == afterbegin || where == beforeend) ||
+ !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
+ return;
+ }
+ before = where == beforebegin ? el :
+ where == afterend ? el.nextSibling :
+ where == afterbegin ? el.firstChild : null;
+
+ if (where == beforebegin || where == afterend) {
+ el = el.parentNode;
+ }
+
+ if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
+ node = ieTable(4, trs, html, tre);
+ } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
+ (tag == 'tr' && (where == beforebegin || where == afterend))) {
+ node = ieTable(3, tbs, html, tbe);
+ } else {
+ node = ieTable(2, ts, html, te);
+ }
+ el.insertBefore(node, before);
+ return node;
+ }
+
+
+ function createContextualFragment(html){
+ var div = document.createElement("div"),
+ fragment = document.createDocumentFragment(),
+ i = 0,
+ length, childNodes;
+
+ div.innerHTML = html;
+ childNodes = div.childNodes;
+ length = childNodes.length;
+
+ for (; i < length; i++) {
+ fragment.appendChild(childNodes[i].cloneNode(true));
+ }
+
+ return fragment;
+ }
+
+ pub = {
+
+ markup : function(o){
+ return createHtml(o);
+ },
+
+
+ applyStyles : function(el, styles){
+ if (styles) {
+ var matches;
+
+ el = Ext.fly(el);
+ if (typeof styles == "function") {
+ styles = styles.call();
+ }
+ if (typeof styles == "string") {
+
+ cssRe.lastIndex = 0;
+ while ((matches = cssRe.exec(styles))) {
+ el.setStyle(matches[1], matches[2]);
+ }
+ } else if (typeof styles == "object") {
+ el.setStyle(styles);
+ }
+ }
+ },
+
+ insertHtml : function(where, el, html){
+ var hash = {},
+ hashVal,
+ range,
+ rangeEl,
+ setStart,
+ frag,
+ rs;
+
+ where = where.toLowerCase();
+
+ hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
+ hash[afterend] = ['AfterEnd', 'nextSibling'];
+
+ if (el.insertAdjacentHTML) {
+ if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
+ return rs;
+ }
+
+ hash[afterbegin] = ['AfterBegin', 'firstChild'];
+ hash[beforeend] = ['BeforeEnd', 'lastChild'];
+ if ((hashVal = hash[where])) {
+ el.insertAdjacentHTML(hashVal[0], html);
+ return el[hashVal[1]];
+ }
+ } else {
+ range = el.ownerDocument.createRange();
+ setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
+ if (hash[where]) {
+ range[setStart](el);
+ if (!range.createContextualFragment) {
+ frag = createContextualFragment(html);
+ }
+ else {
+ frag = range.createContextualFragment(html);
+ }
+ el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
+ return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
+ } else {
+ rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
+ if (el.firstChild) {
+ range[setStart](el[rangeEl]);
+ if (!range.createContextualFragment) {
+ frag = createContextualFragment(html);
+ }
+ else {
+ frag = range.createContextualFragment(html);
+ }
+ if(where == afterbegin){
+ el.insertBefore(frag, el.firstChild);
+ }else{
+ el.appendChild(frag);
+ }
+ } else {
+ el.innerHTML = html;
+ }
+ return el[rangeEl];
+ }
+ }
+ throw 'Illegal insertion point -> "' + where + '"';
+ },
+
+
+ insertBefore : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, beforebegin);
+ },
+
+
+ insertAfter : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, afterend, 'nextSibling');
+ },
+
+
+ insertFirst : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, afterbegin, 'firstChild');
+ },
+
+
+ append : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, beforeend, '', true);
+ },
+
+
+ overwrite : function(el, o, returnElement){
+ el = Ext.getDom(el);
+ el.innerHTML = createHtml(o);
+ return returnElement ? Ext.get(el.firstChild) : el.firstChild;
+ },
+
+ createHtml : createHtml
+ };
+ return pub;
+}();
+
+Ext.Template = function(html){
+ var me = this,
+ a = arguments,
+ buf = [],
+ v;
+
+ if (Ext.isArray(html)) {
+ html = html.join("");
+ } else if (a.length > 1) {
+ for(var i = 0, len = a.length; i < len; i++){
+ v = a[i];
+ if(typeof v == 'object'){
+ Ext.apply(me, v);
+ } else {
+ buf.push(v);
+ }
+ };
+ html = buf.join('');
+ }
+
+
+ me.html = html;
+
+ if (me.compiled) {
+ me.compile();
+ }
+};
+Ext.Template.prototype = {
+
+ re : /\{([\w\-]+)\}/g,
+
+
+
+ applyTemplate : function(values){
+ var me = this;
+
+ return me.compiled ?
+ me.compiled(values) :
+ me.html.replace(me.re, function(m, name){
+ return values[name] !== undefined ? values[name] : "";
+ });
+ },
+
+
+ set : function(html, compile){
+ var me = this;
+ me.html = html;
+ me.compiled = null;
+ return compile ? me.compile() : me;
+ },
+
+
+ compile : function(){
+ var me = this,
+ sep = Ext.isGecko ? "+" : ",";
+
+ function fn(m, name){
+ name = "values['" + name + "']";
+ return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
+ }
+
+ eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
+ me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
+ (Ext.isGecko ? "';};" : "'].join('');};"));
+ return me;
+ },
+
+
+ insertFirst: function(el, values, returnElement){
+ return this.doInsert('afterBegin', el, values, returnElement);
+ },
+
+
+ insertBefore: function(el, values, returnElement){
+ return this.doInsert('beforeBegin', el, values, returnElement);
+ },
+
+
+ insertAfter : function(el, values, returnElement){
+ return this.doInsert('afterEnd', el, values, returnElement);
+ },
+
+
+ append : function(el, values, returnElement){
+ return this.doInsert('beforeEnd', el, values, returnElement);
+ },
+
+ doInsert : function(where, el, values, returnEl){
+ el = Ext.getDom(el);
+ var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
+ return returnEl ? Ext.get(newNode, true) : newNode;
+ },
+
+
+ overwrite : function(el, values, returnElement){
+ el = Ext.getDom(el);
+ el.innerHTML = this.applyTemplate(values);
+ return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
+ }
+};
+
+Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
+
+
+Ext.Template.from = function(el, config){
+ el = Ext.getDom(el);
+ return new Ext.Template(el.value || el.innerHTML, config || '');
+};
+
+
+Ext.DomQuery = function(){
+ var cache = {},
+ simpleCache = {},
+ valueCache = {},
+ nonSpace = /\S/,
+ trimRe = /^\s+|\s+$/g,
+ tplRe = /\{(\d+)\}/g,
+ modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
+ tagTokenRe = /^(#)?([\w\-\*]+)/,
+ nthRe = /(\d*)n\+?(\d*)/,
+ nthRe2 = /\D/,
+
+
+
+ isIE = window.ActiveXObject ? true : false,
+ key = 30803;
+
+
+
+ eval("var batch = 30803;");
+
+
+
+ function child(parent, index){
+ var i = 0,
+ n = parent.firstChild;
+ while(n){
+ if(n.nodeType == 1){
+ if(++i == index){
+ 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 children(parent){
+ var n = parent.firstChild,
+ nodeIndex = -1,
+ nextNode;
+ while(n){
+ nextNode = n.nextSibling;
+
+ if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
+ parent.removeChild(n);
+ }else{
+
+ n.nodeIndex = ++nodeIndex;
+ }
+ n = nextNode;
+ }
+ return this;
+ }
+
+
+
+
+ function byClassName(nodeSet, cls){
+ if(!cls){
+ return nodeSet;
+ }
+ var result = [], ri = -1;
+ for(var i = 0, ci; ci = nodeSet[i]; i++){
+ if((' '+ci.className+' ').indexOf(cls) != -1){
+ result[++ri] = ci;
+ }
+ }
+ return result;
+ };
+
+ function attrValue(n, attr){
+
+ if(!n.tagName && typeof n.length != "undefined"){
+ n = n[0];
+ }
+ if(!n){
+ return null;
+ }
+
+ if(attr == "for"){
+ return n.htmlFor;
+ }
+ if(attr == "class" || attr == "className"){
+ return n.className;
+ }
+ return n.getAttribute(attr) || n[attr];
+
+ };
+
+
+
+
+
+ function getNodes(ns, mode, tagName){
+ var result = [], ri = -1, cs;
+ if(!ns){
+ return result;
+ }
+ tagName = tagName || "*";
+
+ if(typeof ns.getElementsByTagName != "undefined"){
+ ns = [ns];
+ }
+
+
+
+ if(!mode){
+ for(var i = 0, ni; ni = ns[i]; i++){
+ cs = ni.getElementsByTagName(tagName);
+ for(var j = 0, ci; ci = cs[j]; j++){
+ result[++ri] = ci;
+ }
+ }
+
+
+ } else if(mode == "/" || mode == ">"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, ni, cn; ni = ns[i]; i++){
+ cn = ni.childNodes;
+ for(var j = 0, cj; cj = cn[j]; j++){
+ if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
+ result[++ri] = cj;
+ }
+ }
+ }
+
+
+ }else if(mode == "+"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
+ result[++ri] = n;
+ }
+ }
+
+
+ }else if(mode == "~"){
+ var utag = tagName.toUpperCase();
+ for(var i = 0, n; n = ns[i]; i++){
+ while((n = n.nextSibling)){
+ if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
+ result[++ri] = n;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ 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, tagName){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!tagName){
+ return cs;
+ }
+ var result = [], ri = -1;
+ tagName = tagName.toLowerCase();
+ for(var i = 0, ci; ci = cs[i]; i++){
+ if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
+ result[++ri] = ci;
+ }
+ }
+ return result;
+ }
+
+ function byId(cs, id){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!id){
+ return cs;
+ }
+ var result = [], ri = -1;
+ for(var i = 0, ci; ci = cs[i]; i++){
+ if(ci && ci.id == id){
+ result[++ri] = ci;
+ return result;
+ }
+ }
+ return result;
+ }
+
+
+
+ function byAttribute(cs, attr, value, op, custom){
+ var result = [],
+ ri = -1,
+ useGetStyle = custom == "{",
+ fn = Ext.DomQuery.operators[op],
+ a,
+ xml,
+ hasXml;
+
+ for(var i = 0, ci; ci = cs[i]; i++){
+
+ if(ci.nodeType != 1){
+ continue;
+ }
+
+ if(!hasXml){
+ xml = Ext.DomQuery.isXml(ci);
+ hasXml = true;
+ }
+
+
+ if(!xml){
+ if(useGetStyle){
+ a = Ext.DomQuery.getStyle(ci, attr);
+ } else if (attr == "class" || attr == "className"){
+ a = ci.className;
+ } else if (attr == "for"){
+ a = ci.htmlFor;
+ } else if (attr == "href"){
+
+
+ a = ci.getAttribute("href", 2);
+ } else{
+ a = ci.getAttribute(attr);
+ }
+ }else{
+ a = ci.getAttribute(attr);
+ }
+ if((fn && fn(a, value)) || (!fn && a)){
+ result[++ri] = ci;
+ }
+ }
+ return result;
+ }
+
+ function byPseudo(cs, name, value){
+ return Ext.DomQuery.pseudos[name](cs, value);
+ }
+
+ function nodupIEXml(cs){
+ var d = ++key,
+ r;
+ cs[0].setAttribute("_nodup", d);
+ 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, ri = -1;
+ if(!len || typeof cs.nodeType != "undefined" || len == 1){
+ return cs;
+ }
+ if(isIE && 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[++ri] = cs[j];
+ }
+ for(j = i+1; cj = cs[j]; j++){
+ if(cj._nodup != d){
+ cj._nodup = d;
+ r[++ri] = cj;
+ }
+ }
+ return r;
+ }
+ }
+ return r;
+ }
+
+ function quickDiffIEXml(c1, c2){
+ var d = ++key,
+ r = [];
+ for(var i = 0, len = c1.length; i < len; i++){
+ c1[i].setAttribute("_qdiff", d);
+ }
+ 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 len1 = c1.length,
+ d = ++key,
+ r = [];
+ if(!len1){
+ return c2;
+ }
+ if(isIE && typeof c1[0].selectSingleNode != "undefined"){
+ return quickDiffIEXml(c1, c2);
+ }
+ for(var i = 0; i < len1; i++){
+ c1[i]._qdiff = d;
+ }
+ 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, mode, root, id){
+ if(ns == root){
+ var d = root.ownerDocument || root;
+ return d.getElementById(id);
+ }
+ ns = getNodes(ns, mode, "*");
+ return byId(ns, id);
+ }
+
+ return {
+ getStyle : function(el, name){
+ return Ext.fly(el).getStyle(name);
+ },
+
+ compile : function(path, type){
+ type = type || "select";
+
+
+ var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
+ mode,
+ lastPath,
+ matchers = Ext.DomQuery.matchers,
+ matchersLn = matchers.length,
+ modeMatch,
+
+ lmode = path.match(modeRe);
+
+ if(lmode && lmode[1]){
+ fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
+ path = path.replace(lmode[1], "");
+ }
+
+
+ while(path.substr(0, 1)=="/"){
+ path = path.substr(1);
+ }
+
+ while(path && lastPath != path){
+ lastPath = path;
+ var tokenMatch = path.match(tagTokenRe);
+ if(type == "select"){
+ if(tokenMatch){
+
+ if(tokenMatch[1] == "#"){
+ fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';
+ }else{
+ fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
+ }
+ path = path.replace(tokenMatch[0], "");
+ }else if(path.substr(0, 1) != '@'){
+ fn[fn.length] = 'n = getNodes(n, mode, "*");';
+ }
+
+ }else{
+ if(tokenMatch){
+ if(tokenMatch[1] == "#"){
+ fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
+ }else{
+ fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
+ }
+ path = path.replace(tokenMatch[0], "");
+ }
+ }
+ while(!(modeMatch = path.match(modeRe))){
+ var matched = false;
+ for(var j = 0; j < matchersLn; j++){
+ var t = matchers[j];
+ var m = path.match(t.re);
+ if(m){
+ fn[fn.length] = t.select.replace(tplRe, function(x, i){
+ return m[i];
+ });
+ path = path.replace(m[0], "");
+ matched = true;
+ break;
+ }
+ }
+
+ if(!matched){
+ throw 'Error parsing selector, parsing failed at "' + path + '"';
+ }
+ }
+ if(modeMatch[1]){
+ fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
+ path = path.replace(modeMatch[1], "");
+ }
+ }
+
+ fn[fn.length] = "return nodup(n);\n}";
+
+
+ eval(fn.join(""));
+ return f;
+ },
+
+
+ jsSelect: function(path, root, type){
+
+ root = root || document;
+
+ if(typeof root == "string"){
+ root = document.getElementById(root);
+ }
+ var paths = path.split(","),
+ results = [];
+
+
+ for(var i = 0, len = paths.length; i < len; i++){
+ var subPath = paths[i].replace(trimRe, "");
+
+ if(!cache[subPath]){
+ cache[subPath] = Ext.DomQuery.compile(subPath);
+ if(!cache[subPath]){
+ throw subPath + " is not a valid selector";
+ }
+ }
+ var result = cache[subPath](root);
+ if(result && result != document){
+ results = results.concat(result);
+ }
+ }
+
+
+
+ if(paths.length > 1){
+ return nodup(results);
+ }
+ return results;
+ },
+ isXml: function(el) {
+ var docEl = (el ? el.ownerDocument || el : 0).documentElement;
+ return docEl ? docEl.nodeName !== "HTML" : false;
+ },
+ select : document.querySelectorAll ? function(path, root, type) {
+ root = root || document;
+ if (!Ext.DomQuery.isXml(root)) {
+ try {
+ var cs = root.querySelectorAll(path);
+ return Ext.toArray(cs);
+ }
+ catch (ex) {}
+ }
+ return Ext.DomQuery.jsSelect.call(this, path, root, type);
+ } : function(path, root, type) {
+ return Ext.DomQuery.jsSelect.call(this, path, root, type);
+ },
+
+
+ selectNode : function(path, root){
+ return Ext.DomQuery.select(path, root)[0];
+ },
+
+
+ selectValue : function(path, root, defaultValue){
+ path = path.replace(trimRe, "");
+ if(!valueCache[path]){
+ valueCache[path] = Ext.DomQuery.compile(path, "select");
+ }
+ var n = valueCache[path](root), v;
+ n = n[0] ? n[0] : n;
+
+
+
+
+
+ if (typeof n.normalize == 'function') n.normalize();
+
+ v = (n && n.firstChild ? n.firstChild.nodeValue : null);
+ return ((v === null||v === undefined||v==='') ? defaultValue : v);
+ },
+
+
+ selectNumber : function(path, root, defaultValue){
+ var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
+ return parseFloat(v);
+ },
+
+
+ is : function(el, ss){
+ if(typeof el == "string"){
+ el = document.getElementById(el);
+ }
+ var isArray = Ext.isArray(el),
+ result = Ext.DomQuery.filter(isArray ? el : [el], ss);
+ return isArray ? (result.length == el.length) : (result.length > 0);
+ },
+
+
+ filter : function(els, ss, nonMatches){
+ ss = ss.replace(trimRe, "");
+ if(!simpleCache[ss]){
+ simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
+ }
+ var result = simpleCache[ss](els);
+ return nonMatches ? quickDiff(result, els) : result;
+ },
+
+
+ matchers : [{
+ re: /^\.([\w\-]+)/,
+ select: 'n = byClassName(n, " {1} ");'
+ }, {
+ re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
+ select: 'n = byPseudo(n, "{1}", "{2}");'
+ },{
+ re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,
+ select: 'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'
+ }, {
+ re: /^#([\w\-]+)/,
+ select: 'n = byId(n, "{1}");'
+ },{
+ re: /^@([\w\-]+)/,
+ select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
+ }
+ ],
+
+ /**
+ * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=.
+ * New operators can be added as long as the match the format <i>c</i>= where <i>c</i> is any character other than space, &gt; &lt;.
+ */
+ 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;
+ },
+ "|=" : function(a, v){
+ return a && (a == v || a.substr(0, v.length+1) == v+'-');
+ },
+ "~=" : function(a, v){
+ return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
+ }
+ },
+
+ /**
+ * <p>Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed
+ * two parameters:</p><div class="mdetail-params"><ul>
+ * <li><b>c</b> : Array<div class="sub-desc">An Array of DOM elements to filter.</div></li>
+ * <li><b>v</b> : String<div class="sub-desc">The argument (if any) supplied in the selector.</div></li>
+ * </ul></div>
+ * <p>A filter function returns an Array of DOM elements which conform to the pseudo class.</p>
+ * <p>In addition to the provided pseudo classes listed above such as <code>first-child</code> and <code>nth-child</code>,
+ * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.</p>
+ * <p>For example, to filter <code>&lt;a></code> elements to only return links to <i>external</i> resources:</p>
+ * <code><pre>
+Ext.DomQuery.pseudos.external = function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+// Include in result set only if it's a link to an external resource
+ if(ci.hostname != location.hostname){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+};</pre></code>
+ * Then external links could be gathered with the following statement:<code><pre>
+var externalLinks = Ext.select("a:external");
+</code></pre>
+ */
+ pseudos : {
+ "first-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.previousSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "last-child" : function(c){
+ var r = [], ri = -1, n;
+ for(var i = 0, ci; ci = n = c[i]; i++){
+ while((n = n.nextSibling) && n.nodeType != 1);
+ if(!n){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nth-child" : function(c, a) {
+ var r = [], ri = -1,
+ m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
+ f = (m[1] || 1) - 0, l = m[2] - 0;
+ for(var i = 0, n; n = c[i]; i++){
+ var pn = n.parentNode;
+ if (batch != pn._batch) {
+ var j = 0;
+ for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
+ if(cn.nodeType == 1){
+ cn.nodeIndex = ++j;
+ }
+ }
+ pn._batch = batch;
+ }
+ if (f == 1) {
+ if (l == 0 || n.nodeIndex == l){
+ r[++ri] = n;
+ }
+ } else if ((n.nodeIndex + l) % f == 0){
+ r[++ri] = n;
+ }
+ }
+
+ return r;
+ },
+
+ "only-child" : function(c){
+ var r = [], ri = -1;;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(!prev(ci) && !next(ci)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "empty" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var cns = ci.childNodes, j = 0, cn, empty = true;
+ while(cn = cns[j]){
+ ++j;
+ if(cn.nodeType == 1 || cn.nodeType == 3){
+ empty = false;
+ break;
+ }
+ }
+ if(empty){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "contains" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "nodeValue" : function(c, v){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.firstChild && ci.firstChild.nodeValue == v){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "checked" : function(c){
+ var r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(ci.checked == true){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "not" : function(c, ss){
+ return Ext.DomQuery.filter(c, ss, true);
+ },
+
+ "any" : function(c, selectors){
+ var ss = selectors.split('|'),
+ r = [], ri = -1, s;
+ for(var i = 0, ci; ci = c[i]; i++){
+ for(var j = 0; s = ss[j]; j++){
+ if(Ext.DomQuery.is(ci, s)){
+ r[++ri] = ci;
+ break;
+ }
+ }
+ }
+ return r;
+ },
+
+ "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,
+ r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(s(ss, ci).length > 0){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "next" : function(c, ss){
+ var is = Ext.DomQuery.is,
+ r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = next(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ },
+
+ "prev" : function(c, ss){
+ var is = Ext.DomQuery.is,
+ r = [], ri = -1;
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = prev(ci);
+ if(n && is(n, ss)){
+ r[++ri] = ci;
+ }
+ }
+ return r;
+ }
+ }
+ };
+}();
+
+/**
+ * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select}
+ * @param {String} path The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Array}
+ * @member Ext
+ * @method query
+ */
+Ext.query = Ext.DomQuery.select;
+/**
+ * @class Ext.util.DelayedTask
+ * <p> The DelayedTask class provides a convenient way to "buffer" the execution of a method,
+ * performing setTimeout where a new timeout cancels the old timeout. When called, the
+ * task will wait the specified time period before executing. If durng that time period,
+ * the task is called again, the original call will be cancelled. This continues so that
+ * the function is only called a single time for each iteration.</p>
+ * <p>This method is especially useful for things like detecting whether a user has finished
+ * typing in a text field. An example would be performing validation on a keypress. You can
+ * use this class to buffer the keypress events for a certain number of milliseconds, and
+ * perform only if they stop for that amount of time. Usage:</p><pre><code>
+var task = new Ext.util.DelayedTask(function(){
+ alert(Ext.getDom('myInputField').value.length);
+});
+// Wait 500ms before calling our function. If the user presses another key
+// during that 500ms, it will be cancelled and we'll wait another 500ms.
+Ext.get('myInputField').on('keypress', function(){
+ task.{@link #delay}(500);
+});
+ * </code></pre>
+ * <p>Note that we are using a DelayedTask here to illustrate a point. The configuration
+ * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will
+ * also setup a delayed task for you to buffer events.</p>
+ * @constructor The parameters to this constructor serve as defaults and are not required.
+ * @param {Function} fn (optional) The default function to call.
+ * @param {Object} scope (optional) The default scope (The <code><b>this</b></code> reference) in which the
+ * function is called. If not specified, <code>this</code> will refer to the browser window.
+ * @param {Array} args (optional) The default Array of arguments.
+ */
+Ext.util.DelayedTask = function(fn, scope, args){
+ var me = this,
+ id,
+ call = function(){
+ clearInterval(id);
+ id = null;
+ fn.apply(scope, args || []);
+ };
+
+ /**
+ * Cancels any pending timeout and queues a new one
+ * @param {Number} delay The milliseconds to delay
+ * @param {Function} newFn (optional) Overrides function passed to constructor
+ * @param {Object} newScope (optional) Overrides scope passed to constructor. Remember that if no scope
+ * is specified, <code>this</code> will refer to the browser window.
+ * @param {Array} newArgs (optional) Overrides args passed to constructor
+ */
+ me.delay = function(delay, newFn, newScope, newArgs){
+ me.cancel();
+ fn = newFn || fn;
+ scope = newScope || scope;
+ args = newArgs || args;
+ id = setInterval(call, delay);
+ };
+
+ /**
+ * Cancel the last queued timeout
+ */
+ me.cancel = function(){
+ if(id){
+ clearInterval(id);
+ id = null;
+ }
+ };
+};/**
+ * @class Ext.Element
+ * <p>Encapsulates a DOM element, adding simple DOM manipulation facilities, normalizing for browser differences.</p>
+ * <p>All instances of this class inherit the methods of {@link Ext.Fx} making visual effects easily available to all DOM elements.</p>
+ * <p>Note that the events documented in this class are not Ext events, they encapsulate browser events. To
+ * access the underlying browser event, see {@link Ext.EventObject#browserEvent}. Some older
+ * browsers may not support the full range of events. Which events are supported is beyond the control of ExtJs.</p>
+ * Usage:<br>
+<pre><code>
+// by id
+var el = Ext.get("my-div");
+
+// by DOM element reference
+var el = Ext.get(myDivElement);
+</code></pre>
+ * <b>Animations</b><br />
+ * <p>When an element is manipulated, by default there is no animation.</p>
+ * <pre><code>
+var el = Ext.get("my-div");
+
+// no animation
+el.setWidth(100);
+ * </code></pre>
+ * <p>Many of the functions for manipulating an element have an optional "animate" parameter. This
+ * parameter can be specified as boolean (<tt>true</tt>) for default animation effects.</p>
+ * <pre><code>
+// default animation
+el.setWidth(100, true);
+ * </code></pre>
+ *
+ * <p>To configure the effects, an object literal with animation options to use as the Element animation
+ * configuration object can also be specified. Note that the supported Element animation configuration
+ * options are a subset of the {@link Ext.Fx} animation options specific to Fx effects. The supported
+ * Element animation configuration options are:</p>
+<pre>
+Option Default Description
+--------- -------- ---------------------------------------------
+{@link Ext.Fx#duration duration} .35 The duration of the animation in seconds
+{@link Ext.Fx#easing easing} easeOut The easing method
+{@link Ext.Fx#callback callback} none A function to execute when the anim completes
+{@link Ext.Fx#scope scope} this The scope (this) of the callback function
+</pre>
+ *
+ * <pre><code>
+// Element animation options object
+var opt = {
+ {@link Ext.Fx#duration duration}: 1,
+ {@link Ext.Fx#easing easing}: 'elasticIn',
+ {@link Ext.Fx#callback callback}: this.foo,
+ {@link Ext.Fx#scope scope}: this
+};
+// animation with some options set
+el.setWidth(100, opt);
+ * </code></pre>
+ * <p>The Element animation object being used for the animation will be set on the options
+ * object as "anim", which allows you to stop or manipulate the animation. Here is an example:</p>
+ * <pre><code>
+// using the "anim" property to get the Anim object
+if(opt.anim.isAnimated()){
+ opt.anim.stop();
+}
+ * </code></pre>
+ * <p>Also see the <tt>{@link #animate}</tt> method for another animation technique.</p>
+ * <p><b> Composite (Collections of) Elements</b></p>
+ * <p>For working with collections of Elements, see {@link Ext.CompositeElement}</p>
+ * @constructor Create a new Element directly.
+ * @param {String/HTMLElement} element
+ * @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class).
+ */
+(function(){
+var DOC = document;
+
+Ext.Element = function(element, forceNew){
+ var dom = typeof element == "string" ?
+ DOC.getElementById(element) : element,
+ id;
+
+ if(!dom) return null;
+
+ id = dom.id;
+
+ if(!forceNew && id && Ext.elCache[id]){ // element object already exists
+ return Ext.elCache[id].el;
+ }
+
+ /**
+ * The DOM element
+ * @type HTMLElement
+ */
+ this.dom = dom;
+
+ /**
+ * The DOM element ID
+ * @type String
+ */
+ this.id = id || Ext.id(dom);
+};
+
+var DH = Ext.DomHelper,
+ El = Ext.Element,
+ EC = Ext.elCache;
+
+El.prototype = {
+ /**
+ * Sets the passed attributes as attributes of this element (a style attribute can be a string, object or function)
+ * @param {Object} o The object with the attributes
+ * @param {Boolean} useSet (optional) false to override the default setAttribute to use expandos.
+ * @return {Ext.Element} this
+ */
+ set : function(o, useSet){
+ var el = this.dom,
+ attr,
+ val,
+ useSet = (useSet !== false) && !!el.setAttribute;
+
+ for (attr in o) {
+ if (o.hasOwnProperty(attr)) {
+ val = o[attr];
+ if (attr == 'style') {
+ DH.applyStyles(el, val);
+ } else if (attr == 'cls') {
+ el.className = val;
+ } else if (useSet) {
+ el.setAttribute(attr, val);
+ } else {
+ el[attr] = val;
+ }
+ }
+ }
+ return this;
+ },
+
+// Mouse events
+ /**
+ * @event click
+ * Fires when a mouse click is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event contextmenu
+ * Fires when a right click is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event dblclick
+ * Fires when a mouse double click is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mousedown
+ * Fires when a mousedown is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mouseup
+ * Fires when a mouseup is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mouseover
+ * Fires when a mouseover is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mousemove
+ * Fires when a mousemove is detected with the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mouseout
+ * Fires when a mouseout is detected with the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mouseenter
+ * Fires when the mouse enters the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event mouseleave
+ * Fires when the mouse leaves the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+// Keyboard events
+ /**
+ * @event keypress
+ * Fires when a keypress is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event keydown
+ * Fires when a keydown is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event keyup
+ * Fires when a keyup is detected within the element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+
+// HTML frame/object events
+ /**
+ * @event load
+ * Fires when the user agent finishes loading all content within the element. Only supported by window, frames, objects and images.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event unload
+ * Fires when the user agent removes all content from a window or frame. For elements, it fires when the target element or any of its content has been removed.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event abort
+ * Fires when an object/image is stopped from loading before completely loaded.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event error
+ * Fires when an object/image/frame cannot be loaded properly.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event resize
+ * Fires when a document view is resized.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event scroll
+ * Fires when a document view is scrolled.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+// Form events
+ /**
+ * @event select
+ * Fires when a user selects some text in a text field, including input and textarea.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event change
+ * Fires when a control loses the input focus and its value has been modified since gaining focus.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event submit
+ * Fires when a form is submitted.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event reset
+ * Fires when a form is reset.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event focus
+ * Fires when an element receives focus either via the pointing device or by tab navigation.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event blur
+ * Fires when an element loses focus either via the pointing device or by tabbing navigation.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+// User Interface events
+ /**
+ * @event DOMFocusIn
+ * Where supported. Similar to HTML focus event, but can be applied to any focusable element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMFocusOut
+ * Where supported. Similar to HTML blur event, but can be applied to any focusable element.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMActivate
+ * Where supported. Fires when an element is activated, for instance, through a mouse click or a keypress.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+// DOM Mutation events
+ /**
+ * @event DOMSubtreeModified
+ * Where supported. Fires when the subtree is modified.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMNodeInserted
+ * Where supported. Fires when a node has been added as a child of another node.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMNodeRemoved
+ * Where supported. Fires when a descendant node of the element is removed.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMNodeRemovedFromDocument
+ * Where supported. Fires when a node is being removed from a document.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMNodeInsertedIntoDocument
+ * Where supported. Fires when a node is being inserted into a document.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMAttrModified
+ * Where supported. Fires when an attribute has been modified.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+ /**
+ * @event DOMCharacterDataModified
+ * Where supported. Fires when the character data has been modified.
+ * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.
+ * @param {HtmlElement} t The target of the event.
+ * @param {Object} o The options configuration passed to the {@link #addListener} call.
+ */
+
+ /**
+ * The default unit to append to CSS values where a unit isn't provided (defaults to px).
+ * @type String
+ */
+ defaultUnit : "px",
+
+ /**
+ * Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child)
+ * @param {String} selector The simple selector to test
+ * @return {Boolean} True if this element matches the selector, else false
+ */
+ is : function(simpleSelector){
+ return Ext.DomQuery.is(this.dom, simpleSelector);
+ },
+
+ /**
+ * Tries to focus the element. Any exceptions are caught and ignored.
+ * @param {Number} defer (optional) Milliseconds to defer the focus
+ * @return {Ext.Element} this
+ */
+ focus : function(defer, /* private */ dom) {
+ var me = this,
+ dom = dom || me.dom;
+ try{
+ if(Number(defer)){
+ me.focus.defer(defer, null, [null, dom]);
+ }else{
+ dom.focus();
+ }
+ }catch(e){}
+ return me;
+ },
+
+ /**
+ * Tries to blur the element. Any exceptions are caught and ignored.
+ * @return {Ext.Element} this
+ */
+ blur : function() {
+ try{
+ this.dom.blur();
+ }catch(e){}
+ return this;
+ },
+
+ /**
+ * Returns the value of the "value" attribute
+ * @param {Boolean} asNumber true to parse the value as a number
+ * @return {String/Number}
+ */
+ getValue : function(asNumber){
+ var val = this.dom.value;
+ return asNumber ? parseInt(val, 10) : val;
+ },
+
+ /**
+ * Appends an event handler to this element. The shorthand version {@link #on} is equivalent.
+ * @param {String} eventName The name of event to handle.
+ * @param {Function} fn The handler function the event invokes. This function is passed
+ * the following parameters:<ul>
+ * <li><b>evt</b> : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
+ * <li><b>el</b> : HtmlElement<div class="sub-desc">The DOM element which was the target of the event.
+ * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
+ * <li><b>o</b> : Object<div class="sub-desc">The options object from the addListener call.</div></li>
+ * </ul>
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+ * <b>If omitted, defaults to this Element.</b>.
+ * @param {Object} options (optional) An object containing handler configuration properties.
+ * This may contain any of the following properties:<ul>
+ * <li><b>scope</b> Object : <div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+ * <b>If omitted, defaults to this Element.</b></div></li>
+ * <li><b>delegate</b> String: <div class="sub-desc">A simple selector to filter the target or look for a descendant of the target. See below for additional details.</div></li>
+ * <li><b>stopEvent</b> Boolean: <div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
+ * <li><b>preventDefault</b> Boolean: <div class="sub-desc">True to prevent the default action</div></li>
+ * <li><b>stopPropagation</b> Boolean: <div class="sub-desc">True to prevent event propagation</div></li>
+ * <li><b>normalized</b> Boolean: <div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
+ * <li><b>target</b> Ext.Element: <div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
+ * <li><b>delay</b> Number: <div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
+ * <li><b>single</b> Boolean: <div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
+ * <li><b>buffer</b> Number: <div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
+ * by the specified number of milliseconds. If the event fires again within that time, the original
+ * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
+ * </ul><br>
+ * <p>
+ * <b>Combining Options</b><br>
+ * In the following examples, the shorthand form {@link #on} is used rather than the more verbose
+ * addListener. The two are equivalent. Using the options argument, it is possible to combine different
+ * types of listeners:<br>
+ * <br>
+ * A delayed, one-time listener that auto stops the event and adds a custom argument (forumId) to the
+ * options object. The options object is available as the third parameter in the handler function.<div style="margin: 5px 20px 20px;">
+ * Code:<pre><code>
+el.on('click', this.onClick, this, {
+ single: true,
+ delay: 100,
+ stopEvent : true,
+ forumId: 4
+});</code></pre></p>
+ * <p>
+ * <b>Attaching multiple handlers in 1 call</b><br>
+ * The method also allows for a single argument to be passed which is a config object containing properties
+ * which specify multiple handlers.</p>
+ * <p>
+ * Code:<pre><code>
+el.on({
+ 'click' : {
+ fn: this.onClick,
+ scope: this,
+ delay: 100
+ },
+ 'mouseover' : {
+ fn: this.onMouseOver,
+ scope: this
+ },
+ 'mouseout' : {
+ fn: this.onMouseOut,
+ scope: this
+ }
+});</code></pre>
+ * <p>
+ * Or a shorthand syntax:<br>
+ * Code:<pre><code></p>
+el.on({
+ 'click' : this.onClick,
+ 'mouseover' : this.onMouseOver,
+ 'mouseout' : this.onMouseOut,
+ scope: this
+});
+ * </code></pre></p>
+ * <p><b>delegate</b></p>
+ * <p>This is a configuration option that you can pass along when registering a handler for
+ * an event to assist with event delegation. Event delegation is a technique that is used to
+ * reduce memory consumption and prevent exposure to memory-leaks. By registering an event
+ * for a container element as opposed to each element within a container. By setting this
+ * configuration option to a simple selector, the target element will be filtered to look for
+ * a descendant of the target.
+ * For example:<pre><code>
+// using this markup:
+&lt;div id='elId'>
+ &lt;p id='p1'>paragraph one&lt;/p>
+ &lt;p id='p2' class='clickable'>paragraph two&lt;/p>
+ &lt;p id='p3'>paragraph three&lt;/p>
+&lt;/div>
+// utilize event delegation to registering just one handler on the container element:
+el = Ext.get('elId');
+el.on(
+ 'click',
+ function(e,t) {
+ // handle click
+ console.info(t.id); // 'p2'
+ },
+ this,
+ {
+ // filter the target element to be a descendant with the class 'clickable'
+ delegate: '.clickable'
+ }
+);
+ * </code></pre></p>
+ * @return {Ext.Element} this
+ */
+ addListener : function(eventName, fn, scope, options){
+ Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
+ return this;
+ },
+
+ /**
+ * Removes an event handler from this element. The shorthand version {@link #un} is equivalent.
+ * <b>Note</b>: if a <i>scope</i> was explicitly specified when {@link #addListener adding} the
+ * listener, the same scope must be specified here.
+ * Example:
+ * <pre><code>
+el.removeListener('click', this.handlerFn);
+// or
+el.un('click', this.handlerFn);
+</code></pre>
+ * @param {String} eventName The name of the event from which to remove the handler.
+ * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
+ * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
+ * then this must refer to the same object.
+ * @return {Ext.Element} this
+ */
+ removeListener : function(eventName, fn, scope){
+ Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this);
+ return this;
+ },
+
+ /**
+ * Removes all previous added listeners from this element
+ * @return {Ext.Element} this
+ */
+ removeAllListeners : function(){
+ Ext.EventManager.removeAll(this.dom);
+ return this;
+ },
+
+ /**
+ * Recursively removes all previous added listeners from this element and its children
+ * @return {Ext.Element} this
+ */
+ purgeAllListeners : function() {
+ Ext.EventManager.purgeElement(this, true);
+ return this;
+ },
+ /**
+ * @private Test if size has a unit, otherwise appends the default
+ */
+ addUnits : function(size){
+ if(size === "" || size == "auto" || size === undefined){
+ size = size || '';
+ } else if(!isNaN(size) || !unitPattern.test(size)){
+ size = size + (this.defaultUnit || 'px');
+ }
+ return size;
+ },
+
+ /**
+ * <p>Updates the <a href="http:
+ * from a specified URL. Note that this is subject to the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a></p>
+ * <p>Updating innerHTML of an element will <b>not</b> execute embedded <tt>&lt;script></tt> elements. This is a browser restriction.</p>
+ * @param {Mixed} options. Either a sring containing the URL from which to load the HTML, or an {@link Ext.Ajax#request} options object specifying
+ * exactly how to request the HTML.
+ * @return {Ext.Element} this
+ */
+ load : function(url, params, cb){
+ Ext.Ajax.request(Ext.apply({
+ params: params,
+ url: url.url || url,
+ callback: cb,
+ el: this.dom,
+ indicatorText: url.indicatorText || ''
+ }, Ext.isObject(url) ? url : {}));
+ return this;
+ },
+
+
+ isBorderBox : function(){
+ return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()];
+ },
+
+
+ remove : function(){
+ var me = this,
+ dom = me.dom;
+
+ if (dom) {
+ delete me.dom;
+ Ext.removeNode(dom);
+ }
+ },
+
+
+ hover : function(overFn, outFn, scope, options){
+ var me = this;
+ me.on('mouseenter', overFn, scope || me.dom, options);
+ me.on('mouseleave', outFn, scope || me.dom, options);
+ return me;
+ },
+
+
+ contains : function(el){
+ return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
+ },
+
+
+ getAttributeNS : function(ns, name){
+ return this.getAttribute(name, ns);
+ },
+
+
+ getAttribute: (function(){
+ var test = document.createElement('table'),
+ isBrokenOnTable = false,
+ hasGetAttribute = 'getAttribute' in test,
+ unknownRe = /undefined|unknown/;
+
+ if (hasGetAttribute) {
+
+ try {
+ test.getAttribute('ext:qtip');
+ } catch (e) {
+ isBrokenOnTable = true;
+ }
+
+ return function(name, ns) {
+ var el = this.dom,
+ value;
+
+ if (el.getAttributeNS) {
+ value = el.getAttributeNS(ns, name) || null;
+ }
+
+ if (value == null) {
+ if (ns) {
+ if (isBrokenOnTable && el.tagName.toUpperCase() == 'TABLE') {
+ try {
+ value = el.getAttribute(ns + ':' + name);
+ } catch (e) {
+ value = '';
+ }
+ } else {
+ value = el.getAttribute(ns + ':' + name);
+ }
+ } else {
+ value = el.getAttribute(name) || el[name];
+ }
+ }
+ return value || '';
+ };
+ } else {
+ return function(name, ns) {
+ var el = this.om,
+ value,
+ attribute;
+
+ if (ns) {
+ attribute = el[ns + ':' + name];
+ value = unknownRe.test(typeof attribute) ? undefined : attribute;
+ } else {
+ value = el[name];
+ }
+ return value || '';
+ };
+ }
+ test = null;
+ })(),
+
+
+ update : function(html) {
+ if (this.dom) {
+ this.dom.innerHTML = html;
+ }
+ return this;
+ }
+};
+
+var ep = El.prototype;
+
+El.addMethods = function(o){
+ Ext.apply(ep, o);
+};
+
+
+ep.on = ep.addListener;
+
+
+ep.un = ep.removeListener;
+
+
+ep.autoBoxAdjust = true;
+
+
+var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
+ docEl;
+
+
+El.get = function(el){
+ var ex,
+ elm,
+ id;
+ if(!el){ return null; }
+ if (typeof el == "string") {
+ if (!(elm = DOC.getElementById(el))) {
+ return null;
+ }
+ if (EC[el] && EC[el].el) {
+ ex = EC[el].el;
+ ex.dom = elm;
+ } else {
+ ex = El.addToCache(new El(elm));
+ }
+ return ex;
+ } else if (el.tagName) {
+ if(!(id = el.id)){
+ id = Ext.id(el);
+ }
+ if (EC[id] && EC[id].el) {
+ ex = EC[id].el;
+ ex.dom = el;
+ } else {
+ ex = El.addToCache(new El(el));
+ }
+ return ex;
+ } else if (el instanceof El) {
+ if(el != docEl){
+
+
+
+
+ if (Ext.isIE && (el.id == undefined || el.id == '')) {
+ el.dom = el.dom;
+ } else {
+ el.dom = DOC.getElementById(el.id) || el.dom;
+ }
+ }
+ return el;
+ } else if(el.isComposite) {
+ return el;
+ } else if(Ext.isArray(el)) {
+ return El.select(el);
+ } else if(el == DOC) {
+
+ if(!docEl){
+ var f = function(){};
+ f.prototype = El.prototype;
+ docEl = new f();
+ docEl.dom = DOC;
+ }
+ return docEl;
+ }
+ return null;
+};
+
+El.addToCache = function(el, id){
+ id = id || el.id;
+ EC[id] = {
+ el: el,
+ data: {},
+ events: {}
+ };
+ return el;
+};
+
+
+El.data = function(el, key, value){
+ el = El.get(el);
+ if (!el) {
+ return null;
+ }
+ var c = EC[el.id].data;
+ if(arguments.length == 2){
+ return c[key];
+ }else{
+ return (c[key] = value);
+ }
+};
+
+
+
+
+function garbageCollect(){
+ if(!Ext.enableGarbageCollector){
+ clearInterval(El.collectorThreadId);
+ } else {
+ var eid,
+ el,
+ d,
+ o;
+
+ for(eid in EC){
+ o = EC[eid];
+ if(o.skipGC){
+ Ext.EventManager.removeFromSpecialCache(o.el);
+ continue;
+ }
+ el = o.el;
+ d = el.dom;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
+ if(Ext.enableListenerCollection){
+ Ext.EventManager.removeAll(d);
+ }
+ delete EC[eid];
+ }
+ }
+
+ if (Ext.isIE) {
+ var t = {};
+ for (eid in EC) {
+ t[eid] = EC[eid];
+ }
+ EC = Ext.elCache = t;
+ }
+ }
+}
+El.collectorThreadId = setInterval(garbageCollect, 30000);
+
+var flyFn = function(){};
+flyFn.prototype = El.prototype;
+
+
+El.Flyweight = function(dom){
+ this.dom = dom;
+};
+
+El.Flyweight.prototype = new flyFn();
+El.Flyweight.prototype.isFlyweight = true;
+El._flyweights = {};
+
+
+El.fly = function(el, named){
+ var ret = null;
+ named = named || '_global';
+
+ if (el = Ext.getDom(el)) {
+ (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
+ ret = El._flyweights[named];
+ }
+ return ret;
+};
+
+
+Ext.get = El.get;
+
+
+Ext.fly = El.fly;
+
+
+var noBoxAdjust = Ext.isStrict ? {
+ select:1
+} : {
+ input:1, select:1, textarea:1
+};
+if(Ext.isIE || Ext.isGecko){
+ noBoxAdjust['button'] = 1;
+}
+
+})();
+
+Ext.Element.addMethods(function(){
+ var PARENTNODE = 'parentNode',
+ NEXTSIBLING = 'nextSibling',
+ PREVIOUSSIBLING = 'previousSibling',
+ DQ = Ext.DomQuery,
+ GET = Ext.get;
+
+ return {
+
+ findParent : function(simpleSelector, maxDepth, returnEl){
+ var p = this.dom,
+ b = document.body,
+ depth = 0,
+ stopEl;
+ if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
+ return null;
+ }
+ maxDepth = maxDepth || 50;
+ if (isNaN(maxDepth)) {
+ stopEl = Ext.getDom(maxDepth);
+ maxDepth = Number.MAX_VALUE;
+ }
+ while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
+ if(DQ.is(p, simpleSelector)){
+ return returnEl ? GET(p) : p;
+ }
+ depth++;
+ p = p.parentNode;
+ }
+ return null;
+ },
+
+
+ findParentNode : function(simpleSelector, maxDepth, returnEl){
+ var p = Ext.fly(this.dom.parentNode, '_internal');
+ return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
+ },
+
+
+ up : function(simpleSelector, maxDepth){
+ return this.findParentNode(simpleSelector, maxDepth, true);
+ },
+
+
+ select : function(selector){
+ return Ext.Element.select(selector, this.dom);
+ },
+
+
+ query : function(selector){
+ return DQ.select(selector, this.dom);
+ },
+
+
+ child : function(selector, returnDom){
+ var n = DQ.selectNode(selector, this.dom);
+ return returnDom ? n : GET(n);
+ },
+
+
+ down : function(selector, returnDom){
+ var n = DQ.selectNode(" > " + selector, this.dom);
+ return returnDom ? n : GET(n);
+ },
+
+
+ parent : function(selector, returnDom){
+ return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
+ },
+
+
+ next : function(selector, returnDom){
+ return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
+ },
+
+
+ prev : function(selector, returnDom){
+ return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
+ },
+
+
+
+ first : function(selector, returnDom){
+ return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
+ },
+
+
+ last : function(selector, returnDom){
+ return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
+ },
+
+ matchNode : function(dir, start, selector, returnDom){
+ var n = this.dom[start];
+ while(n){
+ if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
+ return !returnDom ? GET(n) : n;
+ }
+ n = n[dir];
+ }
+ return null;
+ }
+ };
+}());
+Ext.Element.addMethods(
+function() {
+ var GETDOM = Ext.getDom,
+ GET = Ext.get,
+ DH = Ext.DomHelper;
+
+ return {
+
+ appendChild: function(el){
+ return GET(el).appendTo(this);
+ },
+
+
+ appendTo: function(el){
+ GETDOM(el).appendChild(this.dom);
+ return this;
+ },
+
+
+ insertBefore: function(el){
+ (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
+ return this;
+ },
+
+
+ insertAfter: function(el){
+ (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
+ return this;
+ },
+
+
+ insertFirst: function(el, returnDom){
+ el = el || {};
+ if(el.nodeType || el.dom || typeof el == 'string'){
+ el = GETDOM(el);
+ this.dom.insertBefore(el, this.dom.firstChild);
+ return !returnDom ? GET(el) : el;
+ }else{
+ return this.createChild(el, this.dom.firstChild, returnDom);
+ }
+ },
+
+
+ replace: function(el){
+ el = GET(el);
+ this.insertBefore(el);
+ el.remove();
+ return this;
+ },
+
+
+ replaceWith: function(el){
+ var me = this;
+
+ if(el.nodeType || el.dom || typeof el == 'string'){
+ el = GETDOM(el);
+ me.dom.parentNode.insertBefore(el, me.dom);
+ }else{
+ el = DH.insertBefore(me.dom, el);
+ }
+
+ delete Ext.elCache[me.id];
+ Ext.removeNode(me.dom);
+ me.id = Ext.id(me.dom = el);
+ Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);
+ return me;
+ },
+
+
+ createChild: function(config, insertBefore, returnDom){
+ config = config || {tag:'div'};
+ return insertBefore ?
+ DH.insertBefore(insertBefore, config, returnDom !== true) :
+ DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
+ },
+
+
+ wrap: function(config, returnDom){
+ var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
+ newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
+ return newEl;
+ },
+
+
+ insertHtml : function(where, html, returnEl){
+ var el = DH.insertHtml(where, this.dom, html);
+ return returnEl ? Ext.get(el) : el;
+ }
+ };
+}());
+Ext.Element.addMethods(function(){
+
+ var supports = Ext.supports,
+ propCache = {},
+ camelRe = /(-[a-z])/gi,
+ view = document.defaultView,
+ opacityRe = /alpha\(opacity=(.*)\)/i,
+ trimRe = /^\s+|\s+$/g,
+ EL = Ext.Element,
+ spacesRe = /\s+/,
+ wordsRe = /\w/g,
+ PADDING = "padding",
+ MARGIN = "margin",
+ BORDER = "border",
+ LEFT = "-left",
+ RIGHT = "-right",
+ TOP = "-top",
+ BOTTOM = "-bottom",
+ WIDTH = "-width",
+ MATH = Math,
+ HIDDEN = 'hidden',
+ ISCLIPPED = 'isClipped',
+ OVERFLOW = 'overflow',
+ OVERFLOWX = 'overflow-x',
+ OVERFLOWY = 'overflow-y',
+ ORIGINALCLIP = 'originalClip',
+
+ borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
+ paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
+ margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
+ data = Ext.Element.data;
+
+
+
+ function camelFn(m, a) {
+ return a.charAt(1).toUpperCase();
+ }
+
+ function chkCache(prop) {
+ return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
+ }
+
+ return {
+
+ adjustWidth : function(width) {
+ var me = this;
+ var isNum = (typeof width == "number");
+ if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+ width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
+ }
+ return (isNum && width < 0) ? 0 : width;
+ },
+
+
+ adjustHeight : function(height) {
+ var me = this;
+ var isNum = (typeof height == "number");
+ if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+ height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
+ }
+ return (isNum && height < 0) ? 0 : height;
+ },
+
+
+
+ addClass : function(className){
+ var me = this,
+ i,
+ len,
+ v,
+ cls = [];
+
+ if (!Ext.isArray(className)) {
+ if (typeof className == 'string' && !this.hasClass(className)) {
+ me.dom.className += " " + className;
+ }
+ }
+ else {
+ for (i = 0, len = className.length; i < len; i++) {
+ v = className[i];
+ if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
+ cls.push(v);
+ }
+ }
+ if (cls.length) {
+ me.dom.className += " " + cls.join(" ");
+ }
+ }
+ return me;
+ },
+
+
+ removeClass : function(className){
+ var me = this,
+ i,
+ idx,
+ len,
+ cls,
+ elClasses;
+ if (!Ext.isArray(className)){
+ className = [className];
+ }
+ if (me.dom && me.dom.className) {
+ elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
+ for (i = 0, len = className.length; i < len; i++) {
+ cls = className[i];
+ if (typeof cls == 'string') {
+ cls = cls.replace(trimRe, '');
+ idx = elClasses.indexOf(cls);
+ if (idx != -1) {
+ elClasses.splice(idx, 1);
+ }
+ }
+ }
+ me.dom.className = elClasses.join(" ");
+ }
+ return me;
+ },
+
+
+ radioClass : function(className){
+ var cn = this.dom.parentNode.childNodes,
+ v,
+ i,
+ len;
+ className = Ext.isArray(className) ? className : [className];
+ for (i = 0, len = cn.length; i < len; i++) {
+ v = cn[i];
+ if (v && v.nodeType == 1) {
+ Ext.fly(v, '_internal').removeClass(className);
+ }
+ };
+ return this.addClass(className);
+ },
+
+
+ toggleClass : function(className){
+ return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
+ },
+
+
+ hasClass : function(className){
+ return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
+ },
+
+
+ replaceClass : function(oldClassName, newClassName){
+ return this.removeClass(oldClassName).addClass(newClassName);
+ },
+
+ isStyle : function(style, val) {
+ return this.getStyle(style) == val;
+ },
+
+
+ getStyle : function(){
+ return view && view.getComputedStyle ?
+ function(prop){
+ var el = this.dom,
+ v,
+ cs,
+ out,
+ display;
+
+ if(el == document){
+ return null;
+ }
+ prop = chkCache(prop);
+ out = (v = el.style[prop]) ? v :
+ (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
+
+
+
+ if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){
+ display = el.style.display;
+ el.style.display = 'inline-block';
+ out = view.getComputedStyle(el, '').marginRight;
+ el.style.display = display;
+ }
+
+ if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){
+ out = 'transparent';
+ }
+ return out;
+ } :
+ function(prop){
+ var el = this.dom,
+ m,
+ cs;
+
+ if(el == document) return null;
+ if (prop == 'opacity') {
+ if (el.style.filter.match) {
+ if(m = el.style.filter.match(opacityRe)){
+ var fv = parseFloat(m[1]);
+ if(!isNaN(fv)){
+ return fv ? fv / 100 : 0;
+ }
+ }
+ }
+ return 1;
+ }
+ prop = chkCache(prop);
+ return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+ };
+ }(),
+
+
+ getColor : function(attr, defaultValue, prefix){
+ var v = this.getStyle(attr),
+ color = (typeof prefix != 'undefined') ? prefix : '#',
+ h;
+
+ if(!v || (/transparent|inherit/.test(v))) {
+ return defaultValue;
+ }
+ if(/^r/.test(v)){
+ Ext.each(v.slice(4, v.length -1).split(','), function(s){
+ h = parseInt(s, 10);
+ color += (h < 16 ? '0' : '') + h.toString(16);
+ });
+ }else{
+ v = v.replace('#', '');
+ color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
+ }
+ return(color.length > 5 ? color.toLowerCase() : defaultValue);
+ },
+
+
+ setStyle : function(prop, value){
+ var tmp, style;
+
+ if (typeof prop != 'object') {
+ tmp = {};
+ tmp[prop] = value;
+ prop = tmp;
+ }
+ for (style in prop) {
+ value = prop[style];
+ style == 'opacity' ?
+ this.setOpacity(value) :
+ this.dom.style[chkCache(style)] = value;
+ }
+ return this;
+ },
+
+
+ setOpacity : function(opacity, animate){
+ var me = this,
+ s = me.dom.style;
+
+ if(!animate || !me.anim){
+ if(Ext.isIE9m){
+ var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
+ val = s.filter.replace(opacityRe, '').replace(trimRe, '');
+
+ s.zoom = 1;
+ s.filter = val + (val.length > 0 ? ' ' : '') + opac;
+ }else{
+ s.opacity = opacity;
+ }
+ }else{
+ me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
+ }
+ return me;
+ },
+
+
+ clearOpacity : function(){
+ var style = this.dom.style;
+ if(Ext.isIE9m){
+ if(!Ext.isEmpty(style.filter)){
+ style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
+ }
+ }else{
+ style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
+ }
+ return this;
+ },
+
+
+ getHeight : function(contentHeight){
+ var me = this,
+ dom = me.dom,
+ hidden = Ext.isIE9m && me.isStyle('display', 'none'),
+ h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
+
+ h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
+ return h < 0 ? 0 : h;
+ },
+
+
+ getWidth : function(contentWidth){
+ var me = this,
+ dom = me.dom,
+ hidden = Ext.isIE9m && me.isStyle('display', 'none'),
+ w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
+ w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
+ return w < 0 ? 0 : w;
+ },
+
+
+ setWidth : function(width, animate){
+ var me = this;
+ width = me.adjustWidth(width);
+ !animate || !me.anim ?
+ me.dom.style.width = me.addUnits(width) :
+ me.anim({width : {to : width}}, me.preanim(arguments, 1));
+ return me;
+ },
+
+
+ setHeight : function(height, animate){
+ var me = this;
+ height = me.adjustHeight(height);
+ !animate || !me.anim ?
+ me.dom.style.height = me.addUnits(height) :
+ me.anim({height : {to : height}}, me.preanim(arguments, 1));
+ return me;
+ },
+
+
+ getBorderWidth : function(side){
+ return this.addStyles(side, borders);
+ },
+
+
+ getPadding : function(side){
+ return this.addStyles(side, paddings);
+ },
+
+
+ clip : function(){
+ var me = this,
+ dom = me.dom;
+
+ if(!data(dom, ISCLIPPED)){
+ data(dom, ISCLIPPED, true);
+ data(dom, ORIGINALCLIP, {
+ o: me.getStyle(OVERFLOW),
+ x: me.getStyle(OVERFLOWX),
+ y: me.getStyle(OVERFLOWY)
+ });
+ me.setStyle(OVERFLOW, HIDDEN);
+ me.setStyle(OVERFLOWX, HIDDEN);
+ me.setStyle(OVERFLOWY, HIDDEN);
+ }
+ return me;
+ },
+
+
+ unclip : function(){
+ var me = this,
+ dom = me.dom;
+
+ if(data(dom, ISCLIPPED)){
+ data(dom, ISCLIPPED, false);
+ var o = data(dom, ORIGINALCLIP);
+ if(o.o){
+ me.setStyle(OVERFLOW, o.o);
+ }
+ if(o.x){
+ me.setStyle(OVERFLOWX, o.x);
+ }
+ if(o.y){
+ me.setStyle(OVERFLOWY, o.y);
+ }
+ }
+ return me;
+ },
+
+
+ addStyles : function(sides, styles){
+ var ttlSize = 0,
+ sidesArr = sides.match(wordsRe),
+ side,
+ size,
+ i,
+ len = sidesArr.length;
+ for (i = 0; i < len; i++) {
+ side = sidesArr[i];
+ size = side && parseInt(this.getStyle(styles[side]), 10);
+ if (size) {
+ ttlSize += MATH.abs(size);
+ }
+ }
+ return ttlSize;
+ },
+
+ margins : margins
+ };
+}()
+);
+
+(function(){
+var D = Ext.lib.Dom,
+ LEFT = "left",
+ RIGHT = "right",
+ TOP = "top",
+ BOTTOM = "bottom",
+ POSITION = "position",
+ STATIC = "static",
+ RELATIVE = "relative",
+ AUTO = "auto",
+ ZINDEX = "z-index";
+
+Ext.Element.addMethods({
+
+ getX : function(){
+ return D.getX(this.dom);
+ },
+
+
+ getY : function(){
+ return D.getY(this.dom);
+ },
+
+
+ getXY : function(){
+ return D.getXY(this.dom);
+ },
+
+
+ getOffsetsTo : function(el){
+ var o = this.getXY(),
+ e = Ext.fly(el, '_internal').getXY();
+ return [o[0]-e[0],o[1]-e[1]];
+ },
+
+
+ setX : function(x, animate){
+ return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
+ },
+
+
+ setY : function(y, animate){
+ return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
+ },
+
+
+ setLeft : function(left){
+ this.setStyle(LEFT, this.addUnits(left));
+ return this;
+ },
+
+
+ setTop : function(top){
+ this.setStyle(TOP, this.addUnits(top));
+ return this;
+ },
+
+
+ setRight : function(right){
+ this.setStyle(RIGHT, this.addUnits(right));
+ return this;
+ },
+
+
+ setBottom : function(bottom){
+ this.setStyle(BOTTOM, this.addUnits(bottom));
+ return this;
+ },
+
+
+ setXY : function(pos, animate){
+ var me = this;
+ if(!animate || !me.anim){
+ D.setXY(me.dom, pos);
+ }else{
+ me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
+ }
+ return me;
+ },
+
+
+ setLocation : function(x, y, animate){
+ return this.setXY([x, y], this.animTest(arguments, animate, 2));
+ },
+
+
+ moveTo : function(x, y, animate){
+ return this.setXY([x, y], this.animTest(arguments, animate, 2));
+ },
+
+
+ getLeft : function(local){
+ return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
+ },
+
+
+ getRight : function(local){
+ var me = this;
+ return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
+ },
+
+
+ getTop : function(local) {
+ return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
+ },
+
+
+ getBottom : function(local){
+ var me = this;
+ return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
+ },
+
+
+ position : function(pos, zIndex, x, y){
+ var me = this;
+
+ if(!pos && me.isStyle(POSITION, STATIC)){
+ me.setStyle(POSITION, RELATIVE);
+ } else if(pos) {
+ me.setStyle(POSITION, pos);
+ }
+ if(zIndex){
+ me.setStyle(ZINDEX, zIndex);
+ }
+ if(x || y) me.setXY([x || false, y || false]);
+ },
+
+
+ clearPositioning : function(value){
+ value = value || '';
+ this.setStyle({
+ left : value,
+ right : value,
+ top : value,
+ bottom : value,
+ "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(ZINDEX)
+ };
+ },
+
+
+ setPositioning : function(pc){
+ var me = this,
+ style = me.dom.style;
+
+ me.setStyle(pc);
+
+ if(pc.right == AUTO){
+ style.right = "";
+ }
+ if(pc.bottom == AUTO){
+ style.bottom = "";
+ }
+
+ return me;
+ },
+
+
+ translatePoints : function(x, y){
+ y = isNaN(x[1]) ? y : x[1];
+ x = isNaN(x[0]) ? x : x[0];
+ var me = this,
+ relative = me.isStyle(POSITION, RELATIVE),
+ o = me.getXY(),
+ l = parseInt(me.getStyle(LEFT), 10),
+ t = parseInt(me.getStyle(TOP), 10);
+
+ l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
+ t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
+
+ return {left: (x - o[0] + l), top: (y - o[1] + t)};
+ },
+
+ animTest : function(args, animate, i) {
+ return !!animate && this.preanim ? this.preanim(args, i) : false;
+ }
+});
+})();
+Ext.Element.addMethods({
+
+ isScrollable : function(){
+ var dom = this.dom;
+ return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
+ },
+
+
+ scrollTo : function(side, value){
+ this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
+ return this;
+ },
+
+
+ getScroll : function(){
+ var d = this.dom,
+ doc = document,
+ body = doc.body,
+ docElement = doc.documentElement,
+ l,
+ t,
+ ret;
+
+ if(d == doc || d == body){
+ if(Ext.isIE && Ext.isStrict){
+ l = docElement.scrollLeft;
+ t = docElement.scrollTop;
+ }else{
+ l = window.pageXOffset;
+ t = window.pageYOffset;
+ }
+ ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
+ }else{
+ ret = {left: d.scrollLeft, top: d.scrollTop};
+ }
+ return ret;
+ }
+});
+
+Ext.Element.VISIBILITY = 1;
+
+Ext.Element.DISPLAY = 2;
+
+
+Ext.Element.OFFSETS = 3;
+
+
+Ext.Element.ASCLASS = 4;
+
+
+Ext.Element.visibilityCls = 'x-hide-nosize';
+
+Ext.Element.addMethods(function(){
+ var El = Ext.Element,
+ OPACITY = "opacity",
+ VISIBILITY = "visibility",
+ DISPLAY = "display",
+ HIDDEN = "hidden",
+ OFFSETS = "offsets",
+ ASCLASS = "asclass",
+ NONE = "none",
+ NOSIZE = 'nosize',
+ ORIGINALDISPLAY = 'originalDisplay',
+ VISMODE = 'visibilityMode',
+ ISVISIBLE = 'isVisible',
+ data = El.data,
+ getDisplay = function(dom){
+ var d = data(dom, ORIGINALDISPLAY);
+ if(d === undefined){
+ data(dom, ORIGINALDISPLAY, d = '');
+ }
+ return d;
+ },
+ getVisMode = function(dom){
+ var m = data(dom, VISMODE);
+ if(m === undefined){
+ data(dom, VISMODE, m = 1);
+ }
+ return m;
+ };
+
+ return {
+
+ originalDisplay : "",
+ visibilityMode : 1,
+
+
+ setVisibilityMode : function(visMode){
+ data(this.dom, VISMODE, visMode);
+ return this;
+ },
+
+
+ animate : function(args, duration, onComplete, easing, animType){
+ this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
+ return this;
+ },
+
+
+ anim : function(args, opt, animType, defaultDur, defaultEase, cb){
+ animType = animType || 'run';
+ opt = opt || {};
+ var me = this,
+ anim = Ext.lib.Anim[animType](
+ me.dom,
+ args,
+ (opt.duration || defaultDur) || .35,
+ (opt.easing || defaultEase) || 'easeOut',
+ function(){
+ if(cb) cb.call(me);
+ if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
+ },
+ me
+ );
+ opt.anim = anim;
+ return anim;
+ },
+
+
+ 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]});
+ },
+
+
+ isVisible : function() {
+ var me = this,
+ dom = me.dom,
+ visible = data(dom, ISVISIBLE);
+
+ if(typeof visible == 'boolean'){
+ return visible;
+ }
+
+ visible = !me.isStyle(VISIBILITY, HIDDEN) &&
+ !me.isStyle(DISPLAY, NONE) &&
+ !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls));
+
+ data(dom, ISVISIBLE, visible);
+ return visible;
+ },
+
+
+ setVisible : function(visible, animate){
+ var me = this, isDisplay, isVisibility, isOffsets, isNosize,
+ dom = me.dom,
+ visMode = getVisMode(dom);
+
+
+
+ if (typeof animate == 'string'){
+ switch (animate) {
+ case DISPLAY:
+ visMode = El.DISPLAY;
+ break;
+ case VISIBILITY:
+ visMode = El.VISIBILITY;
+ break;
+ case OFFSETS:
+ visMode = El.OFFSETS;
+ break;
+ case NOSIZE:
+ case ASCLASS:
+ visMode = El.ASCLASS;
+ break;
+ }
+ me.setVisibilityMode(visMode);
+ animate = false;
+ }
+
+ if (!animate || !me.anim) {
+ if(visMode == El.ASCLASS ){
+
+ me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls);
+
+ } else if (visMode == El.DISPLAY){
+
+ return me.setDisplayed(visible);
+
+ } else if (visMode == El.OFFSETS){
+
+ if (!visible){
+ me.hideModeStyles = {
+ position: me.getStyle('position'),
+ top: me.getStyle('top'),
+ left: me.getStyle('left')
+ };
+ me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
+ } else {
+ me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
+ delete me.hideModeStyles;
+ }
+
+ }else{
+ me.fixDisplay();
+ dom.style.visibility = visible ? "visible" : HIDDEN;
+ }
+ }else{
+
+ if(visible){
+ me.setOpacity(.01);
+ me.setVisible(true);
+ }
+ me.anim({opacity: { to: (visible?1:0) }},
+ me.preanim(arguments, 1),
+ null,
+ .35,
+ 'easeIn',
+ function(){
+ visible || me.setVisible(false).setOpacity(1);
+ });
+ }
+ data(dom, ISVISIBLE, visible);
+ return me;
+ },
+
+
+
+ hasMetrics : function(){
+ var dom = this.dom;
+ return this.isVisible() || (getVisMode(dom) == El.VISIBILITY);
+ },
+
+
+ toggle : function(animate){
+ var me = this;
+ me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
+ return me;
+ },
+
+
+ setDisplayed : function(value) {
+ if(typeof value == "boolean"){
+ value = value ? getDisplay(this.dom) : NONE;
+ }
+ this.setStyle(DISPLAY, value);
+ return this;
+ },
+
+
+ fixDisplay : function(){
+ var me = this;
+ if(me.isStyle(DISPLAY, NONE)){
+ me.setStyle(VISIBILITY, HIDDEN);
+ me.setStyle(DISPLAY, getDisplay(this.dom));
+ if(me.isStyle(DISPLAY, NONE)){
+ me.setStyle(DISPLAY, "block");
+ }
+ }
+ },
+
+
+ hide : function(animate){
+
+ if (typeof animate == 'string'){
+ this.setVisible(false, animate);
+ return this;
+ }
+ this.setVisible(false, this.preanim(arguments, 0));
+ return this;
+ },
+
+
+ show : function(animate){
+
+ if (typeof animate == 'string'){
+ this.setVisible(true, animate);
+ return this;
+ }
+ this.setVisible(true, this.preanim(arguments, 0));
+ return this;
+ }
+ };
+}());(function(){
+
+ var NULL = null,
+ UNDEFINED = undefined,
+ TRUE = true,
+ FALSE = false,
+ SETX = "setX",
+ SETY = "setY",
+ SETXY = "setXY",
+ LEFT = "left",
+ BOTTOM = "bottom",
+ TOP = "top",
+ RIGHT = "right",
+ HEIGHT = "height",
+ WIDTH = "width",
+ POINTS = "points",
+ HIDDEN = "hidden",
+ ABSOLUTE = "absolute",
+ VISIBLE = "visible",
+ MOTION = "motion",
+ POSITION = "position",
+ EASEOUT = "easeOut",
+
+ flyEl = new Ext.Element.Flyweight(),
+ queues = {},
+ getObject = function(o){
+ return o || {};
+ },
+ fly = function(dom){
+ flyEl.dom = dom;
+ flyEl.id = Ext.id(dom);
+ return flyEl;
+ },
+
+ getQueue = function(id){
+ if(!queues[id]){
+ queues[id] = [];
+ }
+ return queues[id];
+ },
+ setQueue = function(id, value){
+ queues[id] = value;
+ };
+
+
+Ext.enableFx = TRUE;
+
+
+Ext.Fx = {
+
+
+
+ switchStatements : function(key, fn, argHash){
+ return fn.apply(this, argHash[key]);
+ },
+
+
+ slideIn : function(anchor, o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ st = dom.style,
+ xy,
+ r,
+ b,
+ wrap,
+ after,
+ st,
+ args,
+ pt,
+ bw,
+ bh;
+
+ anchor = anchor || "t";
+
+ me.queueFx(o, function(){
+ xy = fly(dom).getXY();
+
+ fly(dom).fixDisplay();
+
+
+ r = fly(dom).getFxRestore();
+ b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
+ b.right = b.x + b.width;
+ b.bottom = b.y + b.height;
+
+
+ fly(dom).setWidth(b.width).setHeight(b.height);
+
+
+ wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
+
+ st.visibility = VISIBLE;
+ st.position = ABSOLUTE;
+
+
+ function after(){
+ fly(dom).fxUnwrap(wrap, r.pos, o);
+ st.width = r.width;
+ st.height = r.height;
+ fly(dom).afterFx(o);
+ }
+
+
+ pt = {to: [b.x, b.y]};
+ bw = {to: b.width};
+ bh = {to: b.height};
+
+ function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
+ var ret = {};
+ fly(wrap).setWidth(ww).setHeight(wh);
+ if(fly(wrap)[sXY]){
+ fly(wrap)[sXY](sXYval);
+ }
+ style[s1] = style[s2] = "0";
+ if(w){
+ ret.width = w;
+ }
+ if(h){
+ ret.height = h;
+ }
+ if(p){
+ ret.points = p;
+ }
+ return ret;
+ };
+
+ args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
+ t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
+ l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
+ r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
+ b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
+ tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
+ bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
+ br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
+ tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
+ });
+
+ st.visibility = VISIBLE;
+ fly(wrap).show();
+
+ arguments.callee.anim = fly(wrap).fxanim(args,
+ o,
+ MOTION,
+ .5,
+ EASEOUT,
+ after);
+ });
+ return me;
+ },
+
+
+ slideOut : function(anchor, o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ st = dom.style,
+ xy = me.getXY(),
+ wrap,
+ r,
+ b,
+ a,
+ zero = {to: 0};
+
+ anchor = anchor || "t";
+
+ me.queueFx(o, function(){
+
+
+ r = fly(dom).getFxRestore();
+ b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
+ b.right = b.x + b.width;
+ b.bottom = b.y + b.height;
+
+
+ fly(dom).setWidth(b.width).setHeight(b.height);
+
+
+ wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
+
+ st.visibility = VISIBLE;
+ st.position = ABSOLUTE;
+ fly(wrap).setWidth(b.width).setHeight(b.height);
+
+ function after(){
+ o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
+ fly(dom).fxUnwrap(wrap, r.pos, o);
+ st.width = r.width;
+ st.height = r.height;
+ fly(dom).afterFx(o);
+ }
+
+ function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
+ var ret = {};
+
+ style[s1] = style[s2] = "0";
+ ret[p1] = v1;
+ if(p2){
+ ret[p2] = v2;
+ }
+ if(p3){
+ ret[p3] = v3;
+ }
+
+ return ret;
+ };
+
+ a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
+ t : [st, LEFT, BOTTOM, HEIGHT, zero],
+ l : [st, RIGHT, TOP, WIDTH, zero],
+ r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
+ b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
+ tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
+ bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
+ br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
+ tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
+ });
+
+ arguments.callee.anim = fly(wrap).fxanim(a,
+ o,
+ MOTION,
+ .5,
+ EASEOUT,
+ after);
+ });
+ return me;
+ },
+
+
+ puff : function(o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ st = dom.style,
+ width,
+ height,
+ r;
+
+ me.queueFx(o, function(){
+ width = fly(dom).getWidth();
+ height = fly(dom).getHeight();
+ fly(dom).clearOpacity();
+ fly(dom).show();
+
+
+ r = fly(dom).getFxRestore();
+
+ function after(){
+ o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
+ fly(dom).clearOpacity();
+ fly(dom).setPositioning(r.pos);
+ st.width = r.width;
+ st.height = r.height;
+ st.fontSize = '';
+ fly(dom).afterFx(o);
+ }
+
+ arguments.callee.anim = fly(dom).fxanim({
+ width : {to : fly(dom).adjustWidth(width * 2)},
+ height : {to : fly(dom).adjustHeight(height * 2)},
+ points : {by : [-width * .5, -height * .5]},
+ opacity : {to : 0},
+ fontSize: {to : 200, unit: "%"}
+ },
+ o,
+ MOTION,
+ .5,
+ EASEOUT,
+ after);
+ });
+ return me;
+ },
+
+
+ switchOff : function(o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ st = dom.style,
+ r;
+
+ me.queueFx(o, function(){
+ fly(dom).clearOpacity();
+ fly(dom).clip();
+
+
+ r = fly(dom).getFxRestore();
+
+ function after(){
+ o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
+ fly(dom).clearOpacity();
+ fly(dom).setPositioning(r.pos);
+ st.width = r.width;
+ st.height = r.height;
+ fly(dom).afterFx(o);
+ };
+
+ fly(dom).fxanim({opacity : {to : 0.3}},
+ NULL,
+ NULL,
+ .1,
+ NULL,
+ function(){
+ fly(dom).clearOpacity();
+ (function(){
+ fly(dom).fxanim({
+ height : {to : 1},
+ points : {by : [0, fly(dom).getHeight() * .5]}
+ },
+ o,
+ MOTION,
+ 0.3,
+ 'easeIn',
+ after);
+ }).defer(100);
+ });
+ });
+ return me;
+ },
+
+
+ highlight : function(color, o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ attr = o.attr || "backgroundColor",
+ a = {},
+ restore;
+
+ me.queueFx(o, function(){
+ fly(dom).clearOpacity();
+ fly(dom).show();
+
+ function after(){
+ dom.style[attr] = restore;
+ fly(dom).afterFx(o);
+ }
+ restore = dom.style[attr];
+ a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
+ arguments.callee.anim = fly(dom).fxanim(a,
+ o,
+ 'color',
+ 1,
+ 'easeIn',
+ after);
+ });
+ return me;
+ },
+
+
+ frame : function(color, count, o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ proxy,
+ active;
+
+ me.queueFx(o, function(){
+ color = color || '#C3DAF9';
+ if(color.length == 6){
+ color = '#' + color;
+ }
+ count = count || 1;
+ fly(dom).show();
+
+ var xy = fly(dom).getXY(),
+ b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
+ queue = function(){
+ proxy = fly(document.body || document.documentElement).createChild({
+ style:{
+ position : ABSOLUTE,
+ 'z-index': 35000,
+ border : '0px solid ' + color
+ }
+ });
+ return proxy.queueFx({}, animFn);
+ };
+
+
+ arguments.callee.anim = {
+ isAnimated: true,
+ stop: function() {
+ count = 0;
+ proxy.stopFx();
+ }
+ };
+
+ function animFn(){
+ var scale = Ext.isBorderBox ? 2 : 1;
+ active = proxy.anim({
+ 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 * scale},
+ width : {from : b.width, to : b.width + 20 * scale}
+ },{
+ duration: o.duration || 1,
+ callback: function() {
+ proxy.remove();
+ --count > 0 ? queue() : fly(dom).afterFx(o);
+ }
+ });
+ arguments.callee.anim = {
+ isAnimated: true,
+ stop: function(){
+ active.stop();
+ }
+ };
+ };
+ queue();
+ });
+ return me;
+ },
+
+
+ pause : function(seconds){
+ var dom = this.dom,
+ t;
+
+ this.queueFx({}, function(){
+ t = setTimeout(function(){
+ fly(dom).afterFx({});
+ }, seconds * 1000);
+ arguments.callee.anim = {
+ isAnimated: true,
+ stop: function(){
+ clearTimeout(t);
+ fly(dom).afterFx({});
+ }
+ };
+ });
+ return this;
+ },
+
+
+ fadeIn : function(o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ to = o.endOpacity || 1;
+
+ me.queueFx(o, function(){
+ fly(dom).setOpacity(0);
+ fly(dom).fixDisplay();
+ dom.style.visibility = VISIBLE;
+ arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
+ o, NULL, .5, EASEOUT, function(){
+ if(to == 1){
+ fly(dom).clearOpacity();
+ }
+ fly(dom).afterFx(o);
+ });
+ });
+ return me;
+ },
+
+
+ fadeOut : function(o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ style = dom.style,
+ to = o.endOpacity || 0;
+
+ me.queueFx(o, function(){
+ arguments.callee.anim = fly(dom).fxanim({
+ opacity : {to : to}},
+ o,
+ NULL,
+ .5,
+ EASEOUT,
+ function(){
+ if(to == 0){
+ Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ?
+ style.display = "none" :
+ style.visibility = HIDDEN;
+
+ fly(dom).clearOpacity();
+ }
+ fly(dom).afterFx(o);
+ });
+ });
+ return me;
+ },
+
+
+ scale : function(w, h, o){
+ this.shift(Ext.apply({}, o, {
+ width: w,
+ height: h
+ }));
+ return this;
+ },
+
+
+ shift : function(o){
+ o = getObject(o);
+ var dom = this.dom,
+ a = {};
+
+ this.queueFx(o, function(){
+ for (var prop in o) {
+ if (o[prop] != UNDEFINED) {
+ a[prop] = {to : o[prop]};
+ }
+ }
+
+ a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
+ a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;
+
+ if (a.x || a.y || a.xy) {
+ a.points = a.xy ||
+ {to : [ a.x ? a.x.to : fly(dom).getX(),
+ a.y ? a.y.to : fly(dom).getY()]};
+ }
+
+ arguments.callee.anim = fly(dom).fxanim(a,
+ o,
+ MOTION,
+ .35,
+ EASEOUT,
+ function(){
+ fly(dom).afterFx(o);
+ });
+ });
+ return this;
+ },
+
+
+ ghost : function(anchor, o){
+ o = getObject(o);
+ var me = this,
+ dom = me.dom,
+ st = dom.style,
+ a = {opacity: {to: 0}, points: {}},
+ pt = a.points,
+ r,
+ w,
+ h;
+
+ anchor = anchor || "b";
+
+ me.queueFx(o, function(){
+
+ r = fly(dom).getFxRestore();
+ w = fly(dom).getWidth();
+ h = fly(dom).getHeight();
+
+ function after(){
+ o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
+ fly(dom).clearOpacity();
+ fly(dom).setPositioning(r.pos);
+ st.width = r.width;
+ st.height = r.height;
+ fly(dom).afterFx(o);
+ }
+
+ pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
+ t : [0, -h],
+ l : [-w, 0],
+ r : [w, 0],
+ b : [0, h],
+ tl : [-w, -h],
+ bl : [-w, h],
+ br : [w, h],
+ tr : [w, -h]
+ });
+
+ arguments.callee.anim = fly(dom).fxanim(a,
+ o,
+ MOTION,
+ .5,
+ EASEOUT, after);
+ });
+ return me;
+ },
+
+
+ syncFx : function(){
+ var me = this;
+ me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
+ block : FALSE,
+ concurrent : TRUE,
+ stopFx : FALSE
+ });
+ return me;
+ },
+
+
+ sequenceFx : function(){
+ var me = this;
+ me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
+ block : FALSE,
+ concurrent : FALSE,
+ stopFx : FALSE
+ });
+ return me;
+ },
+
+
+ nextFx : function(){
+ var ef = getQueue(this.dom.id)[0];
+ if(ef){
+ ef.call(this);
+ }
+ },
+
+
+ hasActiveFx : function(){
+ return getQueue(this.dom.id)[0];
+ },
+
+
+ stopFx : function(finish){
+ var me = this,
+ id = me.dom.id;
+ if(me.hasActiveFx()){
+ var cur = getQueue(id)[0];
+ if(cur && cur.anim){
+ if(cur.anim.isAnimated){
+ setQueue(id, [cur]);
+ cur.anim.stop(finish !== undefined ? finish : TRUE);
+ }else{
+ setQueue(id, []);
+ }
+ }
+ }
+ return me;
+ },
+
+
+ beforeFx : function(o){
+ if(this.hasActiveFx() && !o.concurrent){
+ if(o.stopFx){
+ this.stopFx();
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return TRUE;
+ },
+
+
+ hasFxBlock : function(){
+ var q = getQueue(this.dom.id);
+ return q && q[0] && q[0].block;
+ },
+
+
+ queueFx : function(o, fn){
+ var me = fly(this.dom);
+ if(!me.hasFxBlock()){
+ Ext.applyIf(o, me.fxDefaults);
+ if(!o.concurrent){
+ var run = me.beforeFx(o);
+ fn.block = o.block;
+ getQueue(me.dom.id).push(fn);
+ if(run){
+ me.nextFx();
+ }
+ }else{
+ fn.call(me);
+ }
+ }
+ return me;
+ },
+
+
+ fxWrap : function(pos, o, vis){
+ var dom = this.dom,
+ wrap,
+ wrapXY;
+ if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){
+ if(o.fixPosition){
+ wrapXY = fly(dom).getXY();
+ }
+ var div = document.createElement("div");
+ div.style.visibility = vis;
+ wrap = dom.parentNode.insertBefore(div, dom);
+ fly(wrap).setPositioning(pos);
+ if(fly(wrap).isStyle(POSITION, "static")){
+ fly(wrap).position("relative");
+ }
+ fly(dom).clearPositioning('auto');
+ fly(wrap).clip();
+ wrap.appendChild(dom);
+ if(wrapXY){
+ fly(wrap).setXY(wrapXY);
+ }
+ }
+ return wrap;
+ },
+
+
+ fxUnwrap : function(wrap, pos, o){
+ var dom = this.dom;
+ fly(dom).clearPositioning();
+ fly(dom).setPositioning(pos);
+ if(!o.wrap){
+ var pn = fly(wrap).dom.parentNode;
+ pn.insertBefore(dom, wrap);
+ fly(wrap).remove();
+ }
+ },
+
+
+ getFxRestore : function(){
+ var st = this.dom.style;
+ return {pos: this.getPositioning(), width: st.width, height : st.height};
+ },
+
+
+ afterFx : function(o){
+ var dom = this.dom,
+ id = dom.id;
+ if(o.afterStyle){
+ fly(dom).setStyle(o.afterStyle);
+ }
+ if(o.afterCls){
+ fly(dom).addClass(o.afterCls);
+ }
+ if(o.remove == TRUE){
+ fly(dom).remove();
+ }
+ if(o.callback){
+ o.callback.call(o.scope, fly(dom));
+ }
+ if(!o.concurrent){
+ getQueue(id).shift();
+ fly(dom).nextFx();
+ }
+ },
+
+
+ fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
+ animType = animType || 'run';
+ opt = opt || {};
+ var anim = Ext.lib.Anim[animType](
+ this.dom,
+ args,
+ (opt.duration || defaultDur) || .35,
+ (opt.easing || defaultEase) || EASEOUT,
+ cb,
+ this
+ );
+ opt.anim = anim;
+ return anim;
+ }
+};
+
+
+Ext.Fx.resize = Ext.Fx.scale;
+
+
+
+Ext.Element.addMethods(Ext.Fx);
+})();
+
+Ext.CompositeElementLite = function(els, root){
+
+ this.elements = [];
+ this.add(els, root);
+ this.el = new Ext.Element.Flyweight();
+};
+
+Ext.CompositeElementLite.prototype = {
+ isComposite: true,
+
+
+ getElement : function(el){
+
+ var e = this.el;
+ e.dom = el;
+ e.id = el.id;
+ return e;
+ },
+
+
+ transformElement : function(el){
+ return Ext.getDom(el);
+ },
+
+
+ getCount : function(){
+ return this.elements.length;
+ },
+
+ add : function(els, root){
+ var me = this,
+ elements = me.elements;
+ if(!els){
+ return this;
+ }
+ if(typeof els == "string"){
+ els = Ext.Element.selectorFunction(els, root);
+ }else if(els.isComposite){
+ els = els.elements;
+ }else if(!Ext.isIterable(els)){
+ els = [els];
+ }
+
+ for(var i = 0, len = els.length; i < len; ++i){
+ elements.push(me.transformElement(els[i]));
+ }
+ return me;
+ },
+
+ invoke : function(fn, args){
+ var me = this,
+ els = me.elements,
+ len = els.length,
+ e,
+ i;
+
+ for(i = 0; i < len; i++) {
+ e = els[i];
+ if(e){
+ Ext.Element.prototype[fn].apply(me.getElement(e), args);
+ }
+ }
+ return me;
+ },
+
+ item : function(index){
+ var me = this,
+ el = me.elements[index],
+ out = null;
+
+ if(el){
+ out = me.getElement(el);
+ }
+ return out;
+ },
+
+
+ addListener : function(eventName, handler, scope, opt){
+ var els = this.elements,
+ len = els.length,
+ i, e;
+
+ for(i = 0; i<len; i++) {
+ e = els[i];
+ if(e) {
+ Ext.EventManager.on(e, eventName, handler, scope || e, opt);
+ }
+ }
+ return this;
+ },
+
+ each : function(fn, scope){
+ var me = this,
+ els = me.elements,
+ len = els.length,
+ i, e;
+
+ for(i = 0; i<len; i++) {
+ e = els[i];
+ if(e){
+ e = this.getElement(e);
+ if(fn.call(scope || e, e, me, i) === false){
+ break;
+ }
+ }
+ }
+ return me;
+ },
+
+
+ fill : function(els){
+ var me = this;
+ me.elements = [];
+ me.add(els);
+ return me;
+ },
+
+
+ filter : function(selector){
+ var els = [],
+ me = this,
+ fn = Ext.isFunction(selector) ? selector
+ : function(el){
+ return el.is(selector);
+ };
+
+ me.each(function(el, self, i) {
+ if (fn(el, i) !== false) {
+ els[els.length] = me.transformElement(el);
+ }
+ });
+
+ me.elements = els;
+ return me;
+ },
+
+
+ indexOf : function(el){
+ return this.elements.indexOf(this.transformElement(el));
+ },
+
+
+ replaceElement : function(el, replacement, domReplace){
+ var index = !isNaN(el) ? el : this.indexOf(el),
+ d;
+ if(index > -1){
+ replacement = Ext.getDom(replacement);
+ if(domReplace){
+ d = this.elements[index];
+ d.parentNode.insertBefore(replacement, d);
+ Ext.removeNode(d);
+ }
+ this.elements.splice(index, 1, replacement);
+ }
+ return this;
+ },
+
+
+ clear : function(){
+ this.elements = [];
+ }
+};
+
+Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
+
+
+Ext.CompositeElementLite.importElementMethods = function() {
+ var fnName,
+ ElProto = Ext.Element.prototype,
+ CelProto = Ext.CompositeElementLite.prototype;
+
+ for (fnName in ElProto) {
+ if (typeof ElProto[fnName] == 'function'){
+ (function(fnName) {
+ CelProto[fnName] = CelProto[fnName] || function() {
+ return this.invoke(fnName, arguments);
+ };
+ }).call(CelProto, fnName);
+
+ }
+ }
+};
+
+Ext.CompositeElementLite.importElementMethods();
+
+if(Ext.DomQuery){
+ Ext.Element.selectorFunction = Ext.DomQuery.select;
+}
+
+
+Ext.Element.select = function(selector, root){
+ var els;
+ if(typeof selector == "string"){
+ els = Ext.Element.selectorFunction(selector, root);
+ }else if(selector.length !== undefined){
+ els = selector;
+ }else{
+ throw "Invalid selector";
+ }
+ return new Ext.CompositeElementLite(els);
+};
+
+Ext.select = Ext.Element.select;
+(function(){
+ var BEFOREREQUEST = "beforerequest",
+ REQUESTCOMPLETE = "requestcomplete",
+ REQUESTEXCEPTION = "requestexception",
+ UNDEFINED = undefined,
+ LOAD = 'load',
+ POST = 'POST',
+ GET = 'GET',
+ WINDOW = window;
+
+
+ Ext.data.Connection = function(config){
+ Ext.apply(this, config);
+ this.addEvents(
+
+ BEFOREREQUEST,
+
+ REQUESTCOMPLETE,
+
+ REQUESTEXCEPTION
+ );
+ Ext.data.Connection.superclass.constructor.call(this);
+ };
+
+ Ext.extend(Ext.data.Connection, Ext.util.Observable, {
+
+
+
+
+
+ timeout : 30000,
+
+ autoAbort:false,
+
+
+ disableCaching: true,
+
+
+ disableCachingParam: '_dc',
+
+
+ request : function(o){
+ var me = this;
+ if(me.fireEvent(BEFOREREQUEST, me, o)){
+ if (o.el) {
+ if(!Ext.isEmpty(o.indicatorText)){
+ me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
+ }
+ if(me.indicatorText) {
+ Ext.getDom(o.el).innerHTML = me.indicatorText;
+ }
+ o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
+ Ext.getDom(o.el).innerHTML = response.responseText;
+ });
+ }
+
+ var p = o.params,
+ url = o.url || me.url,
+ method,
+ cb = {success: me.handleResponse,
+ failure: me.handleFailure,
+ scope: me,
+ argument: {options: o},
+ timeout : Ext.num(o.timeout, me.timeout)
+ },
+ form,
+ serForm;
+
+
+ if (Ext.isFunction(p)) {
+ p = p.call(o.scope||WINDOW, o);
+ }
+
+ p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
+
+ if (Ext.isFunction(url)) {
+ url = url.call(o.scope || WINDOW, o);
+ }
+
+ if((form = Ext.getDom(o.form))){
+ url = url || form.action;
+ if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) {
+ return me.doFormUpload.call(me, o, p, url);
+ }
+ serForm = Ext.lib.Ajax.serializeForm(form);
+ p = p ? (p + '&' + serForm) : serForm;
+ }
+
+ method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
+
+ if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
+ var dcp = o.disableCachingParam || me.disableCachingParam;
+ url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
+ }
+
+ o.headers = Ext.applyIf(o.headers || {}, me.defaultHeaders || {});
+
+ if(o.autoAbort === true || me.autoAbort) {
+ me.abort();
+ }
+
+ if((method == GET || o.xmlData || o.jsonData) && p){
+ url = Ext.urlAppend(url, p);
+ p = '';
+ }
+ return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
+ }else{
+ return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
+ }
+ },
+
+
+ isLoading : function(transId){
+ return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
+ },
+
+
+ abort : function(transId){
+ if(transId || this.isLoading()){
+ Ext.lib.Ajax.abort(transId || this.transId);
+ }
+ },
+
+
+ handleResponse : function(response){
+ this.transId = false;
+ var options = response.argument.options;
+ response.argument = options ? options.argument : null;
+ this.fireEvent(REQUESTCOMPLETE, this, response, options);
+ if(options.success){
+ options.success.call(options.scope, response, options);
+ }
+ if(options.callback){
+ options.callback.call(options.scope, options, true, response);
+ }
+ },
+
+
+ handleFailure : function(response, e){
+ this.transId = false;
+ var options = response.argument.options;
+ response.argument = options ? options.argument : null;
+ this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
+ if(options.failure){
+ options.failure.call(options.scope, response, options);
+ }
+ if(options.callback){
+ options.callback.call(options.scope, options, false, response);
+ }
+ },
+
+
+ doFormUpload : function(o, ps, url){
+ var id = Ext.id(),
+ doc = document,
+ frame = doc.createElement('iframe'),
+ form = Ext.getDom(o.form),
+ hiddens = [],
+ hd,
+ encoding = 'multipart/form-data',
+ buf = {
+ target: form.target,
+ method: form.method,
+ encoding: form.encoding,
+ enctype: form.enctype,
+ action: form.action
+ };
+
+
+ Ext.fly(frame).set({
+ id: id,
+ name: id,
+ cls: 'x-hidden',
+ src: Ext.SSL_SECURE_URL
+ });
+
+ doc.body.appendChild(frame);
+
+
+ if(Ext.isIE){
+ document.frames[id].name = id;
+ }
+
+
+ Ext.fly(form).set({
+ target: id,
+ method: POST,
+ enctype: encoding,
+ encoding: encoding,
+ action: url || buf.action
+ });
+
+
+ Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
+ hd = doc.createElement('input');
+ Ext.fly(hd).set({
+ type: 'hidden',
+ value: v,
+ name: k
+ });
+ form.appendChild(hd);
+ hiddens.push(hd);
+ });
+
+ function cb(){
+ var me = this,
+
+ r = {responseText : '',
+ responseXML : null,
+ argument : o.argument},
+ doc,
+ firstChild;
+
+ try{
+ doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
+ if(doc){
+ if(doc.body){
+ if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){
+ r.responseText = firstChild.value;
+ }else{
+ r.responseText = doc.body.innerHTML;
+ }
+ }
+
+ r.responseXML = doc.XMLDocument || doc;
+ }
+ }
+ catch(e) {}
+
+ Ext.EventManager.removeListener(frame, LOAD, cb, me);
+
+ me.fireEvent(REQUESTCOMPLETE, me, r, o);
+
+ function runCallback(fn, scope, args){
+ if(Ext.isFunction(fn)){
+ fn.apply(scope, args);
+ }
+ }
+
+ runCallback(o.success, o.scope, [r, o]);
+ runCallback(o.callback, o.scope, [o, true, r]);
+
+ if(!me.debugUploads){
+ setTimeout(function(){Ext.removeNode(frame);}, 100);
+ }
+ }
+
+ Ext.EventManager.on(frame, LOAD, cb, this);
+ form.submit();
+
+ Ext.fly(form).set(buf);
+ Ext.each(hiddens, function(h) {
+ Ext.removeNode(h);
+ });
+ }
+ });
+})();
+
+
+Ext.Ajax = new Ext.data.Connection({
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ autoAbort : false,
+
+
+ serializeForm : function(form){
+ return Ext.lib.Ajax.serializeForm(form);
+ }
+});
+
+Ext.util.JSON = new (function(){
+ var useHasOwn = !!{}.hasOwnProperty,
+ isNative = function() {
+ var useNative = null;
+
+ return function() {
+ if (useNative === null) {
+ useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
+ }
+
+ return useNative;
+ };
+ }(),
+ pad = function(n) {
+ return n < 10 ? "0" + n : n;
+ },
+ doDecode = function(json){
+ return json ? eval("(" + json + ")") : "";
+ },
+ doEncode = function(o){
+ if(!Ext.isDefined(o) || o === null){
+ return "null";
+ }else if(Ext.isArray(o)){
+ return encodeArray(o);
+ }else if(Ext.isDate(o)){
+ return Ext.util.JSON.encodeDate(o);
+ }else if(Ext.isString(o)){
+ return encodeString(o);
+ }else if(typeof o == "number"){
+
+ return isFinite(o) ? String(o) : "null";
+ }else if(Ext.isBoolean(o)){
+ return String(o);
+ }else {
+ var a = ["{"], b, i, v;
+ for (i in o) {
+
+ if(!o.getElementsByTagName){
+ if(!useHasOwn || o.hasOwnProperty(i)) {
+ v = o[i];
+ switch (typeof v) {
+ case "undefined":
+ case "function":
+ case "unknown":
+ break;
+ default:
+ if(b){
+ a.push(',');
+ }
+ a.push(doEncode(i), ":",
+ v === null ? "null" : doEncode(v));
+ b = true;
+ }
+ }
+ }
+ }
+ a.push("}");
+ return a.join("");
+ }
+ },
+ m = {
+ "\b": '\\b',
+ "\t": '\\t',
+ "\n": '\\n',
+ "\f": '\\f',
+ "\r": '\\r',
+ '"' : '\\"',
+ "\\": '\\\\'
+ },
+ encodeString = 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 + '"';
+ },
+ encodeArray = 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("");
+ };
+
+
+ this.encodeDate = function(o){
+ return '"' + o.getFullYear() + "-" +
+ pad(o.getMonth() + 1) + "-" +
+ pad(o.getDate()) + "T" +
+ pad(o.getHours()) + ":" +
+ pad(o.getMinutes()) + ":" +
+ pad(o.getSeconds()) + '"';
+ };
+
+
+ this.encode = function() {
+ var ec;
+ return function(o) {
+ if (!ec) {
+
+ ec = isNative() ? JSON.stringify : doEncode;
+ }
+ return ec(o);
+ };
+ }();
+
+
+
+ this.decode = function() {
+ var dc;
+ return function(json) {
+ if (!dc) {
+
+ dc = isNative() ? JSON.parse : doDecode;
+ }
+ return dc(json);
+ };
+ }();
+
+})();
+
+Ext.encode = Ext.util.JSON.encode;
+
+Ext.decode = Ext.util.JSON.decode;
+
+Ext.EventManager = function(){
+ var docReadyEvent,
+ docReadyProcId,
+ docReadyState = false,
+ DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari || Ext.isIE10p,
+ E = Ext.lib.Event,
+ D = Ext.lib.Dom,
+ DOC = document,
+ WINDOW = window,
+ DOMCONTENTLOADED = "DOMContentLoaded",
+ COMPLETE = 'complete',
+ propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
+
+ specialElCache = [];
+
+ function getId(el){
+ var id = false,
+ i = 0,
+ len = specialElCache.length,
+ skip = false,
+ o;
+
+ if (el) {
+ if (el.getElementById || el.navigator) {
+
+ for(; i < len; ++i){
+ o = specialElCache[i];
+ if(o.el === el){
+ id = o.id;
+ break;
+ }
+ }
+ if(!id){
+
+ id = Ext.id(el);
+ specialElCache.push({
+ id: id,
+ el: el
+ });
+ skip = true;
+ }
+ }else{
+ id = Ext.id(el);
+ }
+ if(!Ext.elCache[id]){
+ Ext.Element.addToCache(new Ext.Element(el), id);
+ if(skip){
+ Ext.elCache[id].skipGC = true;
+ }
+ }
+ }
+ return id;
+ }
+
+
+ function addListener(el, ename, fn, task, wrap, scope){
+ el = Ext.getDom(el);
+ var id = getId(el),
+ es = Ext.elCache[id].events,
+ wfn;
+
+ wfn = E.on(el, ename, wrap);
+ es[ename] = es[ename] || [];
+
+
+ es[ename].push([fn, wrap, scope, wfn, task]);
+
+
+
+
+
+ if(el.addEventListener && ename == "mousewheel"){
+ var args = ["DOMMouseScroll", wrap, false];
+ el.addEventListener.apply(el, args);
+ Ext.EventManager.addListener(WINDOW, 'unload', function(){
+ el.removeEventListener.apply(el, args);
+ });
+ }
+
+
+ if(el == DOC && ename == "mousedown"){
+ Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
+ }
+ }
+
+ function doScrollChk(){
+
+ if(window != top){
+ return false;
+ }
+
+ try{
+ DOC.documentElement.doScroll('left');
+ }catch(e){
+ return false;
+ }
+
+ fireDocReady();
+ return true;
+ }
+
+ function checkReadyState(e){
+
+ if(Ext.isIE9m && doScrollChk()){
+ return true;
+ }
+ if(DOC.readyState == COMPLETE){
+ fireDocReady();
+ return true;
+ }
+ docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
+ return false;
+ }
+
+ var styles;
+ function checkStyleSheets(e){
+ styles || (styles = Ext.query('style, link[rel=stylesheet]'));
+ if(styles.length == DOC.styleSheets.length){
+ fireDocReady();
+ return true;
+ }
+ docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
+ return false;
+ }
+
+ function OperaDOMContentLoaded(e){
+ DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
+ checkStyleSheets();
+ }
+
+ function fireDocReady(e){
+ if(!docReadyState){
+ docReadyState = true;
+
+ if(docReadyProcId){
+ clearTimeout(docReadyProcId);
+ }
+ if(DETECT_NATIVE) {
+ DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
+ }
+ if(Ext.isIE9m && checkReadyState.bindIE){
+ DOC.detachEvent('onreadystatechange', checkReadyState);
+ }
+ E.un(WINDOW, "load", arguments.callee);
+ }
+ if(docReadyEvent && !Ext.isReady){
+ Ext.isReady = true;
+ docReadyEvent.fire();
+ docReadyEvent.listeners = [];
+ }
+
+ }
+
+ function initDocReady(){
+ docReadyEvent || (docReadyEvent = new Ext.util.Event());
+ if (DETECT_NATIVE) {
+ DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
+ }
+
+ if (Ext.isIE9m){
+
+
+ if(!checkReadyState()){
+ checkReadyState.bindIE = true;
+ DOC.attachEvent('onreadystatechange', checkReadyState);
+ }
+
+ }else if(Ext.isOpera ){
+
+
+
+ (DOC.readyState == COMPLETE && checkStyleSheets()) ||
+ DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
+
+ }else if (Ext.isWebKit){
+
+ checkReadyState();
+ }
+
+ E.on(WINDOW, "load", fireDocReady);
+ }
+
+ function createTargeted(h, o){
+ return function(){
+ var args = Ext.toArray(arguments);
+ if(o.target == Ext.EventObject.setEvent(args[0]).target){
+ h.apply(this, args);
+ }
+ };
+ }
+
+ function createBuffered(h, o, task){
+ return function(e){
+
+ task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
+ };
+ }
+
+ function createSingle(h, el, ename, fn, scope){
+ return function(e){
+ Ext.EventManager.removeListener(el, ename, fn, scope);
+ h(e);
+ };
+ }
+
+ function createDelayed(h, o, fn){
+ return function(e){
+ var task = new Ext.util.DelayedTask(h);
+ if(!fn.tasks) {
+ fn.tasks = [];
+ }
+ fn.tasks.push(task);
+ task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
+ };
+ }
+
+ function listen(element, ename, opt, fn, scope){
+ var o = (!opt || typeof opt == "boolean") ? {} : opt,
+ el = Ext.getDom(element), task;
+
+ fn = fn || o.fn;
+ scope = scope || o.scope;
+
+ if(!el){
+ throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
+ }
+ function h(e){
+
+ if(!Ext){
+ return;
+ }
+ e = Ext.EventObject.setEvent(e);
+ var t;
+ if (o.delegate) {
+ if(!(t = e.getTarget(o.delegate, el))){
+ return;
+ }
+ } else {
+ t = e.target;
+ }
+ if (o.stopEvent) {
+ e.stopEvent();
+ }
+ if (o.preventDefault) {
+ e.preventDefault();
+ }
+ if (o.stopPropagation) {
+ e.stopPropagation();
+ }
+ if (o.normalized === false) {
+ e = e.browserEvent;
+ }
+
+ fn.call(scope || el, e, t, o);
+ }
+ if(o.target){
+ h = createTargeted(h, o);
+ }
+ if(o.delay){
+ h = createDelayed(h, o, fn);
+ }
+ if(o.single){
+ h = createSingle(h, el, ename, fn, scope);
+ }
+ if(o.buffer){
+ task = new Ext.util.DelayedTask(h);
+ h = createBuffered(h, o, task);
+ }
+
+ addListener(el, ename, fn, task, h, scope);
+ return h;
+ }
+
+ var pub = {
+
+ addListener : function(element, eventName, fn, scope, options){
+ if(typeof eventName == 'object'){
+ var o = eventName, e, val;
+ for(e in o){
+ val = o[e];
+ if(!propRe.test(e)){
+ if(Ext.isFunction(val)){
+
+ listen(element, e, o, val, o.scope);
+ }else{
+
+ listen(element, e, val);
+ }
+ }
+ }
+ } else {
+ listen(element, eventName, options, fn, scope);
+ }
+ },
+
+
+ removeListener : function(el, eventName, fn, scope){
+ el = Ext.getDom(el);
+ var id = getId(el),
+ f = el && (Ext.elCache[id].events)[eventName] || [],
+ wrap, i, l, k, len, fnc;
+
+ for (i = 0, len = f.length; i < len; i++) {
+
+
+ if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
+ if(fnc[4]) {
+ fnc[4].cancel();
+ }
+ k = fn.tasks && fn.tasks.length;
+ if(k) {
+ while(k--) {
+ fn.tasks[k].cancel();
+ }
+ delete fn.tasks;
+ }
+ wrap = fnc[1];
+ E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
+
+
+ if(wrap && el.addEventListener && eventName == "mousewheel"){
+ el.removeEventListener("DOMMouseScroll", wrap, false);
+ }
+
+
+ if(wrap && el == DOC && eventName == "mousedown"){
+ Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
+ }
+
+ f.splice(i, 1);
+ if (f.length === 0) {
+ delete Ext.elCache[id].events[eventName];
+ }
+ for (k in Ext.elCache[id].events) {
+ return false;
+ }
+ Ext.elCache[id].events = {};
+ return false;
+ }
+ }
+ },
+
+
+ removeAll : function(el){
+ el = Ext.getDom(el);
+ var id = getId(el),
+ ec = Ext.elCache[id] || {},
+ es = ec.events || {},
+ f, i, len, ename, fn, k, wrap;
+
+ for(ename in es){
+ if(es.hasOwnProperty(ename)){
+ f = es[ename];
+
+ for (i = 0, len = f.length; i < len; i++) {
+ fn = f[i];
+ if(fn[4]) {
+ fn[4].cancel();
+ }
+ if(fn[0].tasks && (k = fn[0].tasks.length)) {
+ while(k--) {
+ fn[0].tasks[k].cancel();
+ }
+ delete fn.tasks;
+ }
+ wrap = fn[1];
+ E.un(el, ename, E.extAdapter ? fn[3] : wrap);
+
+
+ if(el.addEventListener && wrap && ename == "mousewheel"){
+ el.removeEventListener("DOMMouseScroll", wrap, false);
+ }
+
+
+ if(wrap && el == DOC && ename == "mousedown"){
+ Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
+ }
+ }
+ }
+ }
+ if (Ext.elCache[id]) {
+ Ext.elCache[id].events = {};
+ }
+ },
+
+ getListeners : function(el, eventName) {
+ el = Ext.getDom(el);
+ var id = getId(el),
+ ec = Ext.elCache[id] || {},
+ es = ec.events || {},
+ results = [];
+ if (es && es[eventName]) {
+ return es[eventName];
+ } else {
+ return null;
+ }
+ },
+
+ removeFromSpecialCache: function(o) {
+ var i = 0,
+ len = specialElCache.length;
+
+ for (; i < len; ++i) {
+ if (specialElCache[i].el == o) {
+ specialElCache.splice(i, 1);
+ }
+ }
+ },
+
+ purgeElement : function(el, recurse, eventName) {
+ el = Ext.getDom(el);
+ var id = getId(el),
+ ec = Ext.elCache[id] || {},
+ es = ec.events || {},
+ i, f, len;
+ if (eventName) {
+ if (es && es.hasOwnProperty(eventName)) {
+ f = es[eventName];
+ for (i = 0, len = f.length; i < len; i++) {
+ Ext.EventManager.removeListener(el, eventName, f[i][0]);
+ }
+ }
+ } else {
+ Ext.EventManager.removeAll(el);
+ }
+ if (recurse && el && el.childNodes) {
+ for (i = 0, len = el.childNodes.length; i < len; i++) {
+ Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
+ }
+ }
+ },
+
+ _unload : function() {
+ var el;
+ for (el in Ext.elCache) {
+ Ext.EventManager.removeAll(el);
+ }
+ delete Ext.elCache;
+ delete Ext.Element._flyweights;
+
+
+ var c,
+ conn,
+ tid,
+ ajax = Ext.lib.Ajax;
+ (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
+ for (tid in conn) {
+ c = conn[tid];
+ if (c) {
+ ajax.abort({conn: c, tId: tid});
+ }
+ }
+ },
+
+ onDocumentReady : function(fn, scope, options){
+ if (Ext.isReady) {
+ docReadyEvent || (docReadyEvent = new Ext.util.Event());
+ docReadyEvent.addListener(fn, scope, options);
+ docReadyEvent.fire();
+ docReadyEvent.listeners = [];
+ } else {
+ if (!docReadyEvent) {
+ initDocReady();
+ }
+ options = options || {};
+ options.delay = options.delay || 1;
+ docReadyEvent.addListener(fn, scope, options);
+ }
+ },
+
+
+ fireDocReady : fireDocReady
+ };
+
+ pub.on = pub.addListener;
+
+ pub.un = pub.removeListener;
+
+ pub.stoppedMouseDownEvent = new Ext.util.Event();
+ return pub;
+}();
+
+Ext.onReady = Ext.EventManager.onDocumentReady;
+
+
+
+(function(){
+ var initExtCss = function() {
+
+ var bd = document.body || document.getElementsByTagName('body')[0];
+ if (!bd) {
+ return false;
+ }
+
+ var cls = [];
+
+ if (Ext.isIE) {
+
+ if (!Ext.isIE10p) {
+ cls.push('ext-ie');
+ }
+ if (Ext.isIE6) {
+ cls.push('ext-ie6');
+ } else if (Ext.isIE7) {
+ cls.push('ext-ie7', 'ext-ie7m');
+ } else if (Ext.isIE8) {
+ cls.push('ext-ie8', 'ext-ie8m');
+ } else if (Ext.isIE9) {
+ cls.push('ext-ie9', 'ext-ie9m');
+ } else if (Ext.isIE10) {
+ cls.push('ext-ie10');
+ }
+ }
+
+ if (Ext.isGecko) {
+ if (Ext.isGecko2) {
+ cls.push('ext-gecko2');
+ } else {
+ cls.push('ext-gecko3');
+ }
+ }
+
+ if (Ext.isOpera) {
+ cls.push('ext-opera');
+ }
+
+ if (Ext.isWebKit) {
+ cls.push('ext-webkit');
+ }
+
+ if (Ext.isSafari) {
+ cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
+ } else if(Ext.isChrome) {
+ cls.push("ext-chrome");
+ }
+
+ if (Ext.isMac) {
+ cls.push("ext-mac");
+ }
+ if (Ext.isLinux) {
+ cls.push("ext-linux");
+ }
+
+
+ if (Ext.isStrict || Ext.isBorderBox) {
+ var p = bd.parentNode;
+ if (p) {
+ if (!Ext.isStrict) {
+ Ext.fly(p, '_internal').addClass('x-quirks');
+ if (Ext.isIE9m && !Ext.isStrict) {
+ Ext.isIEQuirks = true;
+ }
+ }
+ Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box');
+ }
+ }
+
+
+ if (Ext.enableForcedBoxModel && !Ext.isIE) {
+ Ext.isForcedBorderBox = true;
+ cls.push("ext-forced-border-box");
+ }
+
+ Ext.fly(bd, '_internal').addClass(cls);
+ return true;
+ };
+
+ if (!initExtCss()) {
+ Ext.onReady(initExtCss);
+ }
+})();
+
+
+(function(){
+
+ var supports = Ext.apply(Ext.supports, {
+
+ correctRightMargin: true,
+
+
+ correctTransparentColor: true,
+
+
+ cssFloat: true
+ });
+
+ var supportTests = function(){
+ var div = document.createElement('div'),
+ doc = document,
+ view,
+ last;
+
+ div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
+ doc.body.appendChild(div);
+ last = div.lastChild;
+
+ if((view = doc.defaultView)){
+ if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
+ supports.correctRightMargin = false;
+ }
+ if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
+ supports.correctTransparentColor = false;
+ }
+ }
+ supports.cssFloat = !!last.style.cssFloat;
+ doc.body.removeChild(div);
+ };
+
+ if (Ext.isReady) {
+ supportTests();
+ } else {
+ Ext.onReady(supportTests);
+ }
+})();
+
+
+
+Ext.EventObject = function(){
+ var E = Ext.lib.Event,
+ clickRe = /(dbl)?click/,
+
+ safariKeys = {
+ 3 : 13,
+ 63234 : 37,
+ 63235 : 39,
+ 63232 : 38,
+ 63233 : 40,
+ 63276 : 33,
+ 63277 : 34,
+ 63272 : 46,
+ 63273 : 36,
+ 63275 : 35
+ },
+
+ btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
+
+ Ext.EventObjectImpl = function(e){
+ if(e){
+ this.setEvent(e.browserEvent || e);
+ }
+ };
+
+ Ext.EventObjectImpl.prototype = {
+
+ setEvent : function(e){
+ var me = this;
+ if(e == me || (e && e.browserEvent)){
+ return e;
+ }
+ me.browserEvent = e;
+ if(e){
+
+ me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
+ if(clickRe.test(e.type) && me.button == -1){
+ me.button = 0;
+ }
+ me.type = e.type;
+ me.shiftKey = e.shiftKey;
+
+ me.ctrlKey = e.ctrlKey || e.metaKey || false;
+ me.altKey = e.altKey;
+
+ me.keyCode = e.keyCode;
+ me.charCode = e.charCode;
+
+ me.target = E.getTarget(e);
+
+ me.xy = E.getXY(e);
+ }else{
+ me.button = -1;
+ me.shiftKey = false;
+ me.ctrlKey = false;
+ me.altKey = false;
+ me.keyCode = 0;
+ me.charCode = 0;
+ me.target = null;
+ me.xy = [0, 0];
+ }
+ return me;
+ },
+
+
+ stopEvent : function(){
+ var me = this;
+ if(me.browserEvent){
+ if(me.browserEvent.type == 'mousedown'){
+ Ext.EventManager.stoppedMouseDownEvent.fire(me);
+ }
+ E.stopEvent(me.browserEvent);
+ }
+ },
+
+
+ preventDefault : function(){
+ if(this.browserEvent){
+ E.preventDefault(this.browserEvent);
+ }
+ },
+
+
+ stopPropagation : function(){
+ var me = this;
+ if(me.browserEvent){
+ if(me.browserEvent.type == 'mousedown'){
+ Ext.EventManager.stoppedMouseDownEvent.fire(me);
+ }
+ E.stopPropagation(me.browserEvent);
+ }
+ },
+
+
+ getCharCode : function(){
+ return this.charCode || this.keyCode;
+ },
+
+
+ getKey : function(){
+ return this.normalizeKey(this.keyCode || this.charCode);
+ },
+
+
+ normalizeKey: function(k){
+ return Ext.isSafari ? (safariKeys[k] || k) : k;
+ },
+
+
+ getPageX : function(){
+ return this.xy[0];
+ },
+
+
+ getPageY : function(){
+ return this.xy[1];
+ },
+
+
+ getXY : function(){
+ return this.xy;
+ },
+
+
+ getTarget : function(selector, maxDepth, returnEl){
+ return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
+ },
+
+
+ getRelatedTarget : function(){
+ return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
+ },
+
+
+ getWheelDelta : function(){
+ var e = this.browserEvent;
+ var delta = 0;
+ if(e.wheelDelta){
+ delta = e.wheelDelta/120;
+ }else if(e.detail){
+ delta = -e.detail/3;
+ }
+ return delta;
+ },
+
+
+ within : function(el, related, allowEl){
+ if(el){
+ var t = this[related ? "getRelatedTarget" : "getTarget"]();
+ return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
+ }
+ return false;
+ }
+ };
+
+ return new Ext.EventObjectImpl();
+}();
+Ext.Loader = Ext.apply({}, {
+
+ load: function(fileList, callback, scope, preserveOrder) {
+ var scope = scope || this,
+ head = document.getElementsByTagName("head")[0],
+ fragment = document.createDocumentFragment(),
+ numFiles = fileList.length,
+ loadedFiles = 0,
+ me = this;
+
+
+ var loadFileIndex = function(index) {
+ head.appendChild(
+ me.buildScriptTag(fileList[index], onFileLoaded)
+ );
+ };
+
+
+ var onFileLoaded = function() {
+ loadedFiles ++;
+
+
+ if (numFiles == loadedFiles && typeof callback == 'function') {
+ callback.call(scope);
+ } else {
+ if (preserveOrder === true) {
+ loadFileIndex(loadedFiles);
+ }
+ }
+ };
+
+ if (preserveOrder === true) {
+ loadFileIndex.call(this, 0);
+ } else {
+
+ Ext.each(fileList, function(file, index) {
+ fragment.appendChild(
+ this.buildScriptTag(file, onFileLoaded)
+ );
+ }, this);
+
+ head.appendChild(fragment);
+ }
+ },
+
+
+ buildScriptTag: function(filename, callback) {
+ var script = document.createElement('script');
+ script.type = "text/javascript";
+ script.src = filename;
+
+
+ if (script.readyState) {
+ script.onreadystatechange = function() {
+ if (script.readyState == "loaded" || script.readyState == "complete") {
+ script.onreadystatechange = null;
+ callback();
+ }
+ };
+ } else {
+ script.onload = callback;
+ }
+
+ return script;
+ }
+});
+
+
+Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
+ "Ext.state", "Ext.layout.boxOverflow", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct", "Ext.slider");
+
+
+Ext.apply(Ext, function(){
+ var E = Ext,
+ idSeed = 0,
+ scrollWidth = null;
+
+ return {
+
+ emptyFn : function(){},
+
+
+ BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
+ 'http:/' + '/www.extjs.com/s.gif' :
+ 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
+
+ extendX : function(supr, fn){
+ return Ext.extend(supr, fn(supr.prototype));
+ },
+
+
+ getDoc : function(){
+ return Ext.get(document);
+ },
+
+
+ num : function(v, defaultValue){
+ v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
+ return isNaN(v) ? defaultValue : v;
+ },
+
+
+ value : function(v, defaultValue, allowBlank){
+ return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
+ },
+
+
+ escapeRe : function(s) {
+ return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
+ },
+
+ sequence : function(o, name, fn, scope){
+ o[name] = o[name].createSequence(fn, scope);
+ },
+
+
+ addBehaviors : function(o){
+ if(!Ext.isReady){
+ Ext.onReady(function(){
+ Ext.addBehaviors(o);
+ });
+ } else {
+ var cache = {},
+ parts,
+ b,
+ s;
+ for (b in o) {
+ if ((parts = b.split('@'))[1]) {
+ s = parts[0];
+ if(!cache[s]){
+ cache[s] = Ext.select(s);
+ }
+ cache[s].on(parts[1], o[b]);
+ }
+ }
+ cache = null;
+ }
+ },
+
+
+ getScrollBarWidth: function(force){
+ if(!Ext.isReady){
+ return 0;
+ }
+
+ if(force === true || scrollWidth === null){
+
+ var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
+ child = div.child('div', true);
+ var w1 = child.offsetWidth;
+ div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
+ var w2 = child.offsetWidth;
+ div.remove();
+
+ scrollWidth = w1 - w2 + 2;
+ }
+ return scrollWidth;
+ },
+
+
+
+ combine : function(){
+ var as = arguments, l = as.length, r = [];
+ for(var i = 0; i < l; i++){
+ var a = as[i];
+ if(Ext.isArray(a)){
+ 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;
+ },
+
+
+ copyTo : function(dest, source, names){
+ if(typeof names == 'string'){
+ names = names.split(/[,;\s]/);
+ }
+ Ext.each(names, function(name){
+ if(source.hasOwnProperty(name)){
+ dest[name] = source[name];
+ }
+ }, this);
+ return dest;
+ },
+
+
+ destroy : function(){
+ Ext.each(arguments, function(arg){
+ if(arg){
+ if(Ext.isArray(arg)){
+ this.destroy.apply(this, arg);
+ }else if(typeof arg.destroy == 'function'){
+ arg.destroy();
+ }else if(arg.dom){
+ arg.remove();
+ }
+ }
+ }, this);
+ },
+
+
+ destroyMembers : function(o, arg1, arg2, etc){
+ for(var i = 1, a = arguments, len = a.length; i < len; i++) {
+ Ext.destroy(o[a[i]]);
+ delete o[a[i]];
+ }
+ },
+
+
+ clean : function(arr){
+ var ret = [];
+ Ext.each(arr, function(v){
+ if(!!v){
+ ret.push(v);
+ }
+ });
+ return ret;
+ },
+
+
+ unique : function(arr){
+ var ret = [],
+ collect = {};
+
+ Ext.each(arr, function(v) {
+ if(!collect[v]){
+ ret.push(v);
+ }
+ collect[v] = true;
+ });
+ return ret;
+ },
+
+
+ flatten : function(arr){
+ var worker = [];
+ function rFlatten(a) {
+ Ext.each(a, function(v) {
+ if(Ext.isArray(v)){
+ rFlatten(v);
+ }else{
+ worker.push(v);
+ }
+ });
+ return worker;
+ }
+ return rFlatten(arr);
+ },
+
+
+ min : function(arr, comp){
+ var ret = arr[0];
+ comp = comp || function(a,b){ return a < b ? -1 : 1; };
+ Ext.each(arr, function(v) {
+ ret = comp(ret, v) == -1 ? ret : v;
+ });
+ return ret;
+ },
+
+
+ max : function(arr, comp){
+ var ret = arr[0];
+ comp = comp || function(a,b){ return a > b ? 1 : -1; };
+ Ext.each(arr, function(v) {
+ ret = comp(ret, v) == 1 ? ret : v;
+ });
+ return ret;
+ },
+
+
+ mean : function(arr){
+ return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
+ },
+
+
+ sum : function(arr){
+ var ret = 0;
+ Ext.each(arr, function(v) {
+ ret += v;
+ });
+ return ret;
+ },
+
+
+ partition : function(arr, truth){
+ var ret = [[],[]];
+ Ext.each(arr, function(v, i, a) {
+ ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
+ });
+ return ret;
+ },
+
+
+ invoke : function(arr, methodName){
+ var ret = [],
+ args = Array.prototype.slice.call(arguments, 2);
+ Ext.each(arr, function(v,i) {
+ if (v && typeof v[methodName] == 'function') {
+ ret.push(v[methodName].apply(v, args));
+ } else {
+ ret.push(undefined);
+ }
+ });
+ return ret;
+ },
+
+
+ pluck : function(arr, prop){
+ var ret = [];
+ Ext.each(arr, function(v) {
+ ret.push( v[prop] );
+ });
+ return ret;
+ },
+
+
+ zip : function(){
+ var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
+ arrs = parts[0],
+ fn = parts[1][0],
+ len = Ext.max(Ext.pluck(arrs, "length")),
+ ret = [];
+
+ for (var i = 0; i < len; i++) {
+ ret[i] = [];
+ if(fn){
+ ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
+ }else{
+ for (var j = 0, aLen = arrs.length; j < aLen; j++){
+ ret[i].push( arrs[j][i] );
+ }
+ }
+ }
+ return ret;
+ },
+
+
+ getCmp : function(id){
+ return Ext.ComponentMgr.get(id);
+ },
+
+
+ useShims: E.isIE6 || (E.isMac && E.isGecko2),
+
+
+
+ type : function(o){
+ if(o === undefined || o === null){
+ return false;
+ }
+ if(o.htmlElement){
+ return 'element';
+ }
+ var t = typeof o;
+ if(t == 'object' && o.nodeName) {
+ switch(o.nodeType) {
+ case 1: return 'element';
+ case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
+ }
+ }
+ if(t == 'object' || t == 'function') {
+ switch(o.constructor) {
+ case Array: return 'array';
+ case RegExp: return 'regexp';
+ case Date: return 'date';
+ }
+ if(typeof o.length == 'number' && typeof o.item == 'function') {
+ return 'nodelist';
+ }
+ }
+ return t;
+ },
+
+ intercept : function(o, name, fn, scope){
+ o[name] = o[name].createInterceptor(fn, scope);
+ },
+
+
+ callback : function(cb, scope, args, delay){
+ if(typeof cb == 'function'){
+ if(delay){
+ cb.defer(delay, scope, args || []);
+ }else{
+ cb.apply(scope, args || []);
+ }
+ }
+ }
+ };
+}());
+
+
+Ext.apply(Function.prototype, {
+
+ createSequence : function(fcn, scope){
+ var method = this;
+ return (typeof fcn != 'function') ?
+ this :
+ function(){
+ var retval = method.apply(this || window, arguments);
+ fcn.apply(scope || this || window, arguments);
+ return retval;
+ };
+ }
+});
+
+
+
+Ext.applyIf(String, {
+
+
+ escape : function(string) {
+ return string.replace(/('|\\)/g, "\\$1");
+ },
+
+
+ leftPad : function (val, size, ch) {
+ var result = String(val);
+ if(!ch) {
+ ch = " ";
+ }
+ while (result.length < size) {
+ result = ch + result;
+ }
+ return result;
+ }
+});
+
+
+String.prototype.toggle = function(value, other){
+ return this == value ? other : value;
+};
+
+
+String.prototype.trim = function(){
+ var re = /^\s+|\s+$/g;
+ return function(){ return this.replace(re, ""); };
+}();
+
+
+
+Date.prototype.getElapsed = function(date) {
+ return Math.abs((date || new Date()).getTime()-this.getTime());
+};
+
+
+
+Ext.applyIf(Number.prototype, {
+
+ constrain : function(min, max){
+ return Math.min(Math.max(this, min), max);
+ }
+});
+Ext.lib.Dom.getRegion = function(el) {
+ return Ext.lib.Region.getRegion(el);
+}; Ext.lib.Region = function(t, r, b, l) {
+ var me = this;
+ me.top = t;
+ me[1] = t;
+ me.right = r;
+ me.bottom = b;
+ me.left = l;
+ me[0] = l;
+ };
+
+ Ext.lib.Region.prototype = {
+ contains : function(region) {
+ var me = this;
+ return ( region.left >= me.left &&
+ region.right <= me.right &&
+ region.top >= me.top &&
+ region.bottom <= me.bottom );
+
+ },
+
+ getArea : function() {
+ var me = this;
+ return ( (me.bottom - me.top) * (me.right - me.left) );
+ },
+
+ intersect : function(region) {
+ var me = this,
+ t = Math.max(me.top, region.top),
+ r = Math.min(me.right, region.right),
+ b = Math.min(me.bottom, region.bottom),
+ l = Math.max(me.left, region.left);
+
+ if (b >= t && r >= l) {
+ return new Ext.lib.Region(t, r, b, l);
+ }
+ },
+
+ union : function(region) {
+ var me = this,
+ t = Math.min(me.top, region.top),
+ r = Math.max(me.right, region.right),
+ b = Math.max(me.bottom, region.bottom),
+ l = Math.min(me.left, region.left);
+
+ return new Ext.lib.Region(t, r, b, l);
+ },
+
+ constrainTo : function(r) {
+ var me = this;
+ me.top = me.top.constrain(r.top, r.bottom);
+ me.bottom = me.bottom.constrain(r.top, r.bottom);
+ me.left = me.left.constrain(r.left, r.right);
+ me.right = me.right.constrain(r.left, r.right);
+ return me;
+ },
+
+ adjust : function(t, l, b, r) {
+ var me = this;
+ me.top += t;
+ me.left += l;
+ me.right += r;
+ me.bottom += b;
+ return me;
+ }
+ };
+
+ Ext.lib.Region.getRegion = function(el) {
+ var p = Ext.lib.Dom.getXY(el),
+ t = p[1],
+ r = p[0] + el.offsetWidth,
+ b = p[1] + el.offsetHeight,
+ l = p[0];
+
+ return new Ext.lib.Region(t, r, b, l);
+ }; Ext.lib.Point = function(x, y) {
+ if (Ext.isArray(x)) {
+ y = x[1];
+ x = x[0];
+ }
+ var me = this;
+ me.x = me.right = me.left = me[0] = x;
+ me.y = me.top = me.bottom = me[1] = y;
+ };
+
+ Ext.lib.Point.prototype = new Ext.lib.Region();
+
+Ext.apply(Ext.DomHelper,
+function(){
+ var pub,
+ afterbegin = 'afterbegin',
+ afterend = 'afterend',
+ beforebegin = 'beforebegin',
+ beforeend = 'beforeend',
+ confRe = /tag|children|cn|html$/i;
+
+
+ function doInsert(el, o, returnElement, pos, sibling, append){
+ el = Ext.getDom(el);
+ var newNode;
+ if (pub.useDom) {
+ newNode = createDom(o, null);
+ if (append) {
+ el.appendChild(newNode);
+ } else {
+ (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
+ }
+ } else {
+ newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
+ }
+ return returnElement ? Ext.get(newNode, true) : newNode;
+ }
+
+
+
+ function createDom(o, parentNode){
+ var el,
+ doc = document,
+ useSet,
+ attr,
+ val,
+ cn;
+
+ if (Ext.isArray(o)) {
+ el = doc.createDocumentFragment();
+ for (var i = 0, l = o.length; i < l; i++) {
+ createDom(o[i], el);
+ }
+ } else if (typeof o == 'string') {
+ el = doc.createTextNode(o);
+ } else {
+ el = doc.createElement( o.tag || 'div' );
+ useSet = !!el.setAttribute;
+ for (var attr in o) {
+ if(!confRe.test(attr)){
+ val = o[attr];
+ if(attr == 'cls'){
+ el.className = val;
+ }else{
+ if(useSet){
+ el.setAttribute(attr, val);
+ }else{
+ el[attr] = val;
+ }
+ }
+ }
+ }
+ Ext.DomHelper.applyStyles(el, o.style);
+
+ if ((cn = o.children || o.cn)) {
+ createDom(cn, el);
+ } else if (o.html) {
+ el.innerHTML = o.html;
+ }
+ }
+ if(parentNode){
+ parentNode.appendChild(el);
+ }
+ return el;
+ }
+
+ pub = {
+
+ createTemplate : function(o){
+ var html = Ext.DomHelper.createHtml(o);
+ return new Ext.Template(html);
+ },
+
+
+ useDom : false,
+
+
+ insertBefore : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, beforebegin);
+ },
+
+
+ insertAfter : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, afterend, 'nextSibling');
+ },
+
+
+ insertFirst : function(el, o, returnElement){
+ return doInsert(el, o, returnElement, afterbegin, 'firstChild');
+ },
+
+
+ append: function(el, o, returnElement){
+ return doInsert(el, o, returnElement, beforeend, '', true);
+ },
+
+
+ createDom: createDom
+ };
+ return pub;
+}());
+
+Ext.apply(Ext.Template.prototype, {
+
+ disableFormats : false,
+
+
+
+ re : /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
+ argsRe : /^\s*['"](.*)["']\s*$/,
+ compileARe : /\\/g,
+ compileBRe : /(\r\n|\n)/g,
+ compileCRe : /'/g,
+
+ /**
+ * Returns an HTML fragment of this template with the specified values applied.
+ * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @return {String} The HTML fragment
+ * @hide repeat doc
+ */
+ applyTemplate : function(values){
+ var me = this,
+ useF = me.disableFormats !== true,
+ fm = Ext.util.Format,
+ tpl = me;
+
+ if(me.compiled){
+ return me.compiled(values);
+ }
+ function fn(m, name, format, args){
+ if (format && useF) {
+ if (format.substr(0, 5) == "this.") {
+ return tpl.call(format.substr(5), values[name], values);
+ } else {
+ if (args) {
+ // quoted values are required for strings in compiled templates,
+ // but for non compiled we need to strip them
+ // quoted reversed for jsmin
+ var re = me.argsRe;
+ args = args.split(',');
+ for(var i = 0, len = args.length; i < len; i++){
+ args[i] = args[i].replace(re, "$1");
+ }
+ args = [values[name]].concat(args);
+ } else {
+ args = [values[name]];
+ }
+ return fm[format].apply(fm, args);
+ }
+ } else {
+ return values[name] !== undefined ? values[name] : "";
+ }
+ }
+ return me.html.replace(me.re, fn);
+ },
+
+ /**
+ * Compiles the template into an internal function, eliminating the RegEx overhead.
+ * @return {Ext.Template} this
+ * @hide repeat doc
+ */
+ compile : function(){
+ var me = this,
+ fm = Ext.util.Format,
+ useF = me.disableFormats !== true,
+ sep = Ext.isGecko ? "+" : ",",
+ body;
+
+ function fn(m, name, format, args){
+ if(format && useF){
+ args = args ? ',' + args : "";
+ if(format.substr(0, 5) != "this."){
+ format = "fm." + format + '(';
+ }else{
+ format = 'this.call("'+ format.substr(5) + '", ';
+ args = ", values";
+ }
+ }else{
+ args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
+ }
+ return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
+ }
+
+ // branched to use + in gecko and [].join() in others
+ if(Ext.isGecko){
+ body = "this.compiled = function(values){ return '" +
+ me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
+ "';};";
+ }else{
+ body = ["this.compiled = function(values){ return ['"];
+ body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
+ body.push("'].join('');};");
+ body = body.join('');
+ }
+ eval(body);
+ return me;
+ },
+
+ // private function used to call members
+ call : function(fnName, value, allValues){
+ return this[fnName](value, allValues);
+ }
+});
+Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
+/**
+ * @class Ext.util.Functions
+ * @singleton
+ */
+Ext.util.Functions = {
+ /**
+ * Creates an interceptor function. The passed function is called before the original one. If it returns false,
+ * the original one is not called. The resulting function returns the results of the original function.
+ * The passed function is called with the parameters of the original function. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+sayHi('Fred'); // alerts "Hi, Fred"
+
+// create a new function that validates input without
+// directly modifying the original function:
+var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
+ return name == 'Brian';
+});
+
+sayHiToFriend('Fred'); // no alert
+sayHiToFriend('Brian'); // alerts "Hi, Brian"
+ </code></pre>
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to call before the original
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
+ * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
+ * @return {Function} The new function
+ */
+ createInterceptor: function(origFn, newFn, scope) {
+ var method = origFn;
+ if (!Ext.isFunction(newFn)) {
+ return origFn;
+ }
+ else {
+ return function() {
+ var me = this,
+ args = arguments;
+ newFn.target = me;
+ newFn.method = origFn;
+ return (newFn.apply(scope || me || window, args) !== false) ?
+ origFn.apply(me || window, args) :
+ null;
+ };
+ }
+ },
+
+ /**
+ * Creates a delegate (callback) that sets the scope to obj.
+ * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
+ * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
+ * callback points to obj. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ // Note this use of "this.text" here. This function expects to
+ // execute within a scope that contains a text property. In this
+ // example, the "this" variable is pointing to the btn object that
+ // was passed in createDelegate below.
+ alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
+}
+
+var btn = new Ext.Button({
+ text: 'Say Hi',
+ renderTo: Ext.getBody()
+});
+
+// This callback will execute in the scope of the
+// button instance. Clicking the button alerts
+// "Hi, Fred. You clicked the "Say Hi" button."
+btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
+ </code></pre>
+ * @param {Function} fn The function to delegate.
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Function} The new function
+ */
+ createDelegate: function(fn, obj, args, appendArgs) {
+ if (!Ext.isFunction(fn)) {
+ return fn;
+ }
+ return function() {
+ var callArgs = args || arguments;
+ if (appendArgs === true) {
+ callArgs = Array.prototype.slice.call(arguments, 0);
+ callArgs = callArgs.concat(args);
+ }
+ else if (Ext.isNumber(appendArgs)) {
+ callArgs = Array.prototype.slice.call(arguments, 0);
+ // copy arguments first
+ var applyArgs = [appendArgs, 0].concat(args);
+ // create method call params
+ Array.prototype.splice.apply(callArgs, applyArgs);
+ // splice them in
+ }
+ return fn.apply(obj || window, callArgs);
+ };
+ },
+
+ /**
+ * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+// executes immediately:
+sayHi('Fred');
+
+// executes after 2 seconds:
+Ext.defer(sayHi, 2000, this, ['Fred']);
+
+// this syntax is sometimes useful for deferring
+// execution of an anonymous function:
+Ext.defer(function(){
+ alert('Anonymous');
+}, 100);
+ </code></pre>
+ * @param {Function} fn The function to defer.
+ * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Number} The timeout id that can be used with clearTimeout
+ */
+ defer: function(fn, millis, obj, args, appendArgs) {
+ fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
+ if (millis > 0) {
+ return setTimeout(fn, millis);
+ }
+ fn();
+ return 0;
+ },
+
+
+ /**
+ * Create a combined function call sequence of the original function + the passed function.
+ * The resulting function returns the results of the original function.
+ * The passed fcn is called with the parameters of the original function. Example usage:
+ *
+
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+sayHi('Fred'); // alerts "Hi, Fred"
+
+var sayGoodbye = Ext.createSequence(sayHi, function(name){
+ alert('Bye, ' + name);
+});
+
+sayGoodbye('Fred'); // both alerts show
+
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to sequence
+ * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
+ * If omitted, defaults to the scope in which the original function is called or the browser window.
+ * @return {Function} The new function
+ */
+ createSequence: function(origFn, newFn, scope) {
+ if (!Ext.isFunction(newFn)) {
+ return origFn;
+ }
+ else {
+ return function() {
+ var retval = origFn.apply(this || window, arguments);
+ newFn.apply(scope || this || window, arguments);
+ return retval;
+ };
+ }
+ }
+};
+
+/**
+ * Shorthand for {@link Ext.util.Functions#defer}
+ * @param {Function} fn The function to defer.
+ * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Number} The timeout id that can be used with clearTimeout
+ * @member Ext
+ * @method defer
+ */
+
+Ext.defer = Ext.util.Functions.defer;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createInterceptor}
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to call before the original
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
+ * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
+ * @return {Function} The new function
+ * @member Ext
+ * @method createInterceptor
+ */
+
+Ext.createInterceptor = Ext.util.Functions.createInterceptor;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createSequence}
+ * @param {Function} origFn The original function.
+ * @param {Function} newFn The function to sequence
+ * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
+ * If omitted, defaults to the scope in which the original function is called or the browser window.
+ * @return {Function} The new function
+ * @member Ext
+ * @method createSequence
+ */
+
+Ext.createSequence = Ext.util.Functions.createSequence;
+
+/**
+ * Shorthand for {@link Ext.util.Functions#createDelegate}
+ * @param {Function} fn The function to delegate.
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Function} The new function
+ * @member Ext
+ * @method createDelegate
+ */
+Ext.createDelegate = Ext.util.Functions.createDelegate;
+/**
+ * @class Ext.util.Observable
+ */
+Ext.apply(Ext.util.Observable.prototype, function(){
+ // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
+ // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
+ // private
+ function getMethodEvent(method){
+ var e = (this.methodEvents = this.methodEvents ||
+ {})[method], returnValue, v, cancel, obj = this;
+
+ if (!e) {
+ this.methodEvents[method] = e = {};
+ e.originalFn = this[method];
+ e.methodName = method;
+ e.before = [];
+ e.after = [];
+
+ var makeCall = function(fn, scope, args){
+ if((v = fn.apply(scope || obj, args)) !== undefined){
+ if (typeof v == 'object') {
+ if(v.returnValue !== undefined){
+ returnValue = v.returnValue;
+ }else{
+ returnValue = v;
+ }
+ cancel = !!v.cancel;
+ }
+ else
+ if (v === false) {
+ cancel = true;
+ }
+ else {
+ returnValue = v;
+ }
+ }
+ };
+
+ this[method] = function(){
+ var args = Array.prototype.slice.call(arguments, 0),
+ b;
+ returnValue = v = undefined;
+ cancel = false;
+
+ for(var i = 0, len = e.before.length; i < len; i++){
+ b = e.before[i];
+ makeCall(b.fn, b.scope, args);
+ if (cancel) {
+ return returnValue;
+ }
+ }
+
+ if((v = e.originalFn.apply(obj, args)) !== undefined){
+ returnValue = v;
+ }
+
+ for(var i = 0, len = e.after.length; i < len; i++){
+ b = e.after[i];
+ makeCall(b.fn, b.scope, args);
+ if (cancel) {
+ return returnValue;
+ }
+ }
+ return returnValue;
+ };
+ }
+ return e;
+ }
+
+ return {
+ // these are considered experimental
+ // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
+ // adds an 'interceptor' called before the original method
+ beforeMethod : function(method, fn, scope){
+ getMethodEvent.call(this, method).before.push({
+ fn: fn,
+ scope: scope
+ });
+ },
+
+ // adds a 'sequence' called after the original method
+ afterMethod : function(method, fn, scope){
+ getMethodEvent.call(this, method).after.push({
+ fn: fn,
+ scope: scope
+ });
+ },
+
+ removeMethodListener: function(method, fn, scope){
+ var e = this.getMethodEvent(method);
+ for(var i = 0, len = e.before.length; i < len; i++){
+ if(e.before[i].fn == fn && e.before[i].scope == scope){
+ e.before.splice(i, 1);
+ return;
+ }
+ }
+ for(var i = 0, len = e.after.length; i < len; i++){
+ if(e.after[i].fn == fn && e.after[i].scope == scope){
+ e.after.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ /**
+ * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
+ * @param {Object} o The Observable whose events this object is to relay.
+ * @param {Array} events Array of event names to relay.
+ */
+ relayEvents : function(o, events){
+ var me = this;
+ function createHandler(ename){
+ return function(){
+ return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
+ };
+ }
+ for(var i = 0, len = events.length; i < len; i++){
+ var ename = events[i];
+ me.events[ename] = me.events[ename] || true;
+ o.on(ename, createHandler(ename), me);
+ }
+ },
+
+ /**
+ * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
+ * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
+ * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
+ * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
+ * access the required target more quickly.</p>
+ * <p>Example:</p><pre><code>
+Ext.override(Ext.form.Field, {
+
+ initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
+ this.enableBubble('change');
+ }),
+
+
+ getBubbleTarget : function() {
+ if (!this.formPanel) {
+ this.formPanel = this.findParentByType('form');
+ }
+ return this.formPanel;
+ }
+});
+
+var myForm = new Ext.formPanel({
+ title: 'User Details',
+ items: [{
+ ...
+ }],
+ listeners: {
+ change: function() {
+
+ myForm.header.setStyle('color', 'red');
+ }
+ }
+});
+</code></pre>
+ * @param {String/Array} events The event name to bubble, or an Array of event names.
+ */
+ enableBubble : function(events){
+ var me = this;
+ if(!Ext.isEmpty(events)){
+ events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
+ for(var i = 0, len = events.length; i < len; i++){
+ var ename = events[i];
+ ename = ename.toLowerCase();
+ var ce = me.events[ename] || true;
+ if (typeof ce == 'boolean') {
+ ce = new Ext.util.Event(me, ename);
+ me.events[ename] = ce;
+ }
+ ce.bubble = true;
+ }
+ }
+ }
+ };
+}());
+
+
+
+Ext.util.Observable.capture = function(o, fn, scope){
+ o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
+};
+
+
+
+Ext.util.Observable.observeClass = function(c, listeners){
+ if(c){
+ if(!c.fireEvent){
+ Ext.apply(c, new Ext.util.Observable());
+ Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
+ }
+ if(typeof listeners == 'object'){
+ c.on(listeners);
+ }
+ return c;
+ }
+};
+
+Ext.apply(Ext.EventManager, function(){
+ var resizeEvent,
+ resizeTask,
+ textEvent,
+ textSize,
+ D = Ext.lib.Dom,
+ propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
+ unload = Ext.EventManager._unload,
+ curWidth = 0,
+ curHeight = 0,
+
+
+
+ useKeydown = Ext.isWebKit ?
+ Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
+ !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
+
+ return {
+ _unload: function(){
+ Ext.EventManager.un(window, "resize", this.fireWindowResize, this);
+ unload.call(Ext.EventManager);
+ },
+
+
+ doResizeEvent: function(){
+ var h = D.getViewHeight(),
+ w = D.getViewWidth();
+
+
+ if(curHeight != h || curWidth != w){
+ resizeEvent.fire(curWidth = w, curHeight = h);
+ }
+ },
+
+
+ onWindowResize : function(fn, scope, options){
+ if(!resizeEvent){
+ resizeEvent = new Ext.util.Event();
+ resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
+ Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
+ }
+ resizeEvent.addListener(fn, scope, options);
+ },
+
+
+ fireWindowResize : function(){
+ if(resizeEvent){
+ resizeTask.delay(100);
+ }
+ },
+
+
+ onTextResize : function(fn, scope, options){
+ if(!textEvent){
+ textEvent = new Ext.util.Event();
+ var textEl = new Ext.Element(document.createElement('div'));
+ textEl.dom.className = 'x-text-resize';
+ textEl.dom.innerHTML = 'X';
+ textEl.appendTo(document.body);
+ textSize = textEl.dom.offsetHeight;
+ setInterval(function(){
+ if(textEl.dom.offsetHeight != textSize){
+ textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
+ }
+ }, this.textResizeInterval);
+ }
+ textEvent.addListener(fn, scope, options);
+ },
+
+
+ removeResizeListener : function(fn, scope){
+ if(resizeEvent){
+ resizeEvent.removeListener(fn, scope);
+ }
+ },
+
+
+ fireResize : function(){
+ if(resizeEvent){
+ resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
+ }
+ },
+
+
+ textResizeInterval : 50,
+
+
+ ieDeferSrc : false,
+
+
+ getKeyEvent : function(){
+ return useKeydown ? 'keydown' : 'keypress';
+ },
+
+
+
+ useKeydown: useKeydown
+ };
+}());
+
+Ext.EventManager.on = Ext.EventManager.addListener;
+
+
+Ext.apply(Ext.EventObjectImpl.prototype, {
+
+ BACKSPACE: 8,
+
+ TAB: 9,
+
+ NUM_CENTER: 12,
+
+ ENTER: 13,
+
+ RETURN: 13,
+
+ SHIFT: 16,
+
+ CTRL: 17,
+ CONTROL : 17,
+
+ ALT: 18,
+
+ PAUSE: 19,
+
+ CAPS_LOCK: 20,
+
+ ESC: 27,
+
+ SPACE: 32,
+
+ PAGE_UP: 33,
+ PAGEUP : 33,
+
+ PAGE_DOWN: 34,
+ PAGEDOWN : 34,
+
+ END: 35,
+
+ HOME: 36,
+
+ LEFT: 37,
+
+ UP: 38,
+
+ RIGHT: 39,
+
+ DOWN: 40,
+
+ PRINT_SCREEN: 44,
+
+ INSERT: 45,
+
+ DELETE: 46,
+
+ ZERO: 48,
+
+ ONE: 49,
+
+ TWO: 50,
+
+ THREE: 51,
+
+ FOUR: 52,
+
+ FIVE: 53,
+
+ SIX: 54,
+
+ SEVEN: 55,
+
+ EIGHT: 56,
+
+ NINE: 57,
+
+ A: 65,
+
+ B: 66,
+
+ C: 67,
+
+ D: 68,
+
+ E: 69,
+
+ F: 70,
+
+ G: 71,
+
+ H: 72,
+
+ I: 73,
+
+ J: 74,
+
+ K: 75,
+
+ L: 76,
+
+ M: 77,
+
+ N: 78,
+
+ O: 79,
+
+ P: 80,
+
+ Q: 81,
+
+ R: 82,
+
+ S: 83,
+
+ T: 84,
+
+ U: 85,
+
+ V: 86,
+
+ W: 87,
+
+ X: 88,
+
+ Y: 89,
+
+ Z: 90,
+
+ CONTEXT_MENU: 93,
+
+ NUM_ZERO: 96,
+
+ NUM_ONE: 97,
+
+ NUM_TWO: 98,
+
+ NUM_THREE: 99,
+
+ NUM_FOUR: 100,
+
+ NUM_FIVE: 101,
+
+ NUM_SIX: 102,
+
+ NUM_SEVEN: 103,
+
+ NUM_EIGHT: 104,
+
+ NUM_NINE: 105,
+
+ NUM_MULTIPLY: 106,
+
+ NUM_PLUS: 107,
+
+ NUM_MINUS: 109,
+
+ NUM_PERIOD: 110,
+
+ NUM_DIVISION: 111,
+
+ F1: 112,
+
+ F2: 113,
+
+ F3: 114,
+
+ F4: 115,
+
+ F5: 116,
+
+ F6: 117,
+
+ F7: 118,
+
+ F8: 119,
+
+ F9: 120,
+
+ F10: 121,
+
+ F11: 122,
+
+ F12: 123,
+
+
+ isNavKeyPress : function(){
+ var me = this,
+ k = this.normalizeKey(me.keyCode);
+ return (k >= 33 && k <= 40) ||
+ k == me.RETURN ||
+ k == me.TAB ||
+ k == me.ESC;
+ },
+
+ isSpecialKey : function(){
+ var k = this.normalizeKey(this.keyCode);
+ return (this.type == 'keypress' && this.ctrlKey) ||
+ this.isNavKeyPress() ||
+ (k == this.BACKSPACE) ||
+ (k >= 16 && k <= 20) ||
+ (k >= 44 && k <= 46);
+ },
+
+ getPoint : function(){
+ return new Ext.lib.Point(this.xy[0], this.xy[1]);
+ },
+
+
+ hasModifier : function(){
+ return ((this.ctrlKey || this.altKey) || this.shiftKey);
+ }
+});
+Ext.Element.addMethods({
+
+ swallowEvent : function(eventName, preventDefault) {
+ var me = this;
+ function fn(e) {
+ e.stopPropagation();
+ if (preventDefault) {
+ e.preventDefault();
+ }
+ }
+
+ if (Ext.isArray(eventName)) {
+ Ext.each(eventName, function(e) {
+ me.on(e, fn);
+ });
+ return me;
+ }
+ me.on(eventName, fn);
+ return me;
+ },
+
+
+ relayEvent : function(eventName, observable) {
+ this.on(eventName, function(e) {
+ observable.fireEvent(eventName, e);
+ });
+ },
+
+
+ clean : function(forceReclean) {
+ var me = this,
+ dom = me.dom,
+ n = dom.firstChild,
+ ni = -1;
+
+ if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
+ return me;
+ }
+
+ while (n) {
+ var nx = n.nextSibling;
+ if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
+ dom.removeChild(n);
+ } else {
+ n.nodeIndex = ++ni;
+ }
+ n = nx;
+ }
+
+ Ext.Element.data(dom, 'isCleaned', true);
+ return me;
+ },
+
+
+ load : function() {
+ var updateManager = this.getUpdater();
+ updateManager.update.apply(updateManager, arguments);
+
+ return this;
+ },
+
+
+ getUpdater : function() {
+ return this.updateManager || (this.updateManager = new Ext.Updater(this));
+ },
+
+
+ update : function(html, loadScripts, callback) {
+ if (!this.dom) {
+ return this;
+ }
+ html = html || "";
+
+ if (loadScripts !== true) {
+ this.dom.innerHTML = html;
+ if (typeof callback == 'function') {
+ callback();
+ }
+ return this;
+ }
+
+ var id = Ext.id(),
+ dom = this.dom;
+
+ html += '<span id="' + id + '"></span>';
+
+ Ext.lib.Event.onAvailable(id, function() {
+ var DOC = document,
+ hd = DOC.getElementsByTagName("head")[0],
+ re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
+ srcRe = /\ssrc=([\'\"])(.*?)\1/i,
+ typeRe = /\stype=([\'\"])(.*?)\1/i,
+ match,
+ attrs,
+ srcMatch,
+ typeMatch,
+ el,
+ s;
+
+ while ((match = re.exec(html))) {
+ attrs = match[1];
+ srcMatch = attrs ? attrs.match(srcRe) : false;
+ if (srcMatch && srcMatch[2]) {
+ s = DOC.createElement("script");
+ s.src = srcMatch[2];
+ typeMatch = attrs.match(typeRe);
+ if (typeMatch && typeMatch[2]) {
+ s.type = typeMatch[2];
+ }
+ hd.appendChild(s);
+ } else if (match[2] && match[2].length > 0) {
+ if (window.execScript) {
+ window.execScript(match[2]);
+ } else {
+ window.eval(match[2]);
+ }
+ }
+ }
+
+ el = DOC.getElementById(id);
+ if (el) {
+ Ext.removeNode(el);
+ }
+
+ if (typeof callback == 'function') {
+ callback();
+ }
+ });
+ dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
+ return this;
+ },
+
+
+ removeAllListeners : function() {
+ this.removeAnchor();
+ Ext.EventManager.removeAll(this.dom);
+ return this;
+ },
+
+
+ createProxy : function(config, renderTo, matchBox) {
+ config = (typeof config == 'object') ? config : {tag : "div", cls: config};
+
+ var me = this,
+ proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
+ Ext.DomHelper.insertBefore(me.dom, config, true);
+
+ if (matchBox && me.setBox && me.getBox) {
+ proxy.setBox(me.getBox());
+ }
+ return proxy;
+ }
+});
+
+Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
+
+Ext.Element.addMethods({
+
+ getAnchorXY : function(anchor, local, s){
+
+
+ anchor = (anchor || "tl").toLowerCase();
+ s = s || {};
+
+ var me = this,
+ vp = me.dom == document.body || me.dom == document,
+ w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
+ h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
+ xy,
+ r = Math.round,
+ o = me.getXY(),
+ scroll = me.getScroll(),
+ extraX = vp ? scroll.left : !local ? o[0] : 0,
+ extraY = vp ? scroll.top : !local ? o[1] : 0,
+ hash = {
+ c : [r(w * 0.5), r(h * 0.5)],
+ t : [r(w * 0.5), 0],
+ l : [0, r(h * 0.5)],
+ r : [w, r(h * 0.5)],
+ b : [r(w * 0.5), h],
+ tl : [0, 0],
+ bl : [0, h],
+ br : [w, h],
+ tr : [w, 0]
+ };
+
+ xy = hash[anchor];
+ return [xy[0] + extraX, xy[1] + extraY];
+ },
+
+
+ anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
+ var me = this,
+ dom = me.dom,
+ scroll = !Ext.isEmpty(monitorScroll),
+ action = function(){
+ Ext.fly(dom).alignTo(el, alignment, offsets, animate);
+ Ext.callback(callback, Ext.fly(dom));
+ },
+ anchor = this.getAnchor();
+
+
+ this.removeAnchor();
+ Ext.apply(anchor, {
+ fn: action,
+ scroll: scroll
+ });
+
+ Ext.EventManager.onWindowResize(action, null);
+
+ if(scroll){
+ Ext.EventManager.on(window, 'scroll', action, null,
+ {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
+ }
+ action.call(me);
+ return me;
+ },
+
+
+ removeAnchor : function(){
+ var me = this,
+ anchor = this.getAnchor();
+
+ if(anchor && anchor.fn){
+ Ext.EventManager.removeResizeListener(anchor.fn);
+ if(anchor.scroll){
+ Ext.EventManager.un(window, 'scroll', anchor.fn);
+ }
+ delete anchor.fn;
+ }
+ return me;
+ },
+
+
+ getAnchor : function(){
+ var data = Ext.Element.data,
+ dom = this.dom;
+ if (!dom) {
+ return;
+ }
+ var anchor = data(dom, '_anchor');
+
+ if(!anchor){
+ anchor = data(dom, '_anchor', {});
+ }
+ return anchor;
+ },
+
+
+ getAlignToXY : function(el, p, o){
+ el = Ext.get(el);
+
+ if(!el || !el.dom){
+ throw "Element.alignToXY with an element that doesn't exist";
+ }
+
+ o = o || [0,0];
+ p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
+
+ var me = this,
+ d = me.dom,
+ a1,
+ a2,
+ x,
+ y,
+
+ w,
+ h,
+ r,
+ dw = Ext.lib.Dom.getViewWidth() -10,
+ dh = Ext.lib.Dom.getViewHeight()-10,
+ p1y,
+ p1x,
+ p2y,
+ p2x,
+ swapY,
+ swapX,
+ doc = document,
+ docElement = doc.documentElement,
+ docBody = doc.body,
+ scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
+ scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
+ c = false,
+ p1 = "",
+ p2 = "",
+ 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];
+
+
+
+ a1 = me.getAnchorXY(p1, true);
+ a2 = el.getAnchorXY(p2, false);
+
+ x = a2[0] - a1[0] + o[0];
+ y = a2[1] - a1[1] + o[1];
+
+ if(c){
+ w = me.getWidth();
+ h = me.getHeight();
+ r = el.getRegion();
+
+
+
+ p1y = p1.charAt(0);
+ p1x = p1.charAt(p1.length-1);
+ p2y = p2.charAt(0);
+ p2x = p2.charAt(p2.length-1);
+ swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
+ swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
+
+
+ if (x + w > dw + scrollX) {
+ x = swapX ? r.left-w : dw+scrollX-w;
+ }
+ if (x < scrollX) {
+ x = swapX ? r.right : scrollX;
+ }
+ if (y + h > dh + scrollY) {
+ y = swapY ? r.top-h : dh+scrollY-h;
+ }
+ if (y < scrollY){
+ y = swapY ? r.bottom : scrollY;
+ }
+ }
+ return [x,y];
+ },
+
+
+ alignTo : function(element, position, offsets, animate){
+ var me = this;
+ return me.setXY(me.getAlignToXY(element, position, offsets),
+ me.preanim && !!animate ? me.preanim(arguments, 3) : false);
+ },
+
+
+ adjustForConstraints : function(xy, parent, offsets){
+ return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
+ },
+
+
+ getConstrainToXY : function(el, local, offsets, proposedXY){
+ var os = {top:0, left:0, bottom:0, right: 0};
+
+ return function(el, local, offsets, proposedXY){
+ el = Ext.get(el);
+ offsets = offsets ? Ext.applyIf(offsets, os) : os;
+
+ var vw, vh, vx = 0, vy = 0;
+ if(el.dom == document.body || el.dom == document){
+ vw =Ext.lib.Dom.getViewWidth();
+ vh = Ext.lib.Dom.getViewHeight();
+ }else{
+ vw = el.dom.clientWidth;
+ vh = el.dom.clientHeight;
+ if(!local){
+ var vxy = el.getXY();
+ vx = vxy[0];
+ vy = vxy[1];
+ }
+ }
+
+ var s = el.getScroll();
+
+ vx += offsets.left + s.left;
+ vy += offsets.top + s.top;
+
+ vw -= offsets.right;
+ vh -= offsets.bottom;
+
+ var vr = vx + vw,
+ vb = vy + vh,
+ xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
+ x = xy[0], y = xy[1],
+ offset = this.getConstrainOffset(),
+ w = this.dom.offsetWidth + offset,
+ h = this.dom.offsetHeight + offset;
+
+
+ var moved = false;
+
+
+ if((x + w) > vr){
+ x = vr - w;
+ moved = true;
+ }
+ if((y + h) > vb){
+ y = vb - h;
+ moved = true;
+ }
+
+ if(x < vx){
+ x = vx;
+ moved = true;
+ }
+ if(y < vy){
+ y = vy;
+ moved = true;
+ }
+ return moved ? [x, y] : false;
+ };
+ }(),
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getConstrainOffset : function(){
+ return 0;
+ },
+
+
+ getCenterXY : function(){
+ return this.getAlignToXY(document, 'c-c');
+ },
+
+
+ center : function(centerIn){
+ return this.alignTo(centerIn || document, 'c-c');
+ }
+});
+
+Ext.Element.addMethods({
+
+ select : function(selector, unique){
+ return Ext.Element.select(selector, unique, this.dom);
+ }
+});
+Ext.apply(Ext.Element.prototype, function() {
+ var GETDOM = Ext.getDom,
+ GET = Ext.get,
+ DH = Ext.DomHelper;
+
+ return {
+
+ insertSibling: function(el, where, returnDom){
+ var me = this,
+ rt,
+ isAfter = (where || 'before').toLowerCase() == 'after',
+ insertEl;
+
+ if(Ext.isArray(el)){
+ insertEl = me;
+ Ext.each(el, function(e) {
+ rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
+ if(isAfter){
+ insertEl = rt;
+ }
+ });
+ return rt;
+ }
+
+ el = el || {};
+
+ if(el.nodeType || el.dom){
+ rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
+ if (!returnDom) {
+ rt = GET(rt);
+ }
+ }else{
+ if (isAfter && !me.dom.nextSibling) {
+ rt = DH.append(me.dom.parentNode, el, !returnDom);
+ } else {
+ rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
+ }
+ }
+ return rt;
+ }
+ };
+}());
+
+
+Ext.Element.boxMarkup = '<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>';
+
+Ext.Element.addMethods(function(){
+ var INTERNAL = "_internal",
+ pxMatch = /(\d+\.?\d+)px/;
+ return {
+
+ applyStyles : function(style){
+ Ext.DomHelper.applyStyles(this.dom, style);
+ return this;
+ },
+
+
+ getStyles : function(){
+ var ret = {};
+ Ext.each(arguments, function(v) {
+ ret[v] = this.getStyle(v);
+ },
+ this);
+ return ret;
+ },
+
+
+ setOverflow : function(v){
+ var dom = this.dom;
+ if(v=='auto' && Ext.isMac && Ext.isGecko2){
+ dom.style.overflow = 'hidden';
+ (function(){dom.style.overflow = 'auto';}).defer(1);
+ }else{
+ dom.style.overflow = v;
+ }
+ },
+
+
+ boxWrap : function(cls){
+ cls = cls || 'x-box';
+ var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
+ Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
+ return el;
+ },
+
+
+ setSize : function(width, height, animate){
+ var me = this;
+ if(typeof width == 'object'){
+ height = width.height;
+ width = width.width;
+ }
+ width = me.adjustWidth(width);
+ height = me.adjustHeight(height);
+ if(!animate || !me.anim){
+ me.dom.style.width = me.addUnits(width);
+ me.dom.style.height = me.addUnits(height);
+ }else{
+ me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
+ }
+ return me;
+ },
+
+
+ getComputedHeight : function(){
+ var me = this,
+ h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
+ if(!h){
+ h = parseFloat(me.getStyle('height')) || 0;
+ if(!me.isBorderBox()){
+ h += me.getFrameWidth('tb');
+ }
+ }
+ return h;
+ },
+
+
+ getComputedWidth : function(){
+ var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
+ if(!w){
+ w = parseFloat(this.getStyle('width')) || 0;
+ if(!this.isBorderBox()){
+ w += this.getFrameWidth('lr');
+ }
+ }
+ return w;
+ },
+
+
+ getFrameWidth : function(sides, onlyContentBox){
+ return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
+ },
+
+
+ addClassOnOver : function(className){
+ this.hover(
+ function(){
+ Ext.fly(this, INTERNAL).addClass(className);
+ },
+ function(){
+ Ext.fly(this, INTERNAL).removeClass(className);
+ }
+ );
+ return this;
+ },
+
+
+ addClassOnFocus : function(className){
+ this.on("focus", function(){
+ Ext.fly(this, INTERNAL).addClass(className);
+ }, this.dom);
+ this.on("blur", function(){
+ Ext.fly(this, INTERNAL).removeClass(className);
+ }, this.dom);
+ return this;
+ },
+
+
+ addClassOnClick : function(className){
+ var dom = this.dom;
+ this.on("mousedown", function(){
+ Ext.fly(dom, INTERNAL).addClass(className);
+ var d = Ext.getDoc(),
+ fn = function(){
+ Ext.fly(dom, INTERNAL).removeClass(className);
+ d.removeListener("mouseup", fn);
+ };
+ d.on("mouseup", fn);
+ });
+ return this;
+ },
+
+
+
+ getViewSize : function(){
+ var doc = document,
+ d = this.dom,
+ isDoc = (d == doc || d == doc.body);
+
+
+ if (isDoc) {
+ var extdom = Ext.lib.Dom;
+ return {
+ width : extdom.getViewWidth(),
+ height : extdom.getViewHeight()
+ };
+
+
+ } else {
+ return {
+ width : d.clientWidth,
+ height : d.clientHeight
+ };
+ }
+ },
+
+
+
+ getStyleSize : function(){
+ var me = this,
+ w, h,
+ doc = document,
+ d = this.dom,
+ isDoc = (d == doc || d == doc.body),
+ s = d.style;
+
+
+ if (isDoc) {
+ var extdom = Ext.lib.Dom;
+ return {
+ width : extdom.getViewWidth(),
+ height : extdom.getViewHeight()
+ };
+ }
+
+ if(s.width && s.width != 'auto'){
+ w = parseFloat(s.width);
+ if(me.isBorderBox()){
+ w -= me.getFrameWidth('lr');
+ }
+ }
+
+ if(s.height && s.height != 'auto'){
+ h = parseFloat(s.height);
+ if(me.isBorderBox()){
+ h -= me.getFrameWidth('tb');
+ }
+ }
+
+ return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
+ },
+
+
+ getSize : function(contentSize){
+ return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
+ },
+
+
+ repaint : function(){
+ var dom = this.dom;
+ this.addClass("x-repaint");
+ setTimeout(function(){
+ Ext.fly(dom).removeClass("x-repaint");
+ }, 1);
+ return this;
+ },
+
+
+ unselectable : function(){
+ this.dom.unselectable = "on";
+ return this.swallowEvent("selectstart", true).
+ addClass("x-unselectable");
+ },
+
+
+ getMargins : function(side){
+ var me = this,
+ key,
+ hash = {t:"top", l:"left", r:"right", b: "bottom"},
+ o = {};
+
+ if (!side) {
+ for (key in me.margins){
+ o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
+ }
+ return o;
+ } else {
+ return me.addStyles.call(me, side, me.margins);
+ }
+ }
+ };
+}());
+
+Ext.Element.addMethods({
+
+ setBox : function(box, adjust, animate){
+ var me = this,
+ w = box.width,
+ h = box.height;
+ if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
+ w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
+ h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
+ }
+ me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
+ return me;
+ },
+
+
+ getBox : function(contentBox, local) {
+ var me = this,
+ xy,
+ left,
+ top,
+ getBorderWidth = me.getBorderWidth,
+ getPadding = me.getPadding,
+ l,
+ r,
+ t,
+ b;
+ if(!local){
+ xy = me.getXY();
+ }else{
+ left = parseInt(me.getStyle("left"), 10) || 0;
+ top = parseInt(me.getStyle("top"), 10) || 0;
+ xy = [left, top];
+ }
+ var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
+ if(!contentBox){
+ bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
+ }else{
+ l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
+ r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
+ t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
+ b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
+ bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: 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;
+ },
+
+
+ move : function(direction, distance, animate){
+ var me = this,
+ xy = me.getXY(),
+ x = xy[0],
+ y = xy[1],
+ left = [x - distance, y],
+ right = [x + distance, y],
+ top = [x, y - distance],
+ bottom = [x, y + distance],
+ hash = {
+ l : left,
+ left : left,
+ r : right,
+ right : right,
+ t : top,
+ top : top,
+ up : top,
+ b : bottom,
+ bottom : bottom,
+ down : bottom
+ };
+
+ direction = direction.toLowerCase();
+ me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
+ },
+
+
+ setLeftTop : function(left, top){
+ var me = this,
+ style = me.dom.style;
+ style.left = me.addUnits(left);
+ style.top = me.addUnits(top);
+ return me;
+ },
+
+
+ getRegion : function(){
+ return Ext.lib.Dom.getRegion(this.dom);
+ },
+
+
+ setBounds : function(x, y, width, height, animate){
+ var me = this;
+ if (!animate || !me.anim) {
+ me.setSize(width, height);
+ me.setLocation(x, y);
+ } else {
+ me.anim({points: {to: [x, y]},
+ width: {to: me.adjustWidth(width)},
+ height: {to: me.adjustHeight(height)}},
+ me.preanim(arguments, 4),
+ 'motion');
+ }
+ return me;
+ },
+
+
+ setRegion : function(region, animate) {
+ return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
+ }
+});
+Ext.Element.addMethods({
+
+ scrollTo : function(side, value, animate) {
+
+ var top = /top/i.test(side),
+ me = this,
+ dom = me.dom,
+ prop;
+ if (!animate || !me.anim) {
+
+ prop = 'scroll' + (top ? 'Top' : 'Left');
+ dom[prop] = value;
+ }
+ else {
+
+ prop = 'scroll' + (top ? 'Left' : 'Top');
+ me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
+ }
+ return me;
+ },
+
+
+ scrollIntoView : function(container, hscroll) {
+ var c = Ext.getDom(container) || Ext.getBody().dom,
+ el = this.dom,
+ o = this.getOffsetsTo(c),
+ l = o[0] + c.scrollLeft,
+ t = o[1] + c.scrollTop,
+ b = t + el.offsetHeight,
+ r = l + el.offsetWidth,
+ ch = c.clientHeight,
+ ct = parseInt(c.scrollTop, 10),
+ cl = parseInt(c.scrollLeft, 10),
+ cb = ct + ch,
+ cr = cl + c.clientWidth;
+
+ if (el.offsetHeight > ch || t < ct) {
+ c.scrollTop = t;
+ }
+ else if (b > cb) {
+ c.scrollTop = b-ch;
+ }
+
+ c.scrollTop = c.scrollTop;
+
+ if (hscroll !== false) {
+ if (el.offsetWidth > c.clientWidth || l < cl) {
+ c.scrollLeft = l;
+ }
+ else if (r > cr) {
+ c.scrollLeft = r - c.clientWidth;
+ }
+ c.scrollLeft = c.scrollLeft;
+ }
+ return this;
+ },
+
+
+ scrollChildIntoView : function(child, hscroll) {
+ Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
+ },
+
+
+ scroll : function(direction, distance, animate) {
+ if (!this.isScrollable()) {
+ return false;
+ }
+ var el = this.dom,
+ l = el.scrollLeft, t = el.scrollTop,
+ w = el.scrollWidth, h = el.scrollHeight,
+ cw = el.clientWidth, ch = el.clientHeight,
+ scrolled = false, v,
+ hash = {
+ l: Math.min(l + distance, w-cw),
+ r: v = Math.max(l - distance, 0),
+ t: Math.max(t - distance, 0),
+ b: Math.min(t + distance, h-ch)
+ };
+ hash.d = hash.b;
+ hash.u = hash.t;
+
+ direction = direction.substr(0, 1);
+ if ((v = hash[direction]) > -1) {
+ scrolled = true;
+ this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
+ }
+ return scrolled;
+ }
+});
+Ext.Element.addMethods(
+ function() {
+ var VISIBILITY = "visibility",
+ DISPLAY = "display",
+ HIDDEN = "hidden",
+ NONE = "none",
+ XMASKED = "x-masked",
+ XMASKEDRELATIVE = "x-masked-relative",
+ data = Ext.Element.data;
+
+ return {
+
+ isVisible : function(deep) {
+ var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
+ p = this.dom.parentNode;
+
+ if (deep !== true || !vis) {
+ return vis;
+ }
+
+ while (p && !(/^body/i.test(p.tagName))) {
+ if (!Ext.fly(p, '_isVisible').isVisible()) {
+ return false;
+ }
+ p = p.parentNode;
+ }
+ return true;
+ },
+
+
+ isDisplayed : function() {
+ return !this.isStyle(DISPLAY, NONE);
+ },
+
+
+ enableDisplayMode : function(display) {
+ this.setVisibilityMode(Ext.Element.DISPLAY);
+
+ if (!Ext.isEmpty(display)) {
+ data(this.dom, 'originalDisplay', display);
+ }
+
+ return this;
+ },
+
+
+ mask : function(msg, msgCls) {
+ var me = this,
+ dom = me.dom,
+ dh = Ext.DomHelper,
+ EXTELMASKMSG = "ext-el-mask-msg",
+ el,
+ mask;
+
+ if (!/^body/i.test(dom.tagName) && me.getStyle('position') == 'static') {
+ me.addClass(XMASKEDRELATIVE);
+ }
+ if (el = data(dom, 'maskMsg')) {
+ el.remove();
+ }
+ if (el = data(dom, 'mask')) {
+ el.remove();
+ }
+
+ mask = dh.append(dom, {cls : "ext-el-mask"}, true);
+ data(dom, 'mask', mask);
+
+ me.addClass(XMASKED);
+ mask.setDisplayed(true);
+
+ if (typeof msg == 'string') {
+ var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
+ data(dom, 'maskMsg', mm);
+ mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
+ mm.dom.firstChild.innerHTML = msg;
+ mm.setDisplayed(true);
+ mm.center(me);
+ }
+
+
+ if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
+ mask.setSize(undefined, me.getHeight());
+ }
+
+ return mask;
+ },
+
+
+ unmask : function() {
+ var me = this,
+ dom = me.dom,
+ mask = data(dom, 'mask'),
+ maskMsg = data(dom, 'maskMsg');
+
+ if (mask) {
+ if (maskMsg) {
+ maskMsg.remove();
+ data(dom, 'maskMsg', undefined);
+ }
+
+ mask.remove();
+ data(dom, 'mask', undefined);
+ me.removeClass([XMASKED, XMASKEDRELATIVE]);
+ }
+ },
+
+
+ isMasked : function() {
+ var m = data(this.dom, 'mask');
+ return m && m.isVisible();
+ },
+
+
+ createShim : function() {
+ var el = document.createElement('iframe'),
+ shim;
+
+ el.frameBorder = '0';
+ el.className = 'ext-shim';
+ el.src = Ext.SSL_SECURE_URL;
+ shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
+ shim.autoBoxAdjust = false;
+ return shim;
+ }
+ };
+ }()
+);
+Ext.Element.addMethods({
+
+ addKeyListener : function(key, fn, scope){
+ var config;
+ if(typeof key != 'object' || Ext.isArray(key)){
+ config = {
+ key: key,
+ fn: fn,
+ scope: scope
+ };
+ }else{
+ config = {
+ key : key.key,
+ shift : key.shift,
+ ctrl : key.ctrl,
+ alt : key.alt,
+ fn: fn,
+ scope: scope
+ };
+ }
+ return new Ext.KeyMap(this, config);
+ },
+
+
+ addKeyMap : function(config){
+ return new Ext.KeyMap(this, config);
+ }
+});
+
+
+
+Ext.CompositeElementLite.importElementMethods();
+Ext.apply(Ext.CompositeElementLite.prototype, {
+ addElements : function(els, root){
+ if(!els){
+ return this;
+ }
+ if(typeof els == "string"){
+ els = Ext.Element.selectorFunction(els, root);
+ }
+ var yels = this.elements;
+ Ext.each(els, function(e) {
+ yels.push(Ext.get(e));
+ });
+ return this;
+ },
+
+
+ first : function(){
+ return this.item(0);
+ },
+
+
+ last : function(){
+ return this.item(this.getCount()-1);
+ },
+
+
+ contains : function(el){
+ return this.indexOf(el) != -1;
+ },
+
+
+ removeElement : function(keys, removeDom){
+ var me = this,
+ els = this.elements,
+ el;
+ Ext.each(keys, function(val){
+ if ((el = (els[val] || els[val = me.indexOf(val)]))) {
+ if(removeDom){
+ if(el.dom){
+ el.remove();
+ }else{
+ Ext.removeNode(el);
+ }
+ }
+ els.splice(val, 1);
+ }
+ });
+ return this;
+ }
+});
+
+Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
+
+ constructor : function(els, root){
+ this.elements = [];
+ this.add(els, root);
+ },
+
+
+ getElement : function(el){
+
+ return el;
+ },
+
+
+ transformElement : function(el){
+ return Ext.get(el);
+ }
+
+
+
+
+
+
+});
+
+
+Ext.Element.select = function(selector, unique, root){
+ var els;
+ if(typeof selector == "string"){
+ els = Ext.Element.selectorFunction(selector, root);
+ }else if(selector.length !== undefined){
+ els = selector;
+ }else{
+ throw "Invalid selector";
+ }
+
+ return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
+};
+
+
+Ext.select = Ext.Element.select;
+Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
+function() {
+ var BEFOREUPDATE = "beforeupdate",
+ UPDATE = "update",
+ FAILURE = "failure";
+
+
+ function processSuccess(response){
+ var me = this;
+ me.transaction = null;
+ if (response.argument.form && response.argument.reset) {
+ try {
+ response.argument.form.reset();
+ } catch(e){}
+ }
+ if (me.loadScripts) {
+ me.renderer.render(me.el, response, me,
+ updateComplete.createDelegate(me, [response]));
+ } else {
+ me.renderer.render(me.el, response, me);
+ updateComplete.call(me, response);
+ }
+ }
+
+
+ function updateComplete(response, type, success){
+ this.fireEvent(type || UPDATE, this.el, response);
+ if(Ext.isFunction(response.argument.callback)){
+ response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
+ }
+ }
+
+
+ function processFailure(response){
+ updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
+ }
+
+ return {
+ constructor: function(el, forceNew){
+ var me = this;
+ el = Ext.get(el);
+ if(!forceNew && el.updateManager){
+ return el.updateManager;
+ }
+
+ me.el = el;
+
+ me.defaultUrl = null;
+
+ me.addEvents(
+
+ BEFOREUPDATE,
+
+ UPDATE,
+
+ FAILURE
+ );
+
+ Ext.apply(me, Ext.Updater.defaults);
+
+
+
+
+
+
+
+
+ me.transaction = null;
+
+ me.refreshDelegate = me.refresh.createDelegate(me);
+
+ me.updateDelegate = me.update.createDelegate(me);
+
+ me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
+
+
+ me.renderer = me.renderer || me.getDefaultRenderer();
+
+ Ext.Updater.superclass.constructor.call(me);
+ },
+
+
+ setRenderer : function(renderer){
+ this.renderer = renderer;
+ },
+
+
+ getRenderer : function(){
+ return this.renderer;
+ },
+
+
+ getDefaultRenderer: function() {
+ return new Ext.Updater.BasicRenderer();
+ },
+
+
+ setDefaultUrl : function(defaultUrl){
+ this.defaultUrl = defaultUrl;
+ },
+
+
+ getEl : function(){
+ return this.el;
+ },
+
+
+ update : function(url, params, callback, discardUrl){
+ var me = this,
+ cfg,
+ callerScope;
+
+ if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
+ if(Ext.isObject(url)){
+ cfg = url;
+ url = cfg.url;
+ params = params || cfg.params;
+ callback = callback || cfg.callback;
+ discardUrl = discardUrl || cfg.discardUrl;
+ callerScope = cfg.scope;
+ if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
+ if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
+ if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
+ if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
+ }
+ me.showLoading();
+
+ if(!discardUrl){
+ me.defaultUrl = url;
+ }
+ if(Ext.isFunction(url)){
+ url = url.call(me);
+ }
+
+ var o = Ext.apply({}, {
+ url : url,
+ params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
+ success: processSuccess,
+ failure: processFailure,
+ scope: me,
+ callback: undefined,
+ timeout: (me.timeout*1000),
+ disableCaching: me.disableCaching,
+ argument: {
+ "options": cfg,
+ "url": url,
+ "form": null,
+ "callback": callback,
+ "scope": callerScope || window,
+ "params": params
+ }
+ }, cfg);
+
+ me.transaction = Ext.Ajax.request(o);
+ }
+ },
+
+
+ formUpdate : function(form, url, reset, callback){
+ var me = this;
+ if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
+ if(Ext.isFunction(url)){
+ url = url.call(me);
+ }
+ form = Ext.getDom(form);
+ me.transaction = Ext.Ajax.request({
+ form: form,
+ url:url,
+ success: processSuccess,
+ failure: processFailure,
+ scope: me,
+ timeout: (me.timeout*1000),
+ argument: {
+ "url": url,
+ "form": form,
+ "callback": callback,
+ "reset": reset
+ }
+ });
+ me.showLoading.defer(1, me);
+ }
+ },
+
+
+ startAutoRefresh : function(interval, url, params, callback, refreshNow){
+ var me = this;
+ if(refreshNow){
+ me.update(url || me.defaultUrl, params, callback, true);
+ }
+ if(me.autoRefreshProcId){
+ clearInterval(me.autoRefreshProcId);
+ }
+ me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
+ },
+
+
+ stopAutoRefresh : function(){
+ if(this.autoRefreshProcId){
+ clearInterval(this.autoRefreshProcId);
+ delete this.autoRefreshProcId;
+ }
+ },
+
+
+ isAutoRefreshing : function(){
+ return !!this.autoRefreshProcId;
+ },
+
+
+ showLoading : function(){
+ if(this.showLoadIndicator){
+ this.el.dom.innerHTML = this.indicatorText;
+ }
+ },
+
+
+ abort : function(){
+ if(this.transaction){
+ Ext.Ajax.abort(this.transaction);
+ }
+ },
+
+
+ isUpdating : function(){
+ return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
+ },
+
+
+ refresh : function(callback){
+ if(this.defaultUrl){
+ this.update(this.defaultUrl, null, callback, true);
+ }
+ }
+ };
+}());
+
+
+Ext.Updater.defaults = {
+
+ timeout : 30,
+
+ disableCaching : false,
+
+ showLoadIndicator : true,
+
+ indicatorText : '<div class="loading-indicator">Loading...</div>',
+
+ loadScripts : false,
+
+ sslBlankUrl : Ext.SSL_SECURE_URL
+};
+
+
+
+Ext.Updater.updateElement = function(el, url, params, options){
+ var um = Ext.get(el).getUpdater();
+ Ext.apply(um, options);
+ um.update(url, params, options ? options.callback : null);
+};
+
+
+Ext.Updater.BasicRenderer = function(){};
+
+Ext.Updater.BasicRenderer.prototype = {
+
+ render : function(el, response, updateManager, callback){
+ el.update(response.responseText, updateManager.loadScripts, callback);
+ }
+};
+
+
+
+(function() {
+
+
+Date.useStrict = false;
+
+
+
+
+
+function xf(format) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return format.replace(/\{(\d+)\}/g, function(m, i) {
+ return args[i];
+ });
+}
+
+
+
+Date.formatCodeToRegex = function(character, currentGroup) {
+
+ var p = Date.parseCodes[character];
+
+ if (p) {
+ p = typeof p == 'function'? p() : p;
+ Date.parseCodes[character] = p;
+ }
+
+ return p ? Ext.applyIf({
+ c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
+ }, p) : {
+ g:0,
+ c:null,
+ s:Ext.escapeRe(character)
+ };
+};
+
+
+var $f = Date.formatCodeToRegex;
+
+Ext.apply(Date, {
+
+ parseFunctions: {
+ "M$": function(input, strict) {
+
+
+ var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
+ var r = (input || '').match(re);
+ return r? new Date(((r[1] || '') + r[2]) * 1) : null;
+ }
+ },
+ parseRegexes: [],
+
+
+ formatFunctions: {
+ "M$": function() {
+
+ return '\\/Date(' + this.getTime() + ')\\/';
+ }
+ },
+
+ y2kYear : 50,
+
+
+ MILLI : "ms",
+
+
+ SECOND : "s",
+
+
+ MINUTE : "mi",
+
+
+ HOUR : "h",
+
+
+ DAY : "d",
+
+
+ MONTH : "mo",
+
+
+ YEAR : "y",
+
+
+ defaults: {},
+
+
+ dayNames : [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+
+
+ monthNames : [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+
+
+ 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
+ },
+
+
+ getShortMonthName : function(month) {
+ return Date.monthNames[month].substring(0, 3);
+ },
+
+
+ getShortDayName : function(day) {
+ return Date.dayNames[day].substring(0, 3);
+ },
+
+
+ getMonthNumber : function(name) {
+
+ return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
+ },
+
+
+ formatContainsHourInfo : (function(){
+ var stripEscapeRe = /(\\.)/g,
+ hourInfoRe = /([gGhHisucUOPZ]|M\$)/;
+ return function(format){
+ return hourInfoRe.test(format.replace(stripEscapeRe, ''));
+ };
+ })(),
+
+
+ formatCodes : {
+ d: "String.leftPad(this.getDate(), 2, '0')",
+ D: "Date.getShortDayName(this.getDay())",
+ j: "this.getDate()",
+ l: "Date.dayNames[this.getDay()]",
+ N: "(this.getDay() ? this.getDay() : 7)",
+ S: "this.getSuffix()",
+ w: "this.getDay()",
+ z: "this.getDayOfYear()",
+ W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
+ F: "Date.monthNames[this.getMonth()]",
+ m: "String.leftPad(this.getMonth() + 1, 2, '0')",
+ M: "Date.getShortMonthName(this.getMonth())",
+ n: "(this.getMonth() + 1)",
+ t: "this.getDaysInMonth()",
+ L: "(this.isLeapYear() ? 1 : 0)",
+ o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
+ Y: "String.leftPad(this.getFullYear(), 4, '0')",
+ y: "('' + this.getFullYear()).substring(2, 4)",
+ a: "(this.getHours() < 12 ? 'am' : 'pm')",
+ A: "(this.getHours() < 12 ? 'AM' : 'PM')",
+ g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
+ G: "this.getHours()",
+ h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
+ H: "String.leftPad(this.getHours(), 2, '0')",
+ i: "String.leftPad(this.getMinutes(), 2, '0')",
+ s: "String.leftPad(this.getSeconds(), 2, '0')",
+ u: "String.leftPad(this.getMilliseconds(), 3, '0')",
+ O: "this.getGMTOffset()",
+ P: "this.getGMTOffset(true)",
+ T: "this.getTimezone()",
+ Z: "(this.getTimezoneOffset() * -60)",
+
+ c: function() {
+ for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
+ var e = c.charAt(i);
+ code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
+ }
+ return code.join(" + ");
+ },
+
+
+ U: "Math.round(this.getTime() / 1000)"
+ },
+
+
+ isValid : function(y, m, d, h, i, s, ms) {
+
+ h = h || 0;
+ i = i || 0;
+ s = s || 0;
+ ms = ms || 0;
+
+
+ var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);
+
+ return y == dt.getFullYear() &&
+ m == dt.getMonth() + 1 &&
+ d == dt.getDate() &&
+ h == dt.getHours() &&
+ i == dt.getMinutes() &&
+ s == dt.getSeconds() &&
+ ms == dt.getMilliseconds();
+ },
+
+
+ parseDate : function(input, format, strict) {
+ var p = Date.parseFunctions;
+ if (p[format] == null) {
+ Date.createParser(format);
+ }
+ return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
+ },
+
+
+ getFormatCode : function(character) {
+ var f = Date.formatCodes[character];
+
+ if (f) {
+ f = typeof f == 'function'? f() : f;
+ Date.formatCodes[character] = f;
+ }
+
+
+ return f || ("'" + String.escape(character) + "'");
+ },
+
+
+ createFormat : function(format) {
+ var code = [],
+ special = false,
+ ch = '';
+
+ for (var i = 0; i < format.length; ++i) {
+ ch = format.charAt(i);
+ if (!special && ch == "\\") {
+ special = true;
+ } else if (special) {
+ special = false;
+ code.push("'" + String.escape(ch) + "'");
+ } else {
+ code.push(Date.getFormatCode(ch));
+ }
+ }
+ Date.formatFunctions[format] = new Function("return " + code.join('+'));
+ },
+
+
+ createParser : function() {
+ var code = [
+ "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
+ "def = Date.defaults,",
+ "results = String(input).match(Date.parseRegexes[{0}]);",
+
+ "if(results){",
+ "{1}",
+
+ "if(u != null){",
+ "v = new Date(u * 1000);",
+ "}else{",
+
+
+
+ "dt = (new Date()).clearTime();",
+
+
+ "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
+ "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
+ "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
+
+
+ "h = Ext.num(h, Ext.num(def.h, dt.getHours()));",
+ "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
+ "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
+ "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
+
+ "if(z >= 0 && y >= 0){",
+
+
+
+
+
+ "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
+
+
+ "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
+ "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
+ "v = null;",
+ "}else{",
+
+
+ "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
+ "}",
+ "}",
+ "}",
+
+ "if(v){",
+
+ "if(zz != null){",
+
+ "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
+ "}else if(o){",
+
+ "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
+ "}",
+ "}",
+
+ "return v;"
+ ].join('\n');
+
+ return function(format) {
+ var regexNum = Date.parseRegexes.length,
+ currentGroup = 1,
+ calc = [],
+ regex = [],
+ special = false,
+ ch = "",
+ i = 0,
+ obj,
+ last;
+
+ for (; i < format.length; ++i) {
+ ch = format.charAt(i);
+ if (!special && ch == "\\") {
+ special = true;
+ } else if (special) {
+ special = false;
+ regex.push(String.escape(ch));
+ } else {
+ obj = $f(ch, currentGroup);
+ currentGroup += obj.g;
+ regex.push(obj.s);
+ if (obj.g && obj.c) {
+ if (obj.calcLast) {
+ last = obj.c;
+ } else {
+ calc.push(obj.c);
+ }
+ }
+ }
+ }
+
+ if (last) {
+ calc.push(last);
+ }
+
+ Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
+ Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
+ };
+ }(),
+
+
+ parseCodes : {
+
+ d: {
+ g:1,
+ c:"d = parseInt(results[{0}], 10);\n",
+ s:"(\\d{2})"
+ },
+ j: {
+ g:1,
+ c:"d = parseInt(results[{0}], 10);\n",
+ s:"(\\d{1,2})"
+ },
+ D: function() {
+ for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
+ return {
+ g:0,
+ c:null,
+ s:"(?:" + a.join("|") +")"
+ };
+ },
+ l: function() {
+ return {
+ g:0,
+ c:null,
+ s:"(?:" + Date.dayNames.join("|") + ")"
+ };
+ },
+ N: {
+ g:0,
+ c:null,
+ s:"[1-7]"
+ },
+ S: {
+ g:0,
+ c:null,
+ s:"(?:st|nd|rd|th)"
+ },
+ w: {
+ g:0,
+ c:null,
+ s:"[0-6]"
+ },
+ z: {
+ g:1,
+ c:"z = parseInt(results[{0}], 10);\n",
+ s:"(\\d{1,3})"
+ },
+ W: {
+ g:0,
+ c:null,
+ s:"(?:\\d{2})"
+ },
+ F: function() {
+ return {
+ g:1,
+ c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
+ s:"(" + Date.monthNames.join("|") + ")"
+ };
+ },
+ M: function() {
+ for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
+ return Ext.applyIf({
+ s:"(" + a.join("|") + ")"
+ }, $f("F"));
+ },
+ m: {
+ g:1,
+ c:"m = parseInt(results[{0}], 10) - 1;\n",
+ s:"(\\d{2})"
+ },
+ n: {
+ g:1,
+ c:"m = parseInt(results[{0}], 10) - 1;\n",
+ s:"(\\d{1,2})"
+ },
+ t: {
+ g:0,
+ c:null,
+ s:"(?:\\d{2})"
+ },
+ L: {
+ g:0,
+ c:null,
+ s:"(?:1|0)"
+ },
+ o: function() {
+ return $f("Y");
+ },
+ Y: {
+ g:1,
+ c:"y = parseInt(results[{0}], 10);\n",
+ s:"(\\d{4})"
+ },
+ y: {
+ g:1,
+ c:"var ty = parseInt(results[{0}], 10);\n"
+ + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
+ s:"(\\d{1,2})"
+ },
+
+ a: function(){
+ return $f("A");
+ },
+ A: {
+
+ calcLast: true,
+ g:1,
+ c:"if (/(am)/i.test(results[{0}])) {\n"
+ + "if (!h || h == 12) { h = 0; }\n"
+ + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
+ s:"(AM|PM|am|pm)"
+ },
+ g: function() {
+ return $f("G");
+ },
+ G: {
+ g:1,
+ c:"h = parseInt(results[{0}], 10);\n",
+ s:"(\\d{1,2})"
+ },
+ h: function() {
+ return $f("H");
+ },
+ H: {
+ g:1,
+ c:"h = parseInt(results[{0}], 10);\n",
+ s:"(\\d{2})"
+ },
+ i: {
+ g:1,
+ c:"i = parseInt(results[{0}], 10);\n",
+ s:"(\\d{2})"
+ },
+ s: {
+ g:1,
+ c:"s = parseInt(results[{0}], 10);\n",
+ s:"(\\d{2})"
+ },
+ u: {
+ g:1,
+ c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
+ s:"(\\d+)"
+ },
+ O: {
+ g:1,
+ c:[
+ "o = results[{0}];",
+ "var sn = o.substring(0,1),",
+ "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
+ "mn = o.substring(3,5) % 60;",
+ "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
+ ].join("\n"),
+ s: "([+\-]\\d{4})"
+ },
+ P: {
+ g:1,
+ c:[
+ "o = results[{0}];",
+ "var sn = o.substring(0,1),",
+ "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
+ "mn = o.substring(4,6) % 60;",
+ "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
+ ].join("\n"),
+ s: "([+\-]\\d{2}:\\d{2})"
+ },
+ T: {
+ g:0,
+ c:null,
+ s:"[A-Z]{1,4}"
+ },
+ Z: {
+ g:1,
+ c:"zz = results[{0}] * 1;\n"
+ + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
+ s:"([+\-]?\\d{1,5})"
+ },
+ c: function() {
+ var calc = [],
+ arr = [
+ $f("Y", 1),
+ $f("m", 2),
+ $f("d", 3),
+ $f("h", 4),
+ $f("i", 5),
+ $f("s", 6),
+ {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},
+ {c:[
+ "if(results[8]) {",
+ "if(results[8] == 'Z'){",
+ "zz = 0;",
+ "}else if (results[8].indexOf(':') > -1){",
+ $f("P", 8).c,
+ "}else{",
+ $f("O", 8).c,
+ "}",
+ "}"
+ ].join('\n')}
+ ];
+
+ for (var i = 0, l = arr.length; i < l; ++i) {
+ calc.push(arr[i].c);
+ }
+
+ return {
+ g:1,
+ c:calc.join(""),
+ s:[
+ arr[0].s,
+ "(?:", "-", arr[1].s,
+ "(?:", "-", arr[2].s,
+ "(?:",
+ "(?:T| )?",
+ arr[3].s, ":", arr[4].s,
+ "(?::", arr[5].s, ")?",
+ "(?:(?:\\.|,)(\\d+))?",
+ "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
+ ")?",
+ ")?",
+ ")?"
+ ].join("")
+ };
+ },
+ U: {
+ g:1,
+ c:"u = parseInt(results[{0}], 10);\n",
+ s:"(-?\\d+)"
+ }
+ }
+});
+
+}());
+
+Ext.apply(Date.prototype, {
+
+ dateFormat : function(format) {
+ if (Date.formatFunctions[format] == null) {
+ Date.createFormat(format);
+ }
+ return Date.formatFunctions[format].call(this);
+ },
+
+
+ getTimezone : function() {
+
+
+
+
+
+
+
+
+
+
+
+
+ return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
+ },
+
+
+ getGMTOffset : function(colon) {
+ return (this.getTimezoneOffset() > 0 ? "-" : "+")
+ + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
+ + (colon ? ":" : "")
+ + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
+ },
+
+
+ getDayOfYear: function() {
+ var num = 0,
+ d = this.clone(),
+ m = this.getMonth(),
+ i;
+
+ for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
+ num += d.getDaysInMonth();
+ }
+ return num + this.getDate() - 1;
+ },
+
+
+ getWeekOfYear : function() {
+
+ var ms1d = 864e5,
+ ms7d = 7 * ms1d;
+
+ return function() {
+ var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
+ AWN = Math.floor(DC3 / 7),
+ Wyr = new Date(AWN * ms7d).getUTCFullYear();
+
+ return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
+ };
+ }(),
+
+
+ isLeapYear : function() {
+ var year = this.getFullYear();
+ return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
+ },
+
+
+ getFirstDayOfMonth : function() {
+ var day = (this.getDay() - (this.getDate() - 1)) % 7;
+ return (day < 0) ? (day + 7) : day;
+ },
+
+
+ getLastDayOfMonth : function() {
+ return this.getLastDateOfMonth().getDay();
+ },
+
+
+
+ getFirstDateOfMonth : function() {
+ return new Date(this.getFullYear(), this.getMonth(), 1);
+ },
+
+
+ getLastDateOfMonth : function() {
+ return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
+ },
+
+
+ getDaysInMonth: function() {
+ var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+ return function() {
+ var m = this.getMonth();
+
+ return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
+ };
+ }(),
+
+
+ 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";
+ }
+ },
+
+
+ clone : function() {
+ return new Date(this.getTime());
+ },
+
+
+ isDST : function() {
+
+
+ return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
+ },
+
+
+ clearTime : function(clone) {
+ if (clone) {
+ return this.clone().clearTime();
+ }
+
+
+ var d = this.getDate();
+
+
+ this.setHours(0);
+ this.setMinutes(0);
+ this.setSeconds(0);
+ this.setMilliseconds(0);
+
+ if (this.getDate() != d) {
+
+
+
+
+ for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
+
+ this.setDate(d);
+ this.setHours(c.getHours());
+ }
+
+ return this;
+ },
+
+
+ add : function(interval, value) {
+ var d = this.clone();
+ if (!interval || value === 0) return d;
+
+ switch(interval.toLowerCase()) {
+ case Date.MILLI:
+ d.setMilliseconds(this.getMilliseconds() + value);
+ break;
+ case Date.SECOND:
+ d.setSeconds(this.getSeconds() + value);
+ break;
+ case Date.MINUTE:
+ d.setMinutes(this.getMinutes() + value);
+ break;
+ case Date.HOUR:
+ d.setHours(this.getHours() + value);
+ break;
+ case Date.DAY:
+ d.setDate(this.getDate() + value);
+ break;
+ case Date.MONTH:
+ var day = this.getDate();
+ if (day > 28) {
+ day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
+ }
+ d.setDate(day);
+ d.setMonth(this.getMonth() + value);
+ break;
+ case Date.YEAR:
+ d.setFullYear(this.getFullYear() + value);
+ break;
+ }
+ return d;
+ },
+
+
+ between : function(start, end) {
+ var t = this.getTime();
+ return start.getTime() <= t && t <= end.getTime();
+ }
+});
+
+
+
+Date.prototype.format = Date.prototype.dateFormat;
+
+
+
+if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
+ Ext.apply(Date.prototype, {
+ _xMonth : Date.prototype.setMonth,
+ _xDate : Date.prototype.setDate,
+
+
+
+ setMonth : function(num) {
+ if (num <= -1) {
+ var n = Math.ceil(-num),
+ back_year = Math.ceil(n / 12),
+ month = (n % 12) ? 12 - n % 12 : 0;
+
+ this.setFullYear(this.getFullYear() - back_year);
+
+ return this._xMonth(month);
+ } else {
+ return this._xMonth(num);
+ }
+ },
+
+
+
+
+ setDate : function(d) {
+
+
+ return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
+ }
+ });
+}
+
+
+
+
+
+Ext.util.MixedCollection = function(allowFunctions, keyFn){
+ this.items = [];
+ this.map = {};
+ this.keys = [];
+ this.length = 0;
+ this.addEvents(
+
+ 'clear',
+
+ 'add',
+
+ 'replace',
+
+ 'remove',
+ 'sort'
+ );
+ this.allowFunctions = allowFunctions === true;
+ if(keyFn){
+ this.getKey = keyFn;
+ }
+ Ext.util.MixedCollection.superclass.constructor.call(this);
+};
+
+Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
+
+
+ allowFunctions : false,
+
+
+ add : function(key, o){
+ if(arguments.length == 1){
+ o = arguments[0];
+ key = this.getKey(o);
+ }
+ if(typeof key != 'undefined' && key !== null){
+ var old = this.map[key];
+ if(typeof old != 'undefined'){
+ return this.replace(key, o);
+ }
+ this.map[key] = o;
+ }
+ this.length++;
+ this.items.push(o);
+ this.keys.push(key);
+ this.fireEvent('add', this.length-1, o, key);
+ return o;
+ },
+
+
+ getKey : function(o){
+ return o.id;
+ },
+
+
+ replace : function(key, o){
+ if(arguments.length == 1){
+ o = arguments[0];
+ key = this.getKey(o);
+ }
+ var old = this.map[key];
+ if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
+ return this.add(key, o);
+ }
+ var index = this.indexOfKey(key);
+ this.items[index] = o;
+ this.map[key] = o;
+ this.fireEvent('replace', key, old, o);
+ return o;
+ },
+
+
+ addAll : function(objs){
+ if(arguments.length > 1 || Ext.isArray(objs)){
+ var args = arguments.length > 1 ? arguments : objs;
+ for(var i = 0, len = args.length; i < len; i++){
+ this.add(args[i]);
+ }
+ }else{
+ for(var key in objs){
+ if(this.allowFunctions || typeof objs[key] != 'function'){
+ this.add(key, objs[key]);
+ }
+ }
+ }
+ },
+
+
+ each : function(fn, scope){
+ var items = [].concat(this.items);
+ for(var i = 0, len = items.length; i < len; i++){
+ if(fn.call(scope || items[i], items[i], i, len) === false){
+ break;
+ }
+ }
+ },
+
+
+ eachKey : function(fn, scope){
+ for(var i = 0, len = this.keys.length; i < len; i++){
+ fn.call(scope || window, this.keys[i], this.items[i], i, len);
+ }
+ },
+
+
+ find : function(fn, scope){
+ for(var i = 0, len = this.items.length; i < len; i++){
+ if(fn.call(scope || window, this.items[i], this.keys[i])){
+ return this.items[i];
+ }
+ }
+ return null;
+ },
+
+
+ insert : function(index, key, o){
+ if(arguments.length == 2){
+ o = arguments[1];
+ key = this.getKey(o);
+ }
+ if(this.containsKey(key)){
+ this.suspendEvents();
+ this.removeKey(key);
+ this.resumeEvents();
+ }
+ if(index >= this.length){
+ return this.add(key, o);
+ }
+ this.length++;
+ this.items.splice(index, 0, o);
+ if(typeof key != 'undefined' && key !== null){
+ this.map[key] = o;
+ }
+ this.keys.splice(index, 0, key);
+ this.fireEvent('add', index, o, key);
+ return o;
+ },
+
+
+ remove : function(o){
+ return this.removeAt(this.indexOf(o));
+ },
+
+
+ removeAt : function(index){
+ if(index < this.length && index >= 0){
+ this.length--;
+ var o = this.items[index];
+ this.items.splice(index, 1);
+ var key = this.keys[index];
+ if(typeof key != 'undefined'){
+ delete this.map[key];
+ }
+ this.keys.splice(index, 1);
+ this.fireEvent('remove', o, key);
+ return o;
+ }
+ return false;
+ },
+
+
+ removeKey : function(key){
+ return this.removeAt(this.indexOfKey(key));
+ },
+
+
+ getCount : function(){
+ return this.length;
+ },
+
+
+ indexOf : function(o){
+ return this.items.indexOf(o);
+ },
+
+
+ indexOfKey : function(key){
+ return this.keys.indexOf(key);
+ },
+
+
+ item : function(key){
+ var mk = this.map[key],
+ item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
+ return typeof item != 'function' || this.allowFunctions ? item : null;
+ },
+
+
+ itemAt : function(index){
+ return this.items[index];
+ },
+
+
+ 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(property, dir, fn){
+ var i, len,
+ dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
+
+
+ c = [],
+ keys = this.keys,
+ items = this.items;
+
+
+ fn = fn || function(a, b) {
+ return a - b;
+ };
+
+
+ for(i = 0, len = items.length; i < len; i++){
+ c[c.length] = {
+ key : keys[i],
+ value: items[i],
+ index: i
+ };
+ }
+
+
+ c.sort(function(a, b){
+ var v = fn(a[property], b[property]) * dsc;
+ if(v === 0){
+ v = (a.index < b.index ? -1 : 1);
+ }
+ return v;
+ });
+
+
+ for(i = 0, len = c.length; i < len; i++){
+ items[i] = c[i].value;
+ keys[i] = c[i].key;
+ }
+
+ this.fireEvent('sort', this);
+ },
+
+
+ sort : function(dir, fn){
+ this._sort('value', dir, fn);
+ },
+
+
+ reorder: function(mapping) {
+ this.suspendEvents();
+
+ var items = this.items,
+ index = 0,
+ length = items.length,
+ order = [],
+ remaining = [],
+ oldIndex;
+
+
+ for (oldIndex in mapping) {
+ order[mapping[oldIndex]] = items[oldIndex];
+ }
+
+ for (index = 0; index < length; index++) {
+ if (mapping[index] == undefined) {
+ remaining.push(items[index]);
+ }
+ }
+
+ for (index = 0; index < length; index++) {
+ if (order[index] == undefined) {
+ order[index] = remaining.shift();
+ }
+ }
+
+ this.clear();
+ this.addAll(order);
+
+ this.resumeEvents();
+ this.fireEvent('sort', this);
+ },
+
+
+ keySort : function(dir, fn){
+ this._sort('key', dir, fn || function(a, b){
+ var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
+ return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+ });
+ },
+
+
+ getRange : function(start, end){
+ var items = this.items;
+ if(items.length < 1){
+ return [];
+ }
+ start = start || 0;
+ end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
+ var i, r = [];
+ if(start <= end){
+ for(i = start; i <= end; i++) {
+ r[r.length] = items[i];
+ }
+ }else{
+ for(i = start; i >= end; i--) {
+ r[r.length] = items[i];
+ }
+ }
+ return r;
+ },
+
+
+ filter : function(property, value, anyMatch, caseSensitive){
+ if(Ext.isEmpty(value, false)){
+ return this.clone();
+ }
+ value = this.createValueMatcher(value, anyMatch, caseSensitive);
+ return this.filterBy(function(o){
+ return o && value.test(o[property]);
+ });
+ },
+
+
+ filterBy : function(fn, scope){
+ 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(scope||this, it[i], k[i])){
+ r.add(k[i], it[i]);
+ }
+ }
+ return r;
+ },
+
+
+ findIndex : function(property, value, start, anyMatch, caseSensitive){
+ if(Ext.isEmpty(value, false)){
+ return -1;
+ }
+ value = this.createValueMatcher(value, anyMatch, caseSensitive);
+ return this.findIndexBy(function(o){
+ return o && value.test(o[property]);
+ }, null, start);
+ },
+
+
+ findIndexBy : function(fn, scope, start){
+ var k = this.keys, it = this.items;
+ for(var i = (start||0), len = it.length; i < len; i++){
+ if(fn.call(scope||this, it[i], k[i])){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+
+ createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
+ if (!value.exec) {
+ var er = Ext.escapeRe;
+ value = String(value);
+
+ if (anyMatch === true) {
+ value = er(value);
+ } else {
+ value = '^' + er(value);
+ if (exactMatch === true) {
+ value += '$';
+ }
+ }
+ value = new RegExp(value, caseSensitive ? '' : 'i');
+ }
+ return value;
+ },
+
+
+ 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.AbstractManager = Ext.extend(Object, {
+ typeName: 'type',
+
+ constructor: function(config) {
+ Ext.apply(this, config || {});
+
+
+ this.all = new Ext.util.MixedCollection();
+
+ this.types = {};
+ },
+
+
+ get : function(id){
+ return this.all.get(id);
+ },
+
+
+ register: function(item) {
+ this.all.add(item);
+ },
+
+
+ unregister: function(item) {
+ this.all.remove(item);
+ },
+
+
+ registerType : function(type, cls){
+ this.types[type] = cls;
+ cls[this.typeName] = type;
+ },
+
+
+ isRegistered : function(type){
+ return this.types[type] !== undefined;
+ },
+
+
+ create: function(config, defaultType) {
+ var type = config[this.typeName] || config.type || defaultType,
+ Constructor = this.types[type];
+
+ if (Constructor == undefined) {
+ throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
+ }
+
+ return new Constructor(config);
+ },
+
+
+ onAvailable : function(id, fn, scope){
+ var all = this.all;
+
+ all.on("add", function(index, o){
+ if (o.id == id) {
+ fn.call(scope || o, o);
+ all.un("add", fn, scope);
+ }
+ });
+ }
+});
+Ext.util.Format = function() {
+ var trimRe = /^\s+|\s+$/g,
+ stripTagsRE = /<\/?[^>]+>/gi,
+ stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
+ nl2brRe = /\r?\n/g;
+
+ return {
+
+ ellipsis : function(value, len, word) {
+ if (value && value.length > len) {
+ if (word) {
+ var vs = value.substr(0, len - 2),
+ index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
+ if (index == -1 || index < (len - 15)) {
+ return value.substr(0, len - 3) + "...";
+ } else {
+ return vs.substr(0, index) + "...";
+ }
+ } else {
+ return value.substr(0, len - 3) + "...";
+ }
+ }
+ return value;
+ },
+
+
+ undef : function(value) {
+ return value !== undefined ? value : "";
+ },
+
+
+ defaultValue : function(value, defaultValue) {
+ if (!defaultValue && defaultValue !== 0) {
+ defaultValue = '';
+ }
+ return value !== undefined && value !== '' ? value : defaultValue;
+ },
+
+
+ htmlEncode : function(value) {
+ return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
+ },
+
+
+ htmlDecode : function(value) {
+ return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
+ },
+
+
+ trim : function(value) {
+ return String(value).replace(trimRe, "");
+ },
+
+
+ substr : function(value, start, length) {
+ return String(value).substr(start, length);
+ },
+
+
+ lowercase : function(value) {
+ return String(value).toLowerCase();
+ },
+
+
+ uppercase : function(value) {
+ return String(value).toUpperCase();
+ },
+
+
+ capitalize : function(value) {
+ return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
+ },
+
+
+ call : function(value, fn) {
+ if (arguments.length > 2) {
+ var args = Array.prototype.slice.call(arguments, 2);
+ args.unshift(value);
+ return eval(fn).apply(window, args);
+ } else {
+ return eval(fn).call(window, value);
+ }
+ },
+
+
+ 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);
+ v = String(v);
+ var ps = v.split('.'),
+ whole = ps[0],
+ sub = ps[1] ? '.'+ ps[1] : '.00',
+ r = /(\d+)(\d{3})/;
+ while (r.test(whole)) {
+ whole = whole.replace(r, '$1' + ',' + '$2');
+ }
+ v = whole + sub;
+ if (v.charAt(0) == '-') {
+ return '-$' + v.substr(1);
+ }
+ return "$" + v;
+ },
+
+
+ date : function(v, format) {
+ if (!v) {
+ return "";
+ }
+ if (!Ext.isDate(v)) {
+ v = new Date(Date.parse(v));
+ }
+ return v.dateFormat(format || "m/d/Y");
+ },
+
+
+ dateRenderer : function(format) {
+ return function(v) {
+ return Ext.util.Format.date(v, format);
+ };
+ },
+
+
+ stripTags : function(v) {
+ return !v ? v : String(v).replace(stripTagsRE, "");
+ },
+
+
+ stripScripts : function(v) {
+ return !v ? v : String(v).replace(stripScriptsRe, "");
+ },
+
+
+ fileSize : function(size) {
+ if (size < 1024) {
+ return size + " bytes";
+ } else if (size < 1048576) {
+ return (Math.round(((size*10) / 1024))/10) + " KB";
+ } else {
+ return (Math.round(((size*10) / 1048576))/10) + " MB";
+ }
+ },
+
+
+ math : function(){
+ var fns = {};
+
+ return function(v, a){
+ if (!fns[a]) {
+ fns[a] = new Function('v', 'return v ' + a + ';');
+ }
+ return fns[a](v);
+ };
+ }(),
+
+
+ round : function(value, precision) {
+ var result = Number(value);
+ if (typeof precision == 'number') {
+ precision = Math.pow(10, precision);
+ result = Math.round(value * precision) / precision;
+ }
+ return result;
+ },
+
+
+ number: function(v, format) {
+ if (!format) {
+ return v;
+ }
+ v = Ext.num(v, NaN);
+ if (isNaN(v)) {
+ return '';
+ }
+ var comma = ',',
+ dec = '.',
+ i18n = false,
+ neg = v < 0;
+
+ v = Math.abs(v);
+ if (format.substr(format.length - 2) == '/i') {
+ format = format.substr(0, format.length - 2);
+ i18n = true;
+ comma = '.';
+ dec = ',';
+ }
+
+ var hasComma = format.indexOf(comma) != -1,
+ psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
+
+ if (1 < psplit.length) {
+ v = v.toFixed(psplit[1].length);
+ } else if(2 < psplit.length) {
+ throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
+ } else {
+ v = v.toFixed(0);
+ }
+
+ var fnum = v.toString();
+
+ psplit = fnum.split('.');
+
+ if (hasComma) {
+ var cnum = psplit[0],
+ parr = [],
+ j = cnum.length,
+ m = Math.floor(j / 3),
+ n = cnum.length % 3 || 3,
+ i;
+
+ for (i = 0; i < j; i += n) {
+ if (i != 0) {
+ n = 3;
+ }
+
+ parr[parr.length] = cnum.substr(i, n);
+ m -= 1;
+ }
+ fnum = parr.join(comma);
+ if (psplit[1]) {
+ fnum += dec + psplit[1];
+ }
+ } else {
+ if (psplit[1]) {
+ fnum = psplit[0] + dec + psplit[1];
+ }
+ }
+
+ return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
+ },
+
+
+ numberRenderer : function(format) {
+ return function(v) {
+ return Ext.util.Format.number(v, format);
+ };
+ },
+
+
+ plural : function(v, s, p) {
+ return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
+ },
+
+
+ nl2br : function(v) {
+ return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
+ }
+ };
+}();
+
+Ext.XTemplate = function(){
+ Ext.XTemplate.superclass.constructor.apply(this, arguments);
+
+ var me = this,
+ s = me.html,
+ re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
+ nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
+ ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
+ execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
+ m,
+ id = 0,
+ tpls = [],
+ VALUES = 'values',
+ PARENT = 'parent',
+ XINDEX = 'xindex',
+ XCOUNT = 'xcount',
+ RETURN = 'return ',
+ WITHVALUES = 'with(values){ ';
+
+ s = ['<tpl>', s, '</tpl>'].join('');
+
+ while((m = s.match(re))){
+ var m2 = m[0].match(nameRe),
+ m3 = m[0].match(ifRe),
+ m4 = m[0].match(execRe),
+ exp = null,
+ fn = null,
+ exec = null,
+ name = m2 && m2[1] ? m2[1] : '';
+
+ if (m3) {
+ exp = m3 && m3[1] ? m3[1] : null;
+ if(exp){
+ fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
+ }
+ }
+ if (m4) {
+ exp = m4 && m4[1] ? m4[1] : null;
+ if(exp){
+ exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
+ }
+ }
+ if(name){
+ switch(name){
+ case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
+ case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
+ default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
+ }
+ }
+ tpls.push({
+ id: id,
+ target: name,
+ exec: exec,
+ test: fn,
+ body: m[1]||''
+ });
+ s = s.replace(m[0], '{xtpl'+ id + '}');
+ ++id;
+ }
+ for(var i = tpls.length-1; i >= 0; --i){
+ me.compileTpl(tpls[i]);
+ }
+ me.master = tpls[tpls.length-1];
+ me.tpls = tpls;
+};
+Ext.extend(Ext.XTemplate, Ext.Template, {
+
+ re : /\{([\w\-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
+
+ codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
+
+
+ applySubTemplate : function(id, values, parent, xindex, xcount){
+ var me = this,
+ len,
+ t = me.tpls[id],
+ vs,
+ buf = [];
+ if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
+ (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
+ return '';
+ }
+ vs = t.target ? t.target.call(me, values, parent) : values;
+ len = vs.length;
+ parent = t.target ? values : parent;
+ if(t.target && Ext.isArray(vs)){
+ for(var i = 0, len = vs.length; i < len; i++){
+ buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
+ }
+ return buf.join('');
+ }
+ return t.compiled.call(me, vs, parent, xindex, xcount);
+ },
+
+
+ compileTpl : function(tpl){
+ var fm = Ext.util.Format,
+ useF = this.disableFormats !== true,
+ sep = Ext.isGecko ? "+" : ",",
+ body;
+
+ function fn(m, name, format, args, math){
+ if(name.substr(0, 4) == 'xtpl'){
+ return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
+ }
+ var v;
+ if(name === '.'){
+ v = 'values';
+ }else if(name === '#'){
+ v = 'xindex';
+ }else if(name.indexOf('.') != -1){
+ v = name;
+ }else{
+ v = "values['" + name + "']";
+ }
+ if(math){
+ v = '(' + v + math + ')';
+ }
+ if (format && useF) {
+ args = args ? ',' + args : "";
+ if(format.substr(0, 5) != "this."){
+ format = "fm." + format + '(';
+ }else{
+ format = 'this.call("'+ format.substr(5) + '", ';
+ args = ", values";
+ }
+ } else {
+ args= ''; format = "("+v+" === undefined ? '' : ";
+ }
+ return "'"+ sep + format + v + args + ")"+sep+"'";
+ }
+
+ function codeFn(m, code){
+
+ return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
+ }
+
+
+ if(Ext.isGecko){
+ body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
+ tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
+ "';};";
+ }else{
+ body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
+ body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
+ body.push("'].join('');};");
+ body = body.join('');
+ }
+ eval(body);
+ return this;
+ },
+
+
+ applyTemplate : function(values){
+ return this.master.compiled.call(this, values, {}, 1, 1);
+ },
+
+
+ compile : function(){return this;}
+
+
+
+
+
+});
+
+Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
+
+
+Ext.XTemplate.from = function(el){
+ el = Ext.getDom(el);
+ return new Ext.XTemplate(el.value || el.innerHTML);
+};
+
+Ext.util.CSS = function(){
+ var rules = null;
+ var doc = document;
+
+ var camelRe = /(-[a-z])/gi;
+ var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
+
+ return {
+
+ createStyleSheet : function(cssText, id){
+ var ss;
+ var head = doc.getElementsByTagName("head")[0];
+ var rules = doc.createElement("style");
+ rules.setAttribute("type", "text/css");
+ if(id){
+ rules.setAttribute("id", id);
+ }
+ if(Ext.isIE){
+ head.appendChild(rules);
+ ss = rules.styleSheet;
+ ss.cssText = cssText;
+ }else{
+ try{
+ rules.appendChild(doc.createTextNode(cssText));
+ }catch(e){
+ rules.cssText = cssText;
+ }
+ head.appendChild(rules);
+ ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
+ }
+ this.cacheStyleSheet(ss);
+ return ss;
+ },
+
+
+ removeStyleSheet : function(id){
+ var existing = doc.getElementById(id);
+ if(existing){
+ existing.parentNode.removeChild(existing);
+ }
+ },
+
+
+ swapStyleSheet : function(id, url){
+ this.removeStyleSheet(id);
+ var ss = doc.createElement("link");
+ ss.setAttribute("rel", "stylesheet");
+ ss.setAttribute("type", "text/css");
+ ss.setAttribute("id", id);
+ ss.setAttribute("href", url);
+ doc.getElementsByTagName("head")[0].appendChild(ss);
+ },
+
+
+ refreshCache : function(){
+ return this.getRules(true);
+ },
+
+
+ cacheStyleSheet : function(ss){
+ if(!rules){
+ rules = {};
+ }
+ try{
+ var ssRules = ss.cssRules || ss.rules;
+ for(var j = ssRules.length-1; j >= 0; --j){
+ rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
+ }
+ }catch(e){}
+ },
+
+
+ getRules : function(refreshCache){
+ if(rules === null || refreshCache){
+ rules = {};
+ var ds = doc.styleSheets;
+ for(var i =0, len = ds.length; i < len; i++){
+ try{
+ this.cacheStyleSheet(ds[i]);
+ }catch(e){}
+ }
+ }
+ return rules;
+ },
+
+
+ getRule : function(selector, refreshCache){
+ var rs = this.getRules(refreshCache);
+ if(!Ext.isArray(selector)){
+ return rs[selector.toLowerCase()];
+ }
+ for(var i = 0; i < selector.length; i++){
+ if(rs[selector[i]]){
+ return rs[selector[i].toLowerCase()];
+ }
+ }
+ return null;
+ },
+
+
+
+ updateRule : function(selector, property, value){
+ if(!Ext.isArray(selector)){
+ var rule = this.getRule(selector);
+ if(rule){
+ rule.style[property.replace(camelRe, camelFn)] = value;
+ return true;
+ }
+ }else{
+ for(var i = 0; i < selector.length; i++){
+ if(this.updateRule(selector[i], property, value)){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ };
+}();
+Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
+
+ constructor : function(el, config){
+ this.el = Ext.get(el);
+ this.el.unselectable();
+
+ Ext.apply(this, config);
+
+ this.addEvents(
+
+ "mousedown",
+
+ "click",
+
+ "mouseup"
+ );
+
+ if(!this.disabled){
+ this.disabled = true;
+ this.enable();
+ }
+
+
+ if(this.handler){
+ this.on("click", this.handler, this.scope || this);
+ }
+
+ Ext.util.ClickRepeater.superclass.constructor.call(this);
+ },
+
+ interval : 20,
+ delay: 250,
+ preventDefault : true,
+ stopDefault : false,
+ timer : 0,
+
+
+ enable: function(){
+ if(this.disabled){
+ this.el.on('mousedown', this.handleMouseDown, this);
+ if (Ext.isIE){
+ this.el.on('dblclick', this.handleDblClick, this);
+ }
+ if(this.preventDefault || this.stopDefault){
+ this.el.on('click', this.eventOptions, this);
+ }
+ }
+ this.disabled = false;
+ },
+
+
+ disable: function( force){
+ if(force || !this.disabled){
+ clearTimeout(this.timer);
+ if(this.pressClass){
+ this.el.removeClass(this.pressClass);
+ }
+ Ext.getDoc().un('mouseup', this.handleMouseUp, this);
+ this.el.removeAllListeners();
+ }
+ this.disabled = true;
+ },
+
+
+ setDisabled: function(disabled){
+ this[disabled ? 'disable' : 'enable']();
+ },
+
+ eventOptions: function(e){
+ if(this.preventDefault){
+ e.preventDefault();
+ }
+ if(this.stopDefault){
+ e.stopEvent();
+ }
+ },
+
+
+ destroy : function() {
+ this.disable(true);
+ Ext.destroy(this.el);
+ this.purgeListeners();
+ },
+
+ handleDblClick : function(e){
+ clearTimeout(this.timer);
+ this.el.blur();
+
+ this.fireEvent("mousedown", this, e);
+ this.fireEvent("click", this, e);
+ },
+
+
+ handleMouseDown : function(e){
+ clearTimeout(this.timer);
+ this.el.blur();
+ if(this.pressClass){
+ this.el.addClass(this.pressClass);
+ }
+ this.mousedownTime = new Date();
+
+ Ext.getDoc().on("mouseup", this.handleMouseUp, this);
+ this.el.on("mouseout", this.handleMouseOut, this);
+
+ this.fireEvent("mousedown", this, e);
+ this.fireEvent("click", this, e);
+
+
+ if (this.accelerate) {
+ this.delay = 400;
+ }
+ this.timer = this.click.defer(this.delay || this.interval, this, [e]);
+ },
+
+
+ click : function(e){
+ this.fireEvent("click", this, e);
+ this.timer = this.click.defer(this.accelerate ?
+ this.easeOutExpo(this.mousedownTime.getElapsed(),
+ 400,
+ -390,
+ 12000) :
+ this.interval, this, [e]);
+ },
+
+ easeOutExpo : function (t, b, c, d) {
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+ },
+
+
+ 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, this);
+ if(this.pressClass){
+ this.el.addClass(this.pressClass);
+ }
+ this.click();
+ },
+
+
+ handleMouseUp : function(e){
+ clearTimeout(this.timer);
+ this.el.un("mouseover", this.handleMouseReturn, this);
+ this.el.un("mouseout", this.handleMouseOut, this);
+ Ext.getDoc().un("mouseup", this.handleMouseUp, this);
+ this.el.removeClass(this.pressClass);
+ this.fireEvent("mouseup", this, e);
+ }
+});
+Ext.KeyNav = function(el, config){
+ this.el = Ext.get(el);
+ Ext.apply(this, config);
+ if(!this.disabled){
+ this.disabled = true;
+ this.enable();
+ }
+};
+
+Ext.KeyNav.prototype = {
+
+ disabled : false,
+
+ defaultEventAction: "stopEvent",
+
+ forceKeyDown : false,
+
+
+ relay : function(e){
+ var k = e.getKey(),
+ h = this.keyToHandler[k];
+ if(h && this[h]){
+ if(this.doRelay(e, this[h], h) !== true){
+ e[this.defaultEventAction]();
+ }
+ }
+ },
+
+
+ doRelay : function(e, h, hname){
+ return h.call(this.scope || this, e, hname);
+ },
+
+
+ enter : false,
+ left : false,
+ right : false,
+ up : false,
+ down : false,
+ tab : false,
+ esc : false,
+ pageUp : false,
+ pageDown : false,
+ del : false,
+ home : false,
+ end : false,
+ space : 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",
+ 32 : "space"
+ },
+
+ stopKeyUp: function(e) {
+ var k = e.getKey();
+
+ if (k >= 37 && k <= 40) {
+
+
+ e.stopEvent();
+ }
+ },
+
+
+ destroy: function(){
+ this.disable();
+ },
+
+
+ enable: function() {
+ if (this.disabled) {
+ if (Ext.isSafari2) {
+
+ this.el.on('keyup', this.stopKeyUp, this);
+ }
+
+ this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+ this.disabled = false;
+ }
+ },
+
+
+ disable: function() {
+ if (!this.disabled) {
+ if (Ext.isSafari2) {
+
+ this.el.un('keyup', this.stopKeyUp, this);
+ }
+
+ this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+ this.disabled = true;
+ }
+ },
+
+
+ setDisabled : function(disabled){
+ this[disabled ? "disable" : "enable"]();
+ },
+
+
+ isKeydown: function(){
+ return this.forceKeyDown || Ext.EventManager.useKeydown;
+ }
+};
+
+Ext.KeyMap = function(el, config, eventName){
+ this.el = Ext.get(el);
+ this.eventName = eventName || "keydown";
+ this.bindings = [];
+ if(config){
+ this.addBinding(config);
+ }
+ this.enable();
+};
+
+Ext.KeyMap.prototype = {
+
+ stopEvent : false,
+
+
+ addBinding : function(config){
+ if(Ext.isArray(config)){
+ Ext.each(config, function(c){
+ this.addBinding(c);
+ }, this);
+ return;
+ }
+ var keyCode = config.key,
+ fn = config.fn || config.handler,
+ scope = config.scope;
+
+ if (config.stopEvent) {
+ this.stopEvent = config.stopEvent;
+ }
+
+ if(typeof keyCode == "string"){
+ var ks = [];
+ var keyString = keyCode.toUpperCase();
+ for(var j = 0, len = keyString.length; j < len; j++){
+ ks.push(keyString.charCodeAt(j));
+ }
+ keyCode = ks;
+ }
+ var keyArray = Ext.isArray(keyCode);
+
+ var handler = function(e){
+ if(this.checkModifiers(config, e)){
+ var k = e.getKey();
+ if(keyArray){
+ for(var i = 0, len = keyCode.length; i < len; i++){
+ if(keyCode[i] == k){
+ if(this.stopEvent){
+ e.stopEvent();
+ }
+ fn.call(scope || window, k, e);
+ return;
+ }
+ }
+ }else{
+ if(k == keyCode){
+ if(this.stopEvent){
+ e.stopEvent();
+ }
+ fn.call(scope || window, k, e);
+ }
+ }
+ }
+ };
+ this.bindings.push(handler);
+ },
+
+
+ checkModifiers: function(config, e){
+ var val, key, keys = ['shift', 'ctrl', 'alt'];
+ for (var i = 0, len = keys.length; i < len; ++i){
+ key = keys[i];
+ val = config[key];
+ if(!(val === undefined || (val === e[key + 'Key']))){
+ return false;
+ }
+ }
+ return true;
+ },
+
+
+ on : function(key, fn, scope){
+ var keyCode, shift, ctrl, alt;
+ if(typeof key == "object" && !Ext.isArray(key)){
+ keyCode = key.key;
+ shift = key.shift;
+ ctrl = key.ctrl;
+ alt = key.alt;
+ }else{
+ keyCode = key;
+ }
+ this.addBinding({
+ key: keyCode,
+ shift: shift,
+ ctrl: ctrl,
+ alt: alt,
+ fn: fn,
+ scope: scope
+ });
+ },
+
+
+ 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.handleKeyDown, this);
+ this.enabled = true;
+ }
+ },
+
+
+ disable: function(){
+ if(this.enabled){
+ this.el.removeListener(this.eventName, this.handleKeyDown, this);
+ this.enabled = false;
+ }
+ },
+
+
+ setDisabled : function(disabled){
+ this[disabled ? "disable" : "enable"]();
+ }
+};
+Ext.util.TextMetrics = function(){
+ var shared;
+ return {
+
+ measure : function(el, text, fixedWidth){
+ if(!shared){
+ shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
+ }
+ shared.bind(el);
+ shared.setFixedWidth(fixedWidth || 'auto');
+ return shared.getSize(text);
+ },
+
+
+ createInstance : function(el, fixedWidth){
+ return Ext.util.TextMetrics.Instance(el, fixedWidth);
+ }
+ };
+}();
+
+Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
+ var ml = new Ext.Element(document.createElement('div'));
+ document.body.appendChild(ml.dom);
+ ml.position('absolute');
+ ml.setLeftTop(-1000, -1000);
+ ml.hide();
+
+ if(fixedWidth){
+ ml.setWidth(fixedWidth);
+ }
+
+ var instance = {
+
+ getSize : function(text){
+ ml.update(text);
+ 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', 'text-transform', 'letter-spacing')
+ );
+ },
+
+
+ setFixedWidth : function(width){
+ ml.setWidth(width);
+ },
+
+
+ getWidth : function(text){
+ ml.dom.style.width = 'auto';
+ return this.getSize(text).width;
+ },
+
+
+ getHeight : function(text){
+ return this.getSize(text).height;
+ }
+ };
+
+ instance.bind(bindTo);
+
+ return instance;
+};
+
+Ext.Element.addMethods({
+
+ getTextWidth : function(text, min, max){
+ return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
+ }
+});
+
+Ext.util.Cookies = {
+
+ set : function(name, value){
+ var argv = arguments;
+ var argc = arguments.length;
+ var expires = (argc > 2) ? argv[2] : null;
+ var path = (argc > 3) ? argv[3] : '/';
+ var domain = (argc > 4) ? argv[4] : null;
+ var secure = (argc > 5) ? argv[5] : false;
+ document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
+ },
+
+
+ get : function(name){
+ var arg = name + "=";
+ var alen = arg.length;
+ var clen = document.cookie.length;
+ var i = 0;
+ var j = 0;
+ while(i < clen){
+ j = i + alen;
+ if(document.cookie.substring(i, j) == arg){
+ return Ext.util.Cookies.getCookieVal(j);
+ }
+ i = document.cookie.indexOf(" ", i) + 1;
+ if(i === 0){
+ break;
+ }
+ }
+ return null;
+ },
+
+
+ clear : function(name){
+ if(Ext.util.Cookies.get(name)){
+ document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
+ }
+ },
+
+ getCookieVal : function(offset){
+ var endstr = document.cookie.indexOf(";", offset);
+ if(endstr == -1){
+ endstr = document.cookie.length;
+ }
+ return unescape(document.cookie.substring(offset, endstr));
+ }
+};
+Ext.handleError = function(e) {
+ throw e;
+};
+
+
+Ext.Error = function(message) {
+
+ this.message = (this.lang[message]) ? this.lang[message] : message;
+};
+
+Ext.Error.prototype = new Error();
+Ext.apply(Ext.Error.prototype, {
+
+ lang: {},
+
+ name: 'Ext.Error',
+
+ getName : function() {
+ return this.name;
+ },
+
+ getMessage : function() {
+ return this.message;
+ },
+
+ toJson : function() {
+ return Ext.encode(this);
+ }
+});
+
+Ext.ComponentMgr = function(){
+ var all = new Ext.util.MixedCollection();
+ var types = {};
+ var ptypes = {};
+
+ return {
+
+ register : function(c){
+ all.add(c);
+ },
+
+
+ unregister : function(c){
+ all.remove(c);
+ },
+
+
+ get : function(id){
+ return all.get(id);
+ },
+
+
+ onAvailable : function(id, fn, scope){
+ all.on("add", function(index, o){
+ if(o.id == id){
+ fn.call(scope || o, o);
+ all.un("add", fn, scope);
+ }
+ });
+ },
+
+
+ all : all,
+
+
+ types : types,
+
+
+ ptypes: ptypes,
+
+
+ isRegistered : function(xtype){
+ return types[xtype] !== undefined;
+ },
+
+
+ isPluginRegistered : function(ptype){
+ return ptypes[ptype] !== undefined;
+ },
+
+
+ registerType : function(xtype, cls){
+ types[xtype] = cls;
+ cls.xtype = xtype;
+ },
+
+
+ create : function(config, defaultType){
+ return config.render ? config : new types[config.xtype || defaultType](config);
+ },
+
+
+ registerPlugin : function(ptype, cls){
+ ptypes[ptype] = cls;
+ cls.ptype = ptype;
+ },
+
+
+ createPlugin : function(config, defaultType){
+ var PluginCls = ptypes[config.ptype || defaultType];
+ if (PluginCls.init) {
+ return PluginCls;
+ } else {
+ return new PluginCls(config);
+ }
+ }
+ };
+}();
+
+
+Ext.reg = Ext.ComponentMgr.registerType;
+
+Ext.preg = Ext.ComponentMgr.registerPlugin;
+
+Ext.create = Ext.ComponentMgr.create;
+Ext.Component = function(config){
+ config = config || {};
+ if(config.initialConfig){
+ if(config.isAction){
+ this.baseAction = config;
+ }
+ config = config.initialConfig;
+ }else if(config.tagName || config.dom || Ext.isString(config)){
+ config = {applyTo: config, id: config.id || config};
+ }
+
+
+ this.initialConfig = config;
+
+ Ext.apply(this, config);
+ this.addEvents(
+
+ 'added',
+
+ 'disable',
+
+ 'enable',
+
+ 'beforeshow',
+
+ 'show',
+
+ 'beforehide',
+
+ 'hide',
+
+ 'removed',
+
+ 'beforerender',
+
+ 'render',
+
+ 'afterrender',
+
+ 'beforedestroy',
+
+ 'destroy',
+
+ 'beforestaterestore',
+
+ 'staterestore',
+
+ 'beforestatesave',
+
+ 'statesave'
+ );
+ this.getId();
+ Ext.ComponentMgr.register(this);
+ Ext.Component.superclass.constructor.call(this);
+
+ if(this.baseAction){
+ this.baseAction.addComponent(this);
+ }
+
+ this.initComponent();
+
+ if(this.plugins){
+ if(Ext.isArray(this.plugins)){
+ for(var i = 0, len = this.plugins.length; i < len; i++){
+ this.plugins[i] = this.initPlugin(this.plugins[i]);
+ }
+ }else{
+ this.plugins = this.initPlugin(this.plugins);
+ }
+ }
+
+ if(this.stateful !== false){
+ this.initState();
+ }
+
+ if(this.applyTo){
+ this.applyToMarkup(this.applyTo);
+ delete this.applyTo;
+ }else if(this.renderTo){
+ this.render(this.renderTo);
+ delete this.renderTo;
+ }
+};
+
+
+Ext.Component.AUTO_ID = 1000;
+
+Ext.extend(Ext.Component, Ext.util.Observable, {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ disabled : false,
+
+ hidden : false,
+
+
+
+
+
+
+
+ autoEl : 'div',
+
+
+ disabledClass : 'x-item-disabled',
+
+ allowDomMove : true,
+
+ autoShow : false,
+
+ hideMode : 'display',
+
+ hideParent : false,
+
+
+
+
+
+ rendered : false,
+
+
+
+
+
+
+
+ tplWriteMode : 'overwrite',
+
+
+
+
+ bubbleEvents: [],
+
+
+
+ ctype : 'Ext.Component',
+
+
+ actionMode : 'el',
+
+
+ getActionEl : function(){
+ return this[this.actionMode];
+ },
+
+ initPlugin : function(p){
+ if(p.ptype && !Ext.isFunction(p.init)){
+ p = Ext.ComponentMgr.createPlugin(p);
+ }else if(Ext.isString(p)){
+ p = Ext.ComponentMgr.createPlugin({
+ ptype: p
+ });
+ }
+ p.init(this);
+ return p;
+ },
+
+
+ initComponent : function(){
+
+ if(this.listeners){
+ this.on(this.listeners);
+ delete this.listeners;
+ }
+ this.enableBubble(this.bubbleEvents);
+ },
+
+
+ render : function(container, position){
+ if(!this.rendered && this.fireEvent('beforerender', this) !== false){
+ if(!container && this.el){
+ this.el = Ext.get(this.el);
+ container = this.el.dom.parentNode;
+ this.allowDomMove = false;
+ }
+ this.container = Ext.get(container);
+ if(this.ctCls){
+ this.container.addClass(this.ctCls);
+ }
+ this.rendered = true;
+ if(position !== undefined){
+ if(Ext.isNumber(position)){
+ position = this.container.dom.childNodes[position];
+ }else{
+ position = Ext.getDom(position);
+ }
+ }
+ this.onRender(this.container, position || null);
+ if(this.autoShow){
+ this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
+ }
+ if(this.cls){
+ this.el.addClass(this.cls);
+ delete this.cls;
+ }
+ if(this.style){
+ this.el.applyStyles(this.style);
+ delete this.style;
+ }
+ if(this.overCls){
+ this.el.addClassOnOver(this.overCls);
+ }
+ this.fireEvent('render', this);
+
+
+
+
+ var contentTarget = this.getContentTarget();
+ if (this.html){
+ contentTarget.update(Ext.DomHelper.markup(this.html));
+ delete this.html;
+ }
+ if (this.contentEl){
+ var ce = Ext.getDom(this.contentEl);
+ Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
+ contentTarget.appendChild(ce);
+ }
+ if (this.tpl) {
+ if (!this.tpl.compile) {
+ this.tpl = new Ext.XTemplate(this.tpl);
+ }
+ if (this.data) {
+ this.tpl[this.tplWriteMode](contentTarget, this.data);
+ delete this.data;
+ }
+ }
+ this.afterRender(this.container);
+
+
+ if(this.hidden){
+
+ this.doHide();
+ }
+ if(this.disabled){
+
+ this.disable(true);
+ }
+
+ if(this.stateful !== false){
+ this.initStateEvents();
+ }
+ this.fireEvent('afterrender', this);
+ }
+ return this;
+ },
+
+
+
+ update: function(htmlOrData, loadScripts, cb) {
+ var contentTarget = this.getContentTarget();
+ if (this.tpl && typeof htmlOrData !== "string") {
+ this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
+ } else {
+ var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
+ contentTarget.update(html, loadScripts, cb);
+ }
+ },
+
+
+
+ onAdded : function(container, pos) {
+ this.ownerCt = container;
+ this.initRef();
+ this.fireEvent('added', this, container, pos);
+ },
+
+
+ onRemoved : function() {
+ this.removeRef();
+ this.fireEvent('removed', this, this.ownerCt);
+ delete this.ownerCt;
+ },
+
+
+ initRef : function() {
+
+ if(this.ref && !this.refOwner){
+ var levels = this.ref.split('/'),
+ last = levels.length,
+ i = 0,
+ t = this;
+
+ while(t && i < last){
+ t = t.ownerCt;
+ ++i;
+ }
+ if(t){
+ t[this.refName = levels[--i]] = this;
+
+ this.refOwner = t;
+ }
+ }
+ },
+
+ removeRef : function() {
+ if (this.refOwner && this.refName) {
+ delete this.refOwner[this.refName];
+ delete this.refOwner;
+ }
+ },
+
+
+ initState : function(){
+ if(Ext.state.Manager){
+ var id = this.getStateId();
+ if(id){
+ var state = Ext.state.Manager.get(id);
+ if(state){
+ if(this.fireEvent('beforestaterestore', this, state) !== false){
+ this.applyState(Ext.apply({}, state));
+ this.fireEvent('staterestore', this, state);
+ }
+ }
+ }
+ }
+ },
+
+
+ getStateId : function(){
+ return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
+ },
+
+
+ initStateEvents : function(){
+ if(this.stateEvents){
+ for(var i = 0, e; e = this.stateEvents[i]; i++){
+ this.on(e, this.saveState, this, {delay:100});
+ }
+ }
+ },
+
+
+ applyState : function(state){
+ if(state){
+ Ext.apply(this, state);
+ }
+ },
+
+
+ getState : function(){
+ return null;
+ },
+
+
+ saveState : function(){
+ if(Ext.state.Manager && this.stateful !== false){
+ var id = this.getStateId();
+ if(id){
+ var state = this.getState();
+ if(this.fireEvent('beforestatesave', this, state) !== false){
+ Ext.state.Manager.set(id, state);
+ this.fireEvent('statesave', this, state);
+ }
+ }
+ }
+ },
+
+
+ applyToMarkup : function(el){
+ this.allowDomMove = false;
+ this.el = Ext.get(el);
+ this.render(this.el.dom.parentNode);
+ },
+
+
+ addClass : function(cls){
+ if(this.el){
+ this.el.addClass(cls);
+ }else{
+ this.cls = this.cls ? this.cls + ' ' + cls : cls;
+ }
+ return this;
+ },
+
+
+ removeClass : function(cls){
+ if(this.el){
+ this.el.removeClass(cls);
+ }else if(this.cls){
+ this.cls = this.cls.split(' ').remove(cls).join(' ');
+ }
+ return this;
+ },
+
+
+
+ onRender : function(ct, position){
+ if(!this.el && this.autoEl){
+ if(Ext.isString(this.autoEl)){
+ this.el = document.createElement(this.autoEl);
+ }else{
+ var div = document.createElement('div');
+ Ext.DomHelper.overwrite(div, this.autoEl);
+ this.el = div.firstChild;
+ }
+ if (!this.el.id) {
+ this.el.id = this.getId();
+ }
+ }
+ if(this.el){
+ this.el = Ext.get(this.el);
+ if(this.allowDomMove !== false){
+ ct.dom.insertBefore(this.el.dom, position);
+ if (div) {
+ Ext.removeNode(div);
+ div = null;
+ }
+ }
+ }
+ },
+
+
+ getAutoCreate : function(){
+ var cfg = Ext.isObject(this.autoCreate) ?
+ this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
+ if(this.id && !cfg.id){
+ cfg.id = this.id;
+ }
+ return cfg;
+ },
+
+
+ afterRender : Ext.emptyFn,
+
+
+ destroy : function(){
+ if(!this.isDestroyed){
+ if(this.fireEvent('beforedestroy', this) !== false){
+ this.destroying = true;
+ this.beforeDestroy();
+ if(this.ownerCt && this.ownerCt.remove){
+ this.ownerCt.remove(this, false);
+ }
+ if(this.rendered){
+ this.el.remove();
+ if(this.actionMode == 'container' || this.removeMode == 'container'){
+ this.container.remove();
+ }
+ }
+
+ if(this.focusTask && this.focusTask.cancel){
+ this.focusTask.cancel();
+ }
+ this.onDestroy();
+ Ext.ComponentMgr.unregister(this);
+ this.fireEvent('destroy', this);
+ this.purgeListeners();
+ this.destroying = false;
+ this.isDestroyed = true;
+ }
+ }
+ },
+
+ deleteMembers : function(){
+ var args = arguments;
+ for(var i = 0, len = args.length; i < len; ++i){
+ delete this[args[i]];
+ }
+ },
+
+
+ beforeDestroy : Ext.emptyFn,
+
+
+ onDestroy : Ext.emptyFn,
+
+
+ getEl : function(){
+ return this.el;
+ },
+
+
+ getContentTarget : function(){
+ return this.el;
+ },
+
+
+ getId : function(){
+ return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
+ },
+
+
+ getItemId : function(){
+ return this.itemId || this.getId();
+ },
+
+
+ focus : function(selectText, delay){
+ if(delay){
+ this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
+ this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
+ return this;
+ }
+ if(this.rendered && !this.isDestroyed){
+ this.el.focus();
+ if(selectText === true){
+ this.el.dom.select();
+ }
+ }
+ return this;
+ },
+
+
+ blur : function(){
+ if(this.rendered){
+ this.el.blur();
+ }
+ return this;
+ },
+
+
+ disable : function( silent){
+ if(this.rendered){
+ this.onDisable();
+ }
+ this.disabled = true;
+ if(silent !== true){
+ this.fireEvent('disable', this);
+ }
+ return this;
+ },
+
+
+ onDisable : function(){
+ this.getActionEl().addClass(this.disabledClass);
+ this.el.dom.disabled = true;
+ },
+
+
+ enable : function(){
+ if(this.rendered){
+ this.onEnable();
+ }
+ this.disabled = false;
+ this.fireEvent('enable', this);
+ return this;
+ },
+
+
+ onEnable : function(){
+ this.getActionEl().removeClass(this.disabledClass);
+ this.el.dom.disabled = false;
+ },
+
+
+ setDisabled : function(disabled){
+ return this[disabled ? 'disable' : 'enable']();
+ },
+
+
+ show : function(){
+ if(this.fireEvent('beforeshow', this) !== false){
+ this.hidden = false;
+ if(this.autoRender){
+ this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
+ }
+ if(this.rendered){
+ this.onShow();
+ }
+ this.fireEvent('show', this);
+ }
+ return this;
+ },
+
+
+ onShow : function(){
+ this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
+ },
+
+
+ hide : function(){
+ if(this.fireEvent('beforehide', this) !== false){
+ this.doHide();
+ this.fireEvent('hide', this);
+ }
+ return this;
+ },
+
+
+ doHide: function(){
+ this.hidden = true;
+ if(this.rendered){
+ this.onHide();
+ }
+ },
+
+
+ onHide : function(){
+ this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
+ },
+
+
+ getVisibilityEl : function(){
+ return this.hideParent ? this.container : this.getActionEl();
+ },
+
+
+ setVisible : function(visible){
+ return this[visible ? 'show' : 'hide']();
+ },
+
+
+ isVisible : function(){
+ return this.rendered && this.getVisibilityEl().isVisible();
+ },
+
+
+ cloneConfig : function(overrides){
+ overrides = overrides || {};
+ var id = overrides.id || Ext.id();
+ var cfg = Ext.applyIf(overrides, this.initialConfig);
+ cfg.id = id;
+ return new this.constructor(cfg);
+ },
+
+
+ getXType : function(){
+ return this.constructor.xtype;
+ },
+
+
+ isXType : function(xtype, shallow){
+
+ if (Ext.isFunction(xtype)){
+ xtype = xtype.xtype;
+ }else if (Ext.isObject(xtype)){
+ xtype = xtype.constructor.xtype;
+ }
+
+ return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
+ },
+
+
+ getXTypes : function(){
+ var tc = this.constructor;
+ if(!tc.xtypes){
+ var c = [], sc = this;
+ while(sc && sc.constructor.xtype){
+ c.unshift(sc.constructor.xtype);
+ sc = sc.constructor.superclass;
+ }
+ tc.xtypeChain = c;
+ tc.xtypes = c.join('/');
+ }
+ return tc.xtypes;
+ },
+
+
+ findParentBy : function(fn) {
+ for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
+ return p || null;
+ },
+
+
+ findParentByType : function(xtype, shallow){
+ return this.findParentBy(function(c){
+ return c.isXType(xtype, shallow);
+ });
+ },
+
+
+ bubble : function(fn, scope, args){
+ var p = this;
+ while(p){
+ if(fn.apply(scope || p, args || [p]) === false){
+ break;
+ }
+ p = p.ownerCt;
+ }
+ return this;
+ },
+
+
+ getPositionEl : function(){
+ return this.positionEl || this.el;
+ },
+
+
+ purgeListeners : function(){
+ Ext.Component.superclass.purgeListeners.call(this);
+ if(this.mons){
+ this.on('beforedestroy', this.clearMons, this, {single: true});
+ }
+ },
+
+
+ clearMons : function(){
+ Ext.each(this.mons, function(m){
+ m.item.un(m.ename, m.fn, m.scope);
+ }, this);
+ this.mons = [];
+ },
+
+
+ createMons: function(){
+ if(!this.mons){
+ this.mons = [];
+ this.on('beforedestroy', this.clearMons, this, {single: true});
+ }
+ },
+
+
+ mon : function(item, ename, fn, scope, opt){
+ this.createMons();
+ if(Ext.isObject(ename)){
+ var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
+
+ var o = ename;
+ for(var e in o){
+ if(propRe.test(e)){
+ continue;
+ }
+ if(Ext.isFunction(o[e])){
+
+ this.mons.push({
+ item: item, ename: e, fn: o[e], scope: o.scope
+ });
+ item.on(e, o[e], o.scope, o);
+ }else{
+
+ this.mons.push({
+ item: item, ename: e, fn: o[e], scope: o.scope
+ });
+ item.on(e, o[e]);
+ }
+ }
+ return;
+ }
+
+ this.mons.push({
+ item: item, ename: ename, fn: fn, scope: scope
+ });
+ item.on(ename, fn, scope, opt);
+ },
+
+
+ mun : function(item, ename, fn, scope){
+ var found, mon;
+ this.createMons();
+ for(var i = 0, len = this.mons.length; i < len; ++i){
+ mon = this.mons[i];
+ if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
+ this.mons.splice(i, 1);
+ item.un(ename, fn, scope);
+ found = true;
+ break;
+ }
+ }
+ return found;
+ },
+
+
+ nextSibling : function(){
+ if(this.ownerCt){
+ var index = this.ownerCt.items.indexOf(this);
+ if(index != -1 && index+1 < this.ownerCt.items.getCount()){
+ return this.ownerCt.items.itemAt(index+1);
+ }
+ }
+ return null;
+ },
+
+
+ previousSibling : function(){
+ if(this.ownerCt){
+ var index = this.ownerCt.items.indexOf(this);
+ if(index > 0){
+ return this.ownerCt.items.itemAt(index-1);
+ }
+ }
+ return null;
+ },
+
+
+ getBubbleTarget : function(){
+ return this.ownerCt;
+ }
+});
+
+Ext.reg('component', Ext.Component);
+
+Ext.Action = Ext.extend(Object, {
+
+
+
+
+
+
+
+
+ constructor : function(config){
+ this.initialConfig = config;
+ this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
+ this.items = [];
+ },
+
+
+ isAction : true,
+
+
+ setText : function(text){
+ this.initialConfig.text = text;
+ this.callEach('setText', [text]);
+ },
+
+
+ getText : function(){
+ return this.initialConfig.text;
+ },
+
+
+ setIconClass : function(cls){
+ this.initialConfig.iconCls = cls;
+ this.callEach('setIconClass', [cls]);
+ },
+
+
+ getIconClass : function(){
+ return this.initialConfig.iconCls;
+ },
+
+
+ setDisabled : function(v){
+ this.initialConfig.disabled = v;
+ this.callEach('setDisabled', [v]);
+ },
+
+
+ enable : function(){
+ this.setDisabled(false);
+ },
+
+
+ disable : function(){
+ this.setDisabled(true);
+ },
+
+
+ isDisabled : function(){
+ return this.initialConfig.disabled;
+ },
+
+
+ setHidden : function(v){
+ this.initialConfig.hidden = v;
+ this.callEach('setVisible', [!v]);
+ },
+
+
+ show : function(){
+ this.setHidden(false);
+ },
+
+
+ hide : function(){
+ this.setHidden(true);
+ },
+
+
+ isHidden : function(){
+ return this.initialConfig.hidden;
+ },
+
+
+ setHandler : function(fn, scope){
+ this.initialConfig.handler = fn;
+ this.initialConfig.scope = scope;
+ this.callEach('setHandler', [fn, scope]);
+ },
+
+
+ each : function(fn, scope){
+ Ext.each(this.items, fn, scope);
+ },
+
+
+ callEach : function(fnName, args){
+ var cs = this.items;
+ for(var i = 0, len = cs.length; i < len; i++){
+ cs[i][fnName].apply(cs[i], args);
+ }
+ },
+
+
+ addComponent : function(comp){
+ this.items.push(comp);
+ comp.on('destroy', this.removeComponent, this);
+ },
+
+
+ removeComponent : function(comp){
+ this.items.remove(comp);
+ },
+
+
+ execute : function(){
+ this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
+ }
+});
+
+(function(){
+Ext.Layer = function(config, existingEl){
+ config = config || {};
+ var dh = Ext.DomHelper,
+ cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
+
+ if (existingEl) {
+ this.dom = Ext.getDom(existingEl);
+ }
+ if(!this.dom){
+ var o = config.dh || {tag: 'div', cls: 'x-layer'};
+ this.dom = dh.append(pel, o);
+ }
+ if(config.cls){
+ this.addClass(config.cls);
+ }
+ this.constrain = config.constrain !== false;
+ this.setVisibilityMode(Ext.Element.VISIBILITY);
+ if(config.id){
+ this.id = this.dom.id = config.id;
+ }else{
+ this.id = Ext.id(this.dom);
+ }
+ this.zindex = config.zindex || this.getZIndex();
+ this.position('absolute', this.zindex);
+ if(config.shadow){
+ this.shadowOffset = config.shadowOffset || 4;
+ this.shadow = new Ext.Shadow({
+ offset : this.shadowOffset,
+ mode : config.shadow
+ });
+ }else{
+ this.shadowOffset = 0;
+ }
+ this.useShim = config.shim !== false && Ext.useShims;
+ this.useDisplay = config.useDisplay;
+ this.hide();
+};
+
+var supr = Ext.Element.prototype;
+
+
+var shims = [];
+
+Ext.extend(Ext.Layer, Ext.Element, {
+
+ getZIndex : function(){
+ return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
+ },
+
+ getShim : function(){
+ if(!this.useShim){
+ return null;
+ }
+ if(this.shim){
+ return this.shim;
+ }
+ var shim = shims.shift();
+ if(!shim){
+ shim = this.createShim();
+ shim.enableDisplayMode('block');
+ shim.dom.style.display = 'none';
+ shim.dom.style.visibility = 'visible';
+ }
+ var pn = this.dom.parentNode;
+ if(shim.dom.parentNode != pn){
+ pn.insertBefore(shim.dom, this.dom);
+ }
+ shim.setStyle('z-index', this.getZIndex()-2);
+ this.shim = shim;
+ return shim;
+ },
+
+ hideShim : function(){
+ if(this.shim){
+ this.shim.setDisplayed(false);
+ shims.push(this.shim);
+ delete this.shim;
+ }
+ },
+
+ disableShadow : function(){
+ if(this.shadow){
+ this.shadowDisabled = true;
+ this.shadow.hide();
+ this.lastShadowOffset = this.shadowOffset;
+ this.shadowOffset = 0;
+ }
+ },
+
+ enableShadow : function(show){
+ if(this.shadow){
+ this.shadowDisabled = false;
+ if(Ext.isDefined(this.lastShadowOffset)) {
+ this.shadowOffset = this.lastShadowOffset;
+ delete this.lastShadowOffset;
+ }
+ if(show){
+ this.sync(true);
+ }
+ }
+ },
+
+
+
+
+ sync : function(doShow){
+ var shadow = this.shadow;
+ if(!this.updating && this.isVisible() && (shadow || this.useShim)){
+ var shim = this.getShim(),
+ w = this.getWidth(),
+ h = this.getHeight(),
+ l = this.getLeft(true),
+ t = this.getTop(true);
+
+ if(shadow && !this.shadowDisabled){
+ if(doShow && !shadow.isVisible()){
+ shadow.show(this);
+ }else{
+ shadow.realign(l, t, w, h);
+ }
+ if(shim){
+ if(doShow){
+ shim.show();
+ }
+
+ var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
+ shadowSize = shadow.el.getSize();
+ shimStyle.left = (shadowAdj[0])+'px';
+ shimStyle.top = (shadowAdj[1])+'px';
+ shimStyle.width = (shadowSize.width)+'px';
+ shimStyle.height = (shadowSize.height)+'px';
+ }
+ }else if(shim){
+ if(doShow){
+ shim.show();
+ }
+ shim.setSize(w, h);
+ shim.setLeftTop(l, t);
+ }
+ }
+ },
+
+
+ destroy : function(){
+ this.hideShim();
+ if(this.shadow){
+ this.shadow.hide();
+ }
+ this.removeAllListeners();
+ Ext.removeNode(this.dom);
+ delete this.dom;
+ },
+
+ remove : function(){
+ this.destroy();
+ },
+
+
+ beginUpdate : function(){
+ this.updating = true;
+ },
+
+
+ endUpdate : function(){
+ this.updating = false;
+ this.sync(true);
+ },
+
+
+ hideUnders : function(negOffset){
+ if(this.shadow){
+ this.shadow.hide();
+ }
+ this.hideShim();
+ },
+
+
+ constrainXY : function(){
+ if(this.constrain){
+ var vw = Ext.lib.Dom.getViewWidth(),
+ vh = Ext.lib.Dom.getViewHeight();
+ var s = Ext.getDoc().getScroll();
+
+ var xy = this.getXY();
+ var x = xy[0], y = xy[1];
+ var so = this.shadowOffset;
+ var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
+
+ var moved = false;
+
+ if((x + w) > vw+s.left){
+ x = vw - w - so;
+ moved = true;
+ }
+ if((y + h) > vh+s.top){
+ y = vh - h - so;
+ moved = true;
+ }
+
+ if(x < s.left){
+ x = s.left;
+ moved = true;
+ }
+ if(y < s.top){
+ y = s.top;
+ moved = true;
+ }
+ if(moved){
+ if(this.avoidY){
+ var ay = this.avoidY;
+ if(y <= ay && (y+h) >= ay){
+ y = ay-h-5;
+ }
+ }
+ xy = [x, y];
+ this.storeXY(xy);
+ supr.setXY.call(this, xy);
+ this.sync();
+ }
+ }
+ return this;
+ },
+
+ getConstrainOffset : function(){
+ return this.shadowOffset;
+ },
+
+ isVisible : function(){
+ return this.visible;
+ },
+
+
+ showAction : function(){
+ this.visible = true;
+ if(this.useDisplay === true){
+ this.setDisplayed('');
+ }else if(this.lastXY){
+ supr.setXY.call(this, this.lastXY);
+ }else if(this.lastLT){
+ supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
+ }
+ },
+
+
+ hideAction : function(){
+ this.visible = false;
+ if(this.useDisplay === true){
+ this.setDisplayed(false);
+ }else{
+ this.setLeftTop(-10000,-10000);
+ }
+ },
+
+
+ setVisible : function(v, a, d, c, e){
+ if(v){
+ this.showAction();
+ }
+ if(a && v){
+ var cb = function(){
+ this.sync(true);
+ if(c){
+ c();
+ }
+ }.createDelegate(this);
+ supr.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);
+ }
+ supr.setVisible.call(this, v, a, d, cb, e);
+ if(v){
+ this.sync(true);
+ }else if(!a){
+ this.hideAction();
+ }
+ }
+ return this;
+ },
+
+ storeXY : function(xy){
+ delete this.lastLT;
+ this.lastXY = xy;
+ },
+
+ storeLeftTop : function(left, top){
+ delete this.lastXY;
+ this.lastLT = [left, top];
+ },
+
+
+ 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();
+ }
+ },
+
+
+ setLeft : function(left){
+ this.storeLeftTop(left, this.getTop(true));
+ supr.setLeft.apply(this, arguments);
+ this.sync();
+ return this;
+ },
+
+ setTop : function(top){
+ this.storeLeftTop(this.getLeft(true), top);
+ supr.setTop.apply(this, arguments);
+ this.sync();
+ return this;
+ },
+
+ setLeftTop : function(left, top){
+ this.storeLeftTop(left, top);
+ supr.setLeftTop.apply(this, arguments);
+ this.sync();
+ return this;
+ },
+
+ setXY : function(xy, a, d, c, e){
+ this.fixDisplay();
+ this.beforeAction();
+ this.storeXY(xy);
+ var cb = this.createCB(c);
+ supr.setXY.call(this, xy, a, d, cb, e);
+ if(!a){
+ cb();
+ }
+ return this;
+ },
+
+
+ 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);
+ return this;
+ },
+
+
+ setY : function(y, a, d, c, e){
+ this.setXY([this.getX(), y], a, d, c, e);
+ return this;
+ },
+
+
+ setSize : function(w, h, a, d, c, e){
+ this.beforeAction();
+ var cb = this.createCB(c);
+ supr.setSize.call(this, w, h, a, d, cb, e);
+ if(!a){
+ cb();
+ }
+ return this;
+ },
+
+
+ setWidth : function(w, a, d, c, e){
+ this.beforeAction();
+ var cb = this.createCB(c);
+ supr.setWidth.call(this, w, a, d, cb, e);
+ if(!a){
+ cb();
+ }
+ return this;
+ },
+
+
+ setHeight : function(h, a, d, c, e){
+ this.beforeAction();
+ var cb = this.createCB(c);
+ supr.setHeight.call(this, h, a, d, cb, e);
+ if(!a){
+ cb();
+ }
+ return this;
+ },
+
+
+ setBounds : function(x, y, w, h, a, d, c, e){
+ this.beforeAction();
+ var cb = this.createCB(c);
+ if(!a){
+ this.storeXY([x, y]);
+ supr.setXY.call(this, [x, y]);
+ supr.setSize.call(this, w, h, a, d, cb, e);
+ cb();
+ }else{
+ supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
+ }
+ return this;
+ },
+
+
+ setZIndex : function(zindex){
+ this.zindex = zindex;
+ this.setStyle('z-index', zindex + 2);
+ if(this.shadow){
+ this.shadow.setZIndex(zindex + 1);
+ }
+ if(this.shim){
+ this.shim.setStyle('z-index', zindex);
+ }
+ return this;
+ }
+});
+})();
+
+Ext.Shadow = function(config) {
+ Ext.apply(this, config);
+ if (typeof this.mode != "string") {
+ this.mode = this.defaultMode;
+ }
+ var o = this.offset,
+ a = {
+ h: 0
+ },
+ rad = Math.floor(this.offset / 2);
+ switch (this.mode.toLowerCase()) {
+
+ case "drop":
+ a.w = 0;
+ a.l = a.t = o;
+ a.t -= 1;
+ if (Ext.isIE9m) {
+ a.l -= this.offset + rad;
+ a.t -= this.offset + rad;
+ a.w -= rad;
+ a.h -= rad;
+ a.t += 1;
+ }
+ break;
+ case "sides":
+ a.w = (o * 2);
+ a.l = -o;
+ a.t = o - 1;
+ if (Ext.isIE9m) {
+ a.l -= (this.offset - rad);
+ a.t -= this.offset + rad;
+ a.l += 1;
+ a.w -= (this.offset - rad) * 2;
+ a.w -= rad + 1;
+ a.h -= 1;
+ }
+ break;
+ case "frame":
+ a.w = a.h = (o * 2);
+ a.l = a.t = -o;
+ a.t += 1;
+ a.h -= 2;
+ if (Ext.isIE9m) {
+ a.l -= (this.offset - rad);
+ a.t -= (this.offset - rad);
+ a.l += 1;
+ a.w -= (this.offset + rad + 1);
+ a.h -= (this.offset + rad);
+ a.h += 1;
+ }
+ break;
+ };
+
+ this.adjusts = a;
+};
+
+Ext.Shadow.prototype = {
+
+
+ offset: 4,
+
+
+ defaultMode: "drop",
+
+
+ show: function(target) {
+ target = Ext.get(target);
+ if (!this.el) {
+ this.el = Ext.Shadow.Pool.pull();
+ if (this.el.dom.nextSibling != target.dom) {
+ this.el.insertBefore(target);
+ }
+ }
+ this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
+ if (Ext.isIE9m) {
+ this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
+ }
+ this.realign(
+ target.getLeft(true),
+ target.getTop(true),
+ target.getWidth(),
+ target.getHeight()
+ );
+ this.el.dom.style.display = "block";
+ },
+
+
+ isVisible: function() {
+ return this.el ? true: false;
+ },
+
+
+ realign: function(l, t, w, h) {
+ if (!this.el) {
+ return;
+ }
+ var a = this.adjusts,
+ d = this.el.dom,
+ s = d.style,
+ iea = 0,
+ sw = (w + a.w),
+ sh = (h + a.h),
+ sws = sw + "px",
+ shs = sh + "px",
+ cn,
+ sww;
+ s.left = (l + a.l) + "px";
+ s.top = (t + a.t) + "px";
+ if (s.width != sws || s.height != shs) {
+ s.width = sws;
+ s.height = shs;
+ if (!Ext.isIE9m) {
+ cn = d.childNodes;
+ 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 = [],
+ markup = Ext.isIE9m ?
+ '<div class="x-ie-shadow"></div>':
+ '<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, markup));
+ sh.autoBoxAdjust = false;
+ }
+ return sh;
+ },
+
+ push: function(sh) {
+ p.push(sh);
+ }
+ };
+}();
+Ext.BoxComponent = Ext.extend(Ext.Component, {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ initComponent : function(){
+ Ext.BoxComponent.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'resize',
+
+ 'move'
+ );
+ },
+
+
+ boxReady : false,
+
+ deferHeight: false,
+
+
+ setSize : function(w, h){
+
+
+ if(typeof w == 'object'){
+ h = w.height;
+ w = w.width;
+ }
+ if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
+ w = this.boxMinWidth;
+ }
+ if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
+ h = this.boxMinHeight;
+ }
+ if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
+ w = this.boxMaxWidth;
+ }
+ if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
+ h = this.boxMaxHeight;
+ }
+
+ if(!this.boxReady){
+ this.width = w;
+ this.height = h;
+ return this;
+ }
+
+
+ if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
+ return this;
+ }
+ this.lastSize = {width: w, height: h};
+ var adj = this.adjustSize(w, h),
+ aw = adj.width,
+ ah = adj.height,
+ rz;
+ if(aw !== undefined || ah !== undefined){
+ rz = this.getResizeEl();
+ if(!this.deferHeight && aw !== undefined && ah !== undefined){
+ rz.setSize(aw, ah);
+ }else if(!this.deferHeight && ah !== undefined){
+ rz.setHeight(ah);
+ }else if(aw !== undefined){
+ rz.setWidth(aw);
+ }
+ this.onResize(aw, ah, w, h);
+ this.fireEvent('resize', this, aw, ah, w, h);
+ }
+ return this;
+ },
+
+
+ setWidth : function(width){
+ return this.setSize(width);
+ },
+
+
+ setHeight : function(height){
+ return this.setSize(undefined, height);
+ },
+
+
+ getSize : function(){
+ return this.getResizeEl().getSize();
+ },
+
+
+ getWidth : function(){
+ return this.getResizeEl().getWidth();
+ },
+
+
+ getHeight : function(){
+ return this.getResizeEl().getHeight();
+ },
+
+
+ getOuterSize : function(){
+ var el = this.getResizeEl();
+ return {width: el.getWidth() + el.getMargins('lr'),
+ height: el.getHeight() + el.getMargins('tb')};
+ },
+
+
+ getPosition : function(local){
+ var el = this.getPositionEl();
+ if(local === true){
+ return [el.getLeft(true), el.getTop(true)];
+ }
+ return this.xy || el.getXY();
+ },
+
+
+ getBox : function(local){
+ var pos = this.getPosition(local);
+ var s = this.getSize();
+ s.x = pos[0];
+ s.y = pos[1];
+ return s;
+ },
+
+
+ updateBox : function(box){
+ this.setSize(box.width, box.height);
+ this.setPagePosition(box.x, box.y);
+ return this;
+ },
+
+
+ getResizeEl : function(){
+ return this.resizeEl || this.el;
+ },
+
+
+ setAutoScroll : function(scroll){
+ if(this.rendered){
+ this.getContentTarget().setOverflow(scroll ? 'auto' : '');
+ }
+ this.autoScroll = scroll;
+ return this;
+ },
+
+
+ setPosition : function(x, y){
+ if(x && typeof x[1] == 'number'){
+ y = x[1];
+ x = x[0];
+ }
+ this.x = x;
+ this.y = y;
+ if(!this.boxReady){
+ return this;
+ }
+ var adj = this.adjustPosition(x, y);
+ var ax = adj.x, ay = adj.y;
+
+ var el = this.getPositionEl();
+ if(ax !== undefined || ay !== undefined){
+ if(ax !== undefined && ay !== undefined){
+ el.setLeftTop(ax, ay);
+ }else if(ax !== undefined){
+ el.setLeft(ax);
+ }else if(ay !== undefined){
+ el.setTop(ay);
+ }
+ this.onPosition(ax, ay);
+ this.fireEvent('move', this, ax, ay);
+ }
+ return this;
+ },
+
+
+ setPagePosition : function(x, y){
+ if(x && typeof x[1] == 'number'){
+ y = x[1];
+ x = x[0];
+ }
+ this.pageX = x;
+ this.pageY = y;
+ if(!this.boxReady){
+ return;
+ }
+ if(x === undefined || y === undefined){
+ return;
+ }
+ var p = this.getPositionEl().translatePoints(x, y);
+ this.setPosition(p.left, p.top);
+ return this;
+ },
+
+
+ afterRender : function(){
+ Ext.BoxComponent.superclass.afterRender.call(this);
+ if(this.resizeEl){
+ this.resizeEl = Ext.get(this.resizeEl);
+ }
+ if(this.positionEl){
+ this.positionEl = Ext.get(this.positionEl);
+ }
+ this.boxReady = true;
+ Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
+ this.setSize(this.width, this.height);
+ if(this.x || this.y){
+ this.setPosition(this.x, this.y);
+ }else if(this.pageX || this.pageY){
+ this.setPagePosition(this.pageX, this.pageY);
+ }
+ },
+
+
+ syncSize : function(){
+ delete this.lastSize;
+ this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
+ return this;
+ },
+
+
+ onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
+ },
+
+
+ onPosition : function(x, y){
+
+ },
+
+
+ adjustSize : function(w, h){
+ if(this.autoWidth){
+ w = 'auto';
+ }
+ if(this.autoHeight){
+ h = 'auto';
+ }
+ return {width : w, height: h};
+ },
+
+
+ adjustPosition : function(x, y){
+ return {x : x, y: y};
+ }
+});
+Ext.reg('box', Ext.BoxComponent);
+
+
+
+Ext.Spacer = Ext.extend(Ext.BoxComponent, {
+ autoEl:'div'
+});
+Ext.reg('spacer', Ext.Spacer);
+Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
+
+
+ this.el = Ext.get(dragElement, true);
+ this.el.unselectable();
+
+ this.resizingEl = Ext.get(resizingElement, true);
+
+
+ this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
+
+
+
+ this.minSize = 0;
+
+
+ this.maxSize = 2000;
+
+
+ this.animate = false;
+
+
+ this.useShim = false;
+
+
+ this.shim = null;
+
+ if(!existingProxy){
+
+ this.proxy = Ext.SplitBar.createProxy(this.orientation);
+ }else{
+ this.proxy = Ext.get(existingProxy).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 = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
+ this.el.addClass("x-splitbar-h");
+ }else{
+
+ this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
+ this.el.addClass("x-splitbar-v");
+ }
+
+ this.addEvents(
+
+ "resize",
+
+ "moved",
+
+ "beforeresize",
+
+ "beforeapply"
+ );
+
+ Ext.SplitBar.superclass.constructor.call(this);
+};
+
+Ext.extend(Ext.SplitBar, Ext.util.Observable, {
+ onStartProxyDrag : function(x, y){
+ this.fireEvent("beforeresize", this);
+ this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: "&#160;"}, true);
+ this.overlay.unselectable();
+ this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
+ this.overlay.show();
+ Ext.get(this.proxy).setDisplayed("block");
+ var size = this.adapter.getElementSize(this);
+ this.activeMinSize = this.getMinimumSize();
+ this.activeMaxSize = this.getMaximumSize();
+ var c1 = size - this.activeMinSize;
+ var c2 = Math.max(this.activeMaxSize - size, 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.tickSize
+ );
+ 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.tickSize
+ );
+ }
+ this.dragSpecs.startSize = size;
+ 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 endPoint = Ext.lib.Event.getXY(e);
+ if(this.overlay){
+ Ext.destroy(this.overlay);
+ delete this.overlay;
+ }
+ var newSize;
+ if(this.orientation == Ext.SplitBar.HORIZONTAL){
+ newSize = this.dragSpecs.startSize +
+ (this.placement == Ext.SplitBar.LEFT ?
+ endPoint[0] - this.dragSpecs.startPoint[0] :
+ this.dragSpecs.startPoint[0] - endPoint[0]
+ );
+ }else{
+ newSize = this.dragSpecs.startSize +
+ (this.placement == Ext.SplitBar.TOP ?
+ endPoint[1] - this.dragSpecs.startPoint[1] :
+ this.dragSpecs.startPoint[1] - endPoint[1]
+ );
+ }
+ newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
+ if(newSize != this.dragSpecs.startSize){
+ if(this.fireEvent('beforeapply', this, newSize) !== false){
+ this.adapter.setElementSize(this, newSize);
+ this.fireEvent("moved", this, newSize);
+ this.fireEvent("resize", this, newSize);
+ }
+ }
+ },
+
+
+ getAdapter : function(){
+ return this.adapter;
+ },
+
+
+ setAdapter : function(adapter){
+ this.adapter = adapter;
+ this.adapter.init(this);
+ },
+
+
+ getMinimumSize : function(){
+ return this.minSize;
+ },
+
+
+ setMinimumSize : function(minSize){
+ this.minSize = minSize;
+ },
+
+
+ getMaximumSize : function(){
+ return this.maxSize;
+ },
+
+
+ setMaximumSize : function(maxSize){
+ this.maxSize = maxSize;
+ },
+
+
+ setCurrentSize : function(size){
+ var oldAnimate = this.animate;
+ this.animate = false;
+ this.adapter.setElementSize(this, size);
+ this.animate = oldAnimate;
+ },
+
+
+ destroy : function(removeEl){
+ Ext.destroy(this.shim, Ext.get(this.proxy));
+ this.dd.unreg();
+ if(removeEl){
+ this.el.remove();
+ }
+ this.purgeListeners();
+ }
+});
+
+
+Ext.SplitBar.createProxy = function(dir){
+ var proxy = new Ext.Element(document.createElement("div"));
+ document.body.appendChild(proxy.dom);
+ proxy.unselectable();
+ var cls = 'x-splitbar-proxy';
+ proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
+ return proxy.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, newSize, onComplete){
+ if(s.orientation == Ext.SplitBar.HORIZONTAL){
+ if(!s.animate){
+ s.resizingEl.setWidth(newSize);
+ if(onComplete){
+ onComplete(s, newSize);
+ }
+ }else{
+ s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
+ }
+ }else{
+
+ if(!s.animate){
+ s.resizingEl.setHeight(newSize);
+ if(onComplete){
+ onComplete(s, newSize);
+ }
+ }else{
+ s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
+ }
+ }
+ }
+};
+
+
+Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
+ this.basic = new Ext.SplitBar.BasicLayoutAdapter();
+ this.container = Ext.get(container);
+};
+
+Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
+ init : function(s){
+ this.basic.init(s);
+ },
+
+ getElementSize : function(s){
+ return this.basic.getElementSize(s);
+ },
+
+ setElementSize : function(s, newSize, onComplete){
+ this.basic.setElementSize(s, newSize, 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.Container = Ext.extend(Ext.BoxComponent, {
+
+
+
+
+ bufferResize: 50,
+
+
+
+
+
+
+
+ autoDestroy : true,
+
+
+ forceLayout: false,
+
+
+
+ defaultType : 'panel',
+
+
+ resizeEvent: 'resize',
+
+
+ bubbleEvents: ['add', 'remove'],
+
+
+ initComponent : function(){
+ Ext.Container.superclass.initComponent.call(this);
+
+ this.addEvents(
+
+ 'afterlayout',
+
+ 'beforeadd',
+
+ 'beforeremove',
+
+ 'add',
+
+ 'remove'
+ );
+
+
+ var items = this.items;
+ if(items){
+ delete this.items;
+ this.add(items);
+ }
+ },
+
+
+ initItems : function(){
+ if(!this.items){
+ this.items = new Ext.util.MixedCollection(false, this.getComponentId);
+ this.getLayout();
+ }
+ },
+
+
+ setLayout : function(layout){
+ if(this.layout && this.layout != layout){
+ this.layout.setContainer(null);
+ }
+ this.layout = layout;
+ this.initItems();
+ layout.setContainer(this);
+ },
+
+ afterRender: function(){
+
+
+ Ext.Container.superclass.afterRender.call(this);
+ if(!this.layout){
+ this.layout = 'auto';
+ }
+ if(Ext.isObject(this.layout) && !this.layout.layout){
+ this.layoutConfig = this.layout;
+ this.layout = this.layoutConfig.type;
+ }
+ if(Ext.isString(this.layout)){
+ this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
+ }
+ this.setLayout(this.layout);
+
+
+ if(this.activeItem !== undefined && this.layout.setActiveItem){
+ var item = this.activeItem;
+ delete this.activeItem;
+ this.layout.setActiveItem(item);
+ }
+
+
+ if(!this.ownerCt){
+ this.doLayout(false, true);
+ }
+
+
+
+ if(this.monitorResize === true){
+ Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
+ }
+ },
+
+
+ getLayoutTarget : function(){
+ return this.el;
+ },
+
+
+ getComponentId : function(comp){
+ return comp.getItemId();
+ },
+
+
+ add : function(comp){
+ this.initItems();
+ var args = arguments.length > 1;
+ if(args || Ext.isArray(comp)){
+ var result = [];
+ Ext.each(args ? arguments : comp, function(c){
+ result.push(this.add(c));
+ }, this);
+ return result;
+ }
+ var c = this.lookupComponent(this.applyDefaults(comp));
+ var index = this.items.length;
+ if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
+ this.items.add(c);
+
+ c.onAdded(this, index);
+ this.onAdd(c);
+ this.fireEvent('add', this, c, index);
+ }
+ return c;
+ },
+
+ onAdd : function(c){
+
+ },
+
+
+ onAdded : function(container, pos) {
+
+ this.ownerCt = container;
+ this.initRef();
+
+ this.cascade(function(c){
+ c.initRef();
+ });
+ this.fireEvent('added', this, container, pos);
+ },
+
+
+ insert : function(index, comp) {
+ var args = arguments,
+ length = args.length,
+ result = [],
+ i, c;
+
+ this.initItems();
+
+ if (length > 2) {
+ for (i = length - 1; i >= 1; --i) {
+ result.push(this.insert(index, args[i]));
+ }
+ return result;
+ }
+
+ c = this.lookupComponent(this.applyDefaults(comp));
+ index = Math.min(index, this.items.length);
+
+ if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
+ if (c.ownerCt == this) {
+ this.items.remove(c);
+ }
+ this.items.insert(index, c);
+ c.onAdded(this, index);
+ this.onAdd(c);
+ this.fireEvent('add', this, c, index);
+ }
+
+ return c;
+ },
+
+
+ applyDefaults : function(c){
+ var d = this.defaults;
+ if(d){
+ if(Ext.isFunction(d)){
+ d = d.call(this, c);
+ }
+ if(Ext.isString(c)){
+ c = Ext.ComponentMgr.get(c);
+ Ext.apply(c, d);
+ }else if(!c.events){
+ Ext.applyIf(c.isAction ? c.initialConfig : c, d);
+ }else{
+ Ext.apply(c, d);
+ }
+ }
+ return c;
+ },
+
+
+ onBeforeAdd : function(item){
+ if(item.ownerCt){
+ item.ownerCt.remove(item, false);
+ }
+ if(this.hideBorders === true){
+ item.border = (item.border === true);
+ }
+ },
+
+
+ remove : function(comp, autoDestroy){
+ this.initItems();
+ var c = this.getComponent(comp);
+ if(c && this.fireEvent('beforeremove', this, c) !== false){
+ this.doRemove(c, autoDestroy);
+ this.fireEvent('remove', this, c);
+ }
+ return c;
+ },
+
+ onRemove: function(c){
+
+ },
+
+
+ doRemove: function(c, autoDestroy){
+ var l = this.layout,
+ hasLayout = l && this.rendered;
+
+ if(hasLayout){
+ l.onRemove(c);
+ }
+ this.items.remove(c);
+ c.onRemoved();
+ this.onRemove(c);
+ if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
+ c.destroy();
+ }
+ if(hasLayout){
+ l.afterRemove(c);
+ }
+ },
+
+
+ removeAll: function(autoDestroy){
+ this.initItems();
+ var item, rem = [], items = [];
+ this.items.each(function(i){
+ rem.push(i);
+ });
+ for (var i = 0, len = rem.length; i < len; ++i){
+ item = rem[i];
+ this.remove(item, autoDestroy);
+ if(item.ownerCt !== this){
+ items.push(item);
+ }
+ }
+ return items;
+ },
+
+
+ getComponent : function(comp){
+ if(Ext.isObject(comp)){
+ comp = comp.getItemId();
+ }
+ return this.items.get(comp);
+ },
+
+
+ lookupComponent : function(comp){
+ if(Ext.isString(comp)){
+ return Ext.ComponentMgr.get(comp);
+ }else if(!comp.events){
+ return this.createComponent(comp);
+ }
+ return comp;
+ },
+
+
+ createComponent : function(config, defaultType){
+ if (config.render) {
+ return config;
+ }
+
+
+ var c = Ext.create(Ext.apply({
+ ownerCt: this
+ }, config), defaultType || this.defaultType);
+ delete c.initialConfig.ownerCt;
+ delete c.ownerCt;
+ return c;
+ },
+
+
+ canLayout : function() {
+ var el = this.getVisibilityEl();
+ return el && el.dom && !el.isStyle("display", "none");
+ },
+
+
+
+ doLayout : function(shallow, force){
+ var rendered = this.rendered,
+ forceLayout = force || this.forceLayout;
+
+ if(this.collapsed || !this.canLayout()){
+ this.deferLayout = this.deferLayout || !shallow;
+ if(!forceLayout){
+ return;
+ }
+ shallow = shallow && !this.deferLayout;
+ } else {
+ delete this.deferLayout;
+ }
+ if(rendered && this.layout){
+ this.layout.layout();
+ }
+ if(shallow !== true && this.items){
+ var cs = this.items.items;
+ for(var i = 0, len = cs.length; i < len; i++){
+ var c = cs[i];
+ if(c.doLayout){
+ c.doLayout(false, forceLayout);
+ }
+ }
+ }
+ if(rendered){
+ this.onLayout(shallow, forceLayout);
+ }
+
+ this.hasLayout = true;
+ delete this.forceLayout;
+ },
+
+ onLayout : Ext.emptyFn,
+
+
+ shouldBufferLayout: function(){
+
+ var hl = this.hasLayout;
+ if(this.ownerCt){
+
+ return hl ? !this.hasLayoutPending() : false;
+ }
+
+ return hl;
+ },
+
+
+ hasLayoutPending: function(){
+
+ var pending = false;
+ this.ownerCt.bubble(function(c){
+ if(c.layoutPending){
+ pending = true;
+ return false;
+ }
+ });
+ return pending;
+ },
+
+ onShow : function(){
+
+ Ext.Container.superclass.onShow.call(this);
+
+ if(Ext.isDefined(this.deferLayout)){
+ delete this.deferLayout;
+ this.doLayout(true);
+ }
+ },
+
+
+ getLayout : function(){
+ if(!this.layout){
+ var layout = new Ext.layout.AutoLayout(this.layoutConfig);
+ this.setLayout(layout);
+ }
+ return this.layout;
+ },
+
+
+ beforeDestroy : function(){
+ var c;
+ if(this.items){
+ while(c = this.items.first()){
+ this.doRemove(c, true);
+ }
+ }
+ if(this.monitorResize){
+ Ext.EventManager.removeResizeListener(this.doLayout, this);
+ }
+ Ext.destroy(this.layout);
+ Ext.Container.superclass.beforeDestroy.call(this);
+ },
+
+
+ cascade : function(fn, scope, args){
+ if(fn.apply(scope || this, args || [this]) !== false){
+ if(this.items){
+ var cs = this.items.items;
+ for(var i = 0, len = cs.length; i < len; i++){
+ if(cs[i].cascade){
+ cs[i].cascade(fn, scope, args);
+ }else{
+ fn.apply(scope || cs[i], args || [cs[i]]);
+ }
+ }
+ }
+ }
+ return this;
+ },
+
+
+ findById : function(id){
+ var m = null,
+ ct = this;
+ this.cascade(function(c){
+ if(ct != c && c.id === id){
+ m = c;
+ return false;
+ }
+ });
+ return m;
+ },
+
+
+ findByType : function(xtype, shallow){
+ return this.findBy(function(c){
+ return c.isXType(xtype, shallow);
+ });
+ },
+
+
+ find : function(prop, value){
+ return this.findBy(function(c){
+ return c[prop] === value;
+ });
+ },
+
+
+ findBy : function(fn, scope){
+ var m = [], ct = this;
+ this.cascade(function(c){
+ if(ct != c && fn.call(scope || c, c, ct) === true){
+ m.push(c);
+ }
+ });
+ return m;
+ },
+
+
+ get : function(key){
+ return this.getComponent(key);
+ }
+});
+
+Ext.Container.LAYOUTS = {};
+Ext.reg('container', Ext.Container);
+
+Ext.layout.ContainerLayout = Ext.extend(Object, {
+
+
+
+
+
+
+ monitorResize:false,
+
+ activeItem : null,
+
+ constructor : function(config){
+ this.id = Ext.id(null, 'ext-layout-');
+ Ext.apply(this, config);
+ },
+
+ type: 'container',
+
+
+ IEMeasureHack : function(target, viewFlag) {
+ var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
+ for (i = 0 ; i < tLen ; i++) {
+ c = tChildren[i];
+ e = Ext.get(c);
+ if (e) {
+ d[i] = e.getStyle('display');
+ e.setStyle({display: 'none'});
+ }
+ }
+ ret = target ? target.getViewSize(viewFlag) : {};
+ for (i = 0 ; i < tLen ; i++) {
+ c = tChildren[i];
+ e = Ext.get(c);
+ if (e) {
+ e.setStyle({display: d[i]});
+ }
+ }
+ return ret;
+ },
+
+
+ getLayoutTargetSize : Ext.EmptyFn,
+
+
+ layout : function(){
+ var ct = this.container, target = ct.getLayoutTarget();
+ if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
+ target.addClass(this.targetCls);
+ }
+ this.onLayout(ct, target);
+ ct.fireEvent('afterlayout', ct, this);
+ },
+
+
+ onLayout : function(ct, target){
+ this.renderAll(ct, target);
+ },
+
+
+ isValidParent : function(c, target){
+ return target && c.getPositionEl().dom.parentNode == (target.dom || target);
+ },
+
+
+ renderAll : function(ct, target){
+ var items = ct.items.items, i, c, len = items.length;
+ for(i = 0; i < len; i++) {
+ c = items[i];
+ if(c && (!c.rendered || !this.isValidParent(c, target))){
+ this.renderItem(c, i, target);
+ }
+ }
+ },
+
+
+ renderItem : function(c, position, target){
+ if (c) {
+ if (!c.rendered) {
+ c.render(target, position);
+ this.configureItem(c);
+ } else if (!this.isValidParent(c, target)) {
+ if (Ext.isNumber(position)) {
+ position = target.dom.childNodes[position];
+ }
+
+ target.dom.insertBefore(c.getPositionEl().dom, position || null);
+ c.container = target;
+ this.configureItem(c);
+ }
+ }
+ },
+
+
+
+ getRenderedItems: function(ct){
+ var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
+ for (i = 0; i < len; i++) {
+ if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
+ items.push(c);
+ }
+ };
+ return items;
+ },
+
+
+ configureItem: function(c){
+ if (this.extraCls) {
+ var t = c.getPositionEl ? c.getPositionEl() : c;
+ t.addClass(this.extraCls);
+ }
+
+
+ if (c.doLayout && this.forceLayout) {
+ c.doLayout();
+ }
+ if (this.renderHidden && c != this.activeItem) {
+ c.hide();
+ }
+ },
+
+ onRemove: function(c){
+ if(this.activeItem == c){
+ delete this.activeItem;
+ }
+ if(c.rendered && this.extraCls){
+ var t = c.getPositionEl ? c.getPositionEl() : c;
+ t.removeClass(this.extraCls);
+ }
+ },
+
+ afterRemove: function(c){
+ if(c.removeRestore){
+ c.removeMode = 'container';
+ delete c.removeRestore;
+ }
+ },
+
+
+ onResize: function(){
+ var ct = this.container,
+ b;
+ if(ct.collapsed){
+ return;
+ }
+ if(b = ct.bufferResize && ct.shouldBufferLayout()){
+ if(!this.resizeTask){
+ this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
+ this.resizeBuffer = Ext.isNumber(b) ? b : 50;
+ }
+ ct.layoutPending = true;
+ this.resizeTask.delay(this.resizeBuffer);
+ }else{
+ this.runLayout();
+ }
+ },
+
+ runLayout: function(){
+ var ct = this.container;
+ this.layout();
+ ct.onLayout();
+ delete ct.layoutPending;
+ },
+
+
+ setContainer : function(ct){
+
+ if(this.monitorResize && ct != this.container){
+ var old = this.container;
+ if(old){
+ old.un(old.resizeEvent, this.onResize, this);
+ }
+ if(ct){
+ ct.on(ct.resizeEvent, this.onResize, this);
+ }
+ }
+ this.container = ct;
+ },
+
+
+ parseMargins : function(v){
+ if (Ext.isNumber(v)) {
+ v = v.toString();
+ }
+ var ms = v.split(' '),
+ len = ms.length;
+
+ if (len == 1) {
+ ms[1] = ms[2] = ms[3] = ms[0];
+ } else if(len == 2) {
+ ms[2] = ms[0];
+ ms[3] = ms[1];
+ } else if(len == 3) {
+ ms[3] = ms[1];
+ }
+
+ return {
+ top :parseInt(ms[0], 10) || 0,
+ right :parseInt(ms[1], 10) || 0,
+ bottom:parseInt(ms[2], 10) || 0,
+ left :parseInt(ms[3], 10) || 0
+ };
+ },
+
+
+ fieldTpl: (function() {
+ var t = new Ext.Template(
+ '<div class="x-form-item {itemCls}" tabIndex="-1">',
+ '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
+ '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
+ '</div><div class="{clearCls}"></div>',
+ '</div>'
+ );
+ t.disableFormats = true;
+ return t.compile();
+ })(),
+
+
+ destroy : function(){
+
+ if(this.resizeTask && this.resizeTask.cancel){
+ this.resizeTask.cancel();
+ }
+ if(this.container) {
+ this.container.un(this.container.resizeEvent, this.onResize, this);
+ }
+ if(!Ext.isEmpty(this.targetCls)){
+ var target = this.container.getLayoutTarget();
+ if(target){
+ target.removeClass(this.targetCls);
+ }
+ }
+ }
+});
+Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
+ type: 'auto',
+
+ monitorResize: true,
+
+ onLayout : function(ct, target){
+ Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
+ var cs = this.getRenderedItems(ct), len = cs.length, i, c;
+ for(i = 0; i < len; i++){
+ c = cs[i];
+ if (c.doLayout){
+
+ c.doLayout(true);
+ }
+ }
+ }
+});
+
+Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
+
+Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+ monitorResize:true,
+
+ type: 'fit',
+
+ getLayoutTargetSize : function() {
+ var target = this.container.getLayoutTarget();
+ if (!target) {
+ return {};
+ }
+
+ return target.getStyleSize();
+ },
+
+
+ onLayout : function(ct, target){
+ Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
+ if(!ct.collapsed){
+ this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
+ }
+ },
+
+
+ setItemSize : function(item, size){
+ if(item && size.height > 0){
+ item.setSize(size);
+ }
+ }
+});
+Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
+Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
+
+ deferredRender : false,
+
+
+ layoutOnCardChange : false,
+
+
+
+ renderHidden : true,
+
+ type: 'card',
+
+
+ setActiveItem : function(item){
+ var ai = this.activeItem,
+ ct = this.container;
+ item = ct.getComponent(item);
+
+
+ if(item && ai != item){
+
+
+ if(ai){
+ ai.hide();
+ if (ai.hidden !== true) {
+ return false;
+ }
+ ai.fireEvent('deactivate', ai);
+ }
+
+ var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
+
+
+ this.activeItem = item;
+
+
+
+ delete item.deferLayout;
+
+
+ item.show();
+
+ this.layout();
+
+ if(layout){
+ item.doLayout();
+ }
+ item.fireEvent('activate', item);
+ }
+ },
+
+
+ renderAll : function(ct, target){
+ if(this.deferredRender){
+ this.renderItem(this.activeItem, undefined, target);
+ }else{
+ Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
+ }
+ }
+});
+Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
+
+Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+
+
+ monitorResize : true,
+
+ type : 'anchor',
+
+
+ defaultAnchor : '100%',
+
+ parseAnchorRE : /^(r|right|b|bottom)$/i,
+
+
+ getLayoutTargetSize : function() {
+ var target = this.container.getLayoutTarget(), ret = {};
+ if (target) {
+ ret = target.getViewSize();
+
+
+
+
+ if (Ext.isIE9m && Ext.isStrict && ret.width == 0){
+ ret = target.getStyleSize();
+ }
+ ret.width -= target.getPadding('lr');
+ ret.height -= target.getPadding('tb');
+ }
+ return ret;
+ },
+
+
+ onLayout : function(container, target) {
+ Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);
+
+ var size = this.getLayoutTargetSize(),
+ containerWidth = size.width,
+ containerHeight = size.height,
+ overflow = target.getStyle('overflow'),
+ components = this.getRenderedItems(container),
+ len = components.length,
+ boxes = [],
+ box,
+ anchorWidth,
+ anchorHeight,
+ component,
+ anchorSpec,
+ calcWidth,
+ calcHeight,
+ anchorsArray,
+ totalHeight = 0,
+ i,
+ el;
+
+ if(containerWidth < 20 && containerHeight < 20){
+ return;
+ }
+
+
+ if(container.anchorSize) {
+ if(typeof container.anchorSize == 'number') {
+ anchorWidth = container.anchorSize;
+ } else {
+ anchorWidth = container.anchorSize.width;
+ anchorHeight = container.anchorSize.height;
+ }
+ } else {
+ anchorWidth = container.initialConfig.width;
+ anchorHeight = container.initialConfig.height;
+ }
+
+ for(i = 0; i < len; i++) {
+ component = components[i];
+ el = component.getPositionEl();
+
+
+ if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
+ component.anchor = this.defaultAnchor;
+ }
+
+ if(component.anchor) {
+ anchorSpec = component.anchorSpec;
+
+ if(!anchorSpec){
+ anchorsArray = component.anchor.split(' ');
+ component.anchorSpec = anchorSpec = {
+ right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
+ bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
+ };
+ }
+ calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
+ calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;
+
+ if(calcWidth || calcHeight) {
+ boxes.push({
+ component: component,
+ width: calcWidth || undefined,
+ height: calcHeight || undefined
+ });
+ }
+ }
+ }
+ for (i = 0, len = boxes.length; i < len; i++) {
+ box = boxes[i];
+ box.component.setSize(box.width, box.height);
+ }
+
+ if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
+ var newTargetSize = this.getLayoutTargetSize();
+ if (newTargetSize.width != size.width || newTargetSize.height != size.height){
+ this.adjustmentPass = true;
+ this.onLayout(container, target);
+ }
+ }
+
+ delete this.adjustmentPass;
+ },
+
+
+ parseAnchor : function(a, start, cstart) {
+ if (a && a != 'none') {
+ var last;
+
+ if (this.parseAnchorRE.test(a)) {
+ var diff = cstart - start;
+ return function(v){
+ if(v !== last){
+ last = v;
+ return v - diff;
+ }
+ };
+
+ } else if(a.indexOf('%') != -1) {
+ var ratio = parseFloat(a.replace('%', ''))*.01;
+ return function(v){
+ if(v !== last){
+ last = v;
+ return Math.floor(v*ratio);
+ }
+ };
+
+ } else {
+ a = parseInt(a, 10);
+ if (!isNaN(a)) {
+ return function(v) {
+ if (v !== last) {
+ last = v;
+ return v + a;
+ }
+ };
+ }
+ }
+ }
+ return false;
+ },
+
+
+ adjustWidthAnchor : function(value, comp){
+ return value;
+ },
+
+
+ adjustHeightAnchor : function(value, comp){
+ return value;
+ }
+
+
+});
+Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
+
+Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+ monitorResize:true,
+
+ type: 'column',
+
+ extraCls: 'x-column',
+
+ scrollOffset : 0,
+
+
+
+ targetCls: 'x-column-layout-ct',
+
+ isValidParent : function(c, target){
+ return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
+ },
+
+ getLayoutTargetSize : function() {
+ var target = this.container.getLayoutTarget(), ret;
+ if (target) {
+ ret = target.getViewSize();
+
+
+
+
+ if (Ext.isIE9m && Ext.isStrict && ret.width == 0){
+ ret = target.getStyleSize();
+ }
+
+ ret.width -= target.getPadding('lr');
+ ret.height -= target.getPadding('tb');
+ }
+ return ret;
+ },
+
+ renderAll : function(ct, target) {
+ if(!this.innerCt){
+
+
+ this.innerCt = target.createChild({cls:'x-column-inner'});
+ this.innerCt.createChild({cls:'x-clear'});
+ }
+ Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
+ },
+
+
+ onLayout : function(ct, target){
+ var cs = ct.items.items,
+ len = cs.length,
+ c,
+ i,
+ m,
+ margins = [];
+
+ this.renderAll(ct, target);
+
+ var size = this.getLayoutTargetSize();
+
+ if (Ext.isIE9m && (size.width < 1 && size.height < 1)) {
+ return;
+ }
+
+ var w = size.width - this.scrollOffset,
+ h = size.height,
+ pw = w;
+
+ this.innerCt.setWidth(w);
+
+
+
+
+ for(i = 0; i < len; i++){
+ c = cs[i];
+ m = c.getPositionEl().getMargins('lr');
+ margins[i] = m;
+ if(!c.columnWidth){
+ pw -= (c.getWidth() + m);
+ }
+ }
+
+ pw = pw < 0 ? 0 : pw;
+
+ for(i = 0; i < len; i++){
+ c = cs[i];
+ m = margins[i];
+ if(c.columnWidth){
+ c.setSize(Math.floor(c.columnWidth * pw) - m);
+ }
+ }
+
+
+
+ if (Ext.isIE9m) {
+ if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
+ var ts = this.getLayoutTargetSize();
+ if (ts.width != size.width){
+ this.adjustmentPass = true;
+ this.onLayout(ct, target);
+ }
+ }
+ }
+ delete this.adjustmentPass;
+ }
+
+
+});
+
+Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
+
+Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+ monitorResize:true,
+
+ rendered : false,
+
+ type: 'border',
+
+ targetCls: 'x-border-layout-ct',
+
+ getLayoutTargetSize : function() {
+ var target = this.container.getLayoutTarget();
+ return target ? target.getViewSize() : {};
+ },
+
+
+ onLayout : function(ct, target){
+ var collapsed, i, c, pos, items = ct.items.items, len = items.length;
+ if(!this.rendered){
+ collapsed = [];
+ for(i = 0; i < len; i++) {
+ c = items[i];
+ pos = c.region;
+ if(c.collapsed){
+ collapsed.push(c);
+ }
+ c.collapsed = false;
+ if(!c.rendered){
+ c.render(target, i);
+ c.getPositionEl().addClass('x-border-panel');
+ }
+ this[pos] = pos != 'center' && c.split ?
+ new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
+ new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
+ this[pos].render(target, c);
+ }
+ this.rendered = true;
+ }
+
+ var size = this.getLayoutTargetSize();
+ if(size.width < 20 || size.height < 20){
+ if(collapsed){
+ this.restoreCollapsed = collapsed;
+ }
+ return;
+ }else if(this.restoreCollapsed){
+ collapsed = this.restoreCollapsed;
+ delete this.restoreCollapsed;
+ }
+
+ var w = size.width, h = size.height,
+ centerW = w, centerH = h, centerY = 0, centerX = 0,
+ n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
+ b, m, totalWidth, totalHeight;
+ if(!c && Ext.layout.BorderLayout.WARN !== false){
+ throw 'No center region defined in BorderLayout ' + ct.id;
+ }
+
+ if(n && n.isVisible()){
+ b = n.getSize();
+ m = n.getMargins();
+ b.width = w - (m.left+m.right);
+ b.x = m.left;
+ b.y = m.top;
+ centerY = b.height + b.y + m.bottom;
+ centerH -= centerY;
+ n.applyLayout(b);
+ }
+ if(s && s.isVisible()){
+ b = s.getSize();
+ m = s.getMargins();
+ b.width = w - (m.left+m.right);
+ b.x = m.left;
+ totalHeight = (b.height + m.top + m.bottom);
+ b.y = h - totalHeight + m.top;
+ centerH -= totalHeight;
+ s.applyLayout(b);
+ }
+ if(west && west.isVisible()){
+ b = west.getSize();
+ m = west.getMargins();
+ b.height = centerH - (m.top+m.bottom);
+ b.x = m.left;
+ b.y = centerY + m.top;
+ totalWidth = (b.width + m.left + m.right);
+ centerX += totalWidth;
+ centerW -= totalWidth;
+ west.applyLayout(b);
+ }
+ if(e && e.isVisible()){
+ b = e.getSize();
+ m = e.getMargins();
+ b.height = centerH - (m.top+m.bottom);
+ totalWidth = (b.width + m.left + m.right);
+ b.x = w - totalWidth + m.left;
+ b.y = centerY + m.top;
+ centerW -= totalWidth;
+ e.applyLayout(b);
+ }
+ if(c){
+ m = c.getMargins();
+ var centerBox = {
+ x: centerX + m.left,
+ y: centerY + m.top,
+ width: centerW - (m.left+m.right),
+ height: centerH - (m.top+m.bottom)
+ };
+ c.applyLayout(centerBox);
+ }
+ if(collapsed){
+ for(i = 0, len = collapsed.length; i < len; i++){
+ collapsed[i].collapse(false);
+ }
+ }
+ if(Ext.isIE9m && Ext.isStrict){
+ target.repaint();
+ }
+
+ if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
+ var ts = this.getLayoutTargetSize();
+ if (ts.width != size.width || ts.height != size.height){
+ this.adjustmentPass = true;
+ this.onLayout(ct, target);
+ }
+ }
+ delete this.adjustmentPass;
+ },
+
+ destroy: function() {
+ var r = ['north', 'south', 'east', 'west'], i, region;
+ for (i = 0; i < r.length; i++) {
+ region = this[r[i]];
+ if(region){
+ if(region.destroy){
+ region.destroy();
+ }else if (region.split){
+ region.split.destroy(true);
+ }
+ }
+ }
+ Ext.layout.BorderLayout.superclass.destroy.call(this);
+ }
+
+
+});
+
+
+Ext.layout.BorderLayout.Region = function(layout, config, pos){
+ Ext.apply(this, config);
+ this.layout = layout;
+ this.position = pos;
+ this.state = {};
+ if(typeof this.margins == 'string'){
+ this.margins = this.layout.parseMargins(this.margins);
+ }
+ this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
+ if(this.collapsible){
+ if(typeof this.cmargins == 'string'){
+ this.cmargins = this.layout.parseMargins(this.cmargins);
+ }
+ if(this.collapseMode == 'mini' && !this.cmargins){
+ this.cmargins = {left:0,top:0,right:0,bottom:0};
+ }else{
+ this.cmargins = Ext.applyIf(this.cmargins || {},
+ pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
+ }
+ }
+};
+
+Ext.layout.BorderLayout.Region.prototype = {
+
+
+
+
+
+
+ collapsible : false,
+
+ split:false,
+
+ floatable: true,
+
+ minWidth:50,
+
+ minHeight:50,
+
+
+ defaultMargins : {left:0,top:0,right:0,bottom:0},
+
+ defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
+
+ defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
+ floatingZIndex: 100,
+
+
+ isCollapsed : false,
+
+
+
+
+
+
+ render : function(ct, p){
+ this.panel = p;
+ p.el.enableDisplayMode();
+ this.targetEl = ct;
+ this.el = p.el;
+
+ var gs = p.getState, ps = this.position;
+ p.getState = function(){
+ return Ext.apply(gs.call(p) || {}, this.state);
+ }.createDelegate(this);
+
+ if(ps != 'center'){
+ p.allowQueuedExpand = false;
+ p.on({
+ beforecollapse: this.beforeCollapse,
+ collapse: this.onCollapse,
+ beforeexpand: this.beforeExpand,
+ expand: this.onExpand,
+ hide: this.onHide,
+ show: this.onShow,
+ scope: this
+ });
+ if(this.collapsible || this.floatable){
+ p.collapseEl = 'el';
+ p.slideAnchor = this.getSlideAnchor();
+ }
+ if(p.tools && p.tools.toggle){
+ p.tools.toggle.addClass('x-tool-collapse-'+ps);
+ p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
+ }
+ }
+ },
+
+
+ getCollapsedEl : function(){
+ if(!this.collapsedEl){
+ if(!this.toolTemplate){
+ var tt = new Ext.Template(
+ '<div class="x-tool x-tool-{id}">&#160;</div>'
+ );
+ tt.disableFormats = true;
+ tt.compile();
+ Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
+ }
+ this.collapsedEl = this.targetEl.createChild({
+ cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
+ id: this.panel.id + '-xcollapsed'
+ });
+ this.collapsedEl.enableDisplayMode('block');
+
+ if(this.collapseMode == 'mini'){
+ this.collapsedEl.addClass('x-layout-cmini-'+this.position);
+ this.miniCollapsedEl = this.collapsedEl.createChild({
+ cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
+ });
+ this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
+ this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
+ this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
+ }else {
+ if(this.collapsible !== false && !this.hideCollapseTool) {
+ var t = this.expandToolEl = this.toolTemplate.append(
+ this.collapsedEl.dom,
+ {id:'expand-'+this.position}, true);
+ t.addClassOnOver('x-tool-expand-'+this.position+'-over');
+ t.on('click', this.onExpandClick, this, {stopEvent:true});
+ }
+ if(this.floatable !== false || this.titleCollapse){
+ this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
+ this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
+ }
+ }
+ }
+ return this.collapsedEl;
+ },
+
+
+ onExpandClick : function(e){
+ if(this.isSlid){
+ this.panel.expand(false);
+ }else{
+ this.panel.expand();
+ }
+ },
+
+
+ onCollapseClick : function(e){
+ this.panel.collapse();
+ },
+
+
+ beforeCollapse : function(p, animate){
+ this.lastAnim = animate;
+ if(this.splitEl){
+ this.splitEl.hide();
+ }
+ this.getCollapsedEl().show();
+ var el = this.panel.getEl();
+ this.originalZIndex = el.getStyle('z-index');
+ el.setStyle('z-index', 100);
+ this.isCollapsed = true;
+ this.layout.layout();
+ },
+
+
+ onCollapse : function(animate){
+ this.panel.el.setStyle('z-index', 1);
+ if(this.lastAnim === false || this.panel.animCollapse === false){
+ this.getCollapsedEl().dom.style.visibility = 'visible';
+ }else{
+ this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
+ }
+ this.state.collapsed = true;
+ this.panel.saveState();
+ },
+
+
+ beforeExpand : function(animate){
+ if(this.isSlid){
+ this.afterSlideIn();
+ }
+ var c = this.getCollapsedEl();
+ this.el.show();
+ if(this.position == 'east' || this.position == 'west'){
+ this.panel.setSize(undefined, c.getHeight());
+ }else{
+ this.panel.setSize(c.getWidth(), undefined);
+ }
+ c.hide();
+ c.dom.style.visibility = 'hidden';
+ this.panel.el.setStyle('z-index', this.floatingZIndex);
+ },
+
+
+ onExpand : function(){
+ this.isCollapsed = false;
+ if(this.splitEl){
+ this.splitEl.show();
+ }
+ this.layout.layout();
+ this.panel.el.setStyle('z-index', this.originalZIndex);
+ this.state.collapsed = false;
+ this.panel.saveState();
+ },
+
+
+ collapseClick : function(e){
+ if(this.isSlid){
+ e.stopPropagation();
+ this.slideIn();
+ }else{
+ e.stopPropagation();
+ this.slideOut();
+ }
+ },
+
+
+ onHide : function(){
+ if(this.isCollapsed){
+ this.getCollapsedEl().hide();
+ }else if(this.splitEl){
+ this.splitEl.hide();
+ }
+ },
+
+
+ onShow : function(){
+ if(this.isCollapsed){
+ this.getCollapsedEl().show();
+ }else if(this.splitEl){
+ this.splitEl.show();
+ }
+ },
+
+
+ isVisible : function(){
+ return !this.panel.hidden;
+ },
+
+
+ getMargins : function(){
+ return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
+ },
+
+
+ getSize : function(){
+ return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
+ },
+
+
+ setPanel : function(panel){
+ this.panel = panel;
+ },
+
+
+ getMinWidth: function(){
+ return this.minWidth;
+ },
+
+
+ getMinHeight: function(){
+ return this.minHeight;
+ },
+
+
+ applyLayoutCollapsed : function(box){
+ var ce = this.getCollapsedEl();
+ ce.setLeftTop(box.x, box.y);
+ ce.setSize(box.width, box.height);
+ },
+
+
+ applyLayout : function(box){
+ if(this.isCollapsed){
+ this.applyLayoutCollapsed(box);
+ }else{
+ this.panel.setPosition(box.x, box.y);
+ this.panel.setSize(box.width, box.height);
+ }
+ },
+
+
+ beforeSlide: function(){
+ this.panel.beforeEffect();
+ },
+
+
+ afterSlide : function(){
+ this.panel.afterEffect();
+ },
+
+
+ initAutoHide : function(){
+ if(this.autoHide !== false){
+ if(!this.autoHideHd){
+ this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
+ this.autoHideHd = {
+ "mouseout": function(e){
+ if(!e.within(this.el, true)){
+ this.autoHideSlideTask.delay(500);
+ }
+ },
+ "mouseover" : function(e){
+ this.autoHideSlideTask.cancel();
+ },
+ scope : this
+ };
+ }
+ this.el.on(this.autoHideHd);
+ this.collapsedEl.on(this.autoHideHd);
+ }
+ },
+
+
+ clearAutoHide : function(){
+ if(this.autoHide !== false){
+ this.el.un("mouseout", this.autoHideHd.mouseout);
+ this.el.un("mouseover", this.autoHideHd.mouseover);
+ this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
+ this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
+ }
+ },
+
+
+ clearMonitor : function(){
+ Ext.getDoc().un("click", this.slideInIf, this);
+ },
+
+
+ slideOut : function(){
+ if(this.isSlid || this.el.hasActiveFx()){
+ return;
+ }
+ this.isSlid = true;
+ var ts = this.panel.tools, dh, pc;
+ if(ts && ts.toggle){
+ ts.toggle.hide();
+ }
+ this.el.show();
+
+
+ pc = this.panel.collapsed;
+ this.panel.collapsed = false;
+
+ if(this.position == 'east' || this.position == 'west'){
+
+ dh = this.panel.deferHeight;
+ this.panel.deferHeight = false;
+
+ this.panel.setSize(undefined, this.collapsedEl.getHeight());
+
+
+ this.panel.deferHeight = dh;
+ }else{
+ this.panel.setSize(this.collapsedEl.getWidth(), undefined);
+ }
+
+
+ this.panel.collapsed = pc;
+
+ this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
+ this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
+ this.el.setStyle("z-index", this.floatingZIndex+2);
+ this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
+ if(this.animFloat !== false){
+ this.beforeSlide();
+ this.el.slideIn(this.getSlideAnchor(), {
+ callback: function(){
+ this.afterSlide();
+ this.initAutoHide();
+ Ext.getDoc().on("click", this.slideInIf, this);
+ },
+ scope: this,
+ block: true
+ });
+ }else{
+ this.initAutoHide();
+ Ext.getDoc().on("click", this.slideInIf, this);
+ }
+ },
+
+
+ afterSlideIn : function(){
+ this.clearAutoHide();
+ this.isSlid = false;
+ this.clearMonitor();
+ this.el.setStyle("z-index", "");
+ this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
+ this.el.dom.style.left = this.restoreLT[0];
+ this.el.dom.style.top = this.restoreLT[1];
+
+ var ts = this.panel.tools;
+ if(ts && ts.toggle){
+ ts.toggle.show();
+ }
+ },
+
+
+ slideIn : function(cb){
+ if(!this.isSlid || this.el.hasActiveFx()){
+ Ext.callback(cb);
+ return;
+ }
+ this.isSlid = false;
+ if(this.animFloat !== false){
+ this.beforeSlide();
+ this.el.slideOut(this.getSlideAnchor(), {
+ callback: function(){
+ this.el.hide();
+ this.afterSlide();
+ this.afterSlideIn();
+ Ext.callback(cb);
+ },
+ scope: this,
+ block: true
+ });
+ }else{
+ this.el.hide();
+ this.afterSlideIn();
+ }
+ },
+
+
+ slideInIf : function(e){
+ if(!e.within(this.el)){
+ this.slideIn();
+ }
+ },
+
+
+ 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;
+ }
+ },
+
+ destroy : function(){
+ if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
+ this.autoHideSlideTask.cancel();
+ }
+ Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
+ }
+};
+
+
+Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
+ Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
+
+ this.applyLayout = this.applyFns[pos];
+};
+
+Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
+
+
+ splitTip : "Drag to resize.",
+
+ collapsibleSplitTip : "Drag to resize. Double click to hide.",
+
+ useSplitTips : false,
+
+
+ splitSettings : {
+ north : {
+ orientation: Ext.SplitBar.VERTICAL,
+ placement: Ext.SplitBar.TOP,
+ maxFn : 'getVMaxSize',
+ minProp: 'minHeight',
+ maxProp: 'maxHeight'
+ },
+ south : {
+ orientation: Ext.SplitBar.VERTICAL,
+ placement: Ext.SplitBar.BOTTOM,
+ maxFn : 'getVMaxSize',
+ minProp: 'minHeight',
+ maxProp: 'maxHeight'
+ },
+ east : {
+ orientation: Ext.SplitBar.HORIZONTAL,
+ placement: Ext.SplitBar.RIGHT,
+ maxFn : 'getHMaxSize',
+ minProp: 'minWidth',
+ maxProp: 'maxWidth'
+ },
+ west : {
+ orientation: Ext.SplitBar.HORIZONTAL,
+ placement: Ext.SplitBar.LEFT,
+ maxFn : 'getHMaxSize',
+ minProp: 'minWidth',
+ maxProp: 'maxWidth'
+ }
+ },
+
+
+ applyFns : {
+ west : function(box){
+ if(this.isCollapsed){
+ return this.applyLayoutCollapsed(box);
+ }
+ var sd = this.splitEl.dom, s = sd.style;
+ this.panel.setPosition(box.x, box.y);
+ var sw = sd.offsetWidth;
+ s.left = (box.x+box.width-sw)+'px';
+ s.top = (box.y)+'px';
+ s.height = Math.max(0, box.height)+'px';
+ this.panel.setSize(box.width-sw, box.height);
+ },
+ east : function(box){
+ if(this.isCollapsed){
+ return this.applyLayoutCollapsed(box);
+ }
+ var sd = this.splitEl.dom, s = sd.style;
+ var sw = sd.offsetWidth;
+ this.panel.setPosition(box.x+sw, box.y);
+ s.left = (box.x)+'px';
+ s.top = (box.y)+'px';
+ s.height = Math.max(0, box.height)+'px';
+ this.panel.setSize(box.width-sw, box.height);
+ },
+ north : function(box){
+ if(this.isCollapsed){
+ return this.applyLayoutCollapsed(box);
+ }
+ var sd = this.splitEl.dom, s = sd.style;
+ var sh = sd.offsetHeight;
+ this.panel.setPosition(box.x, box.y);
+ s.left = (box.x)+'px';
+ s.top = (box.y+box.height-sh)+'px';
+ s.width = Math.max(0, box.width)+'px';
+ this.panel.setSize(box.width, box.height-sh);
+ },
+ south : function(box){
+ if(this.isCollapsed){
+ return this.applyLayoutCollapsed(box);
+ }
+ var sd = this.splitEl.dom, s = sd.style;
+ var sh = sd.offsetHeight;
+ this.panel.setPosition(box.x, box.y+sh);
+ s.left = (box.x)+'px';
+ s.top = (box.y)+'px';
+ s.width = Math.max(0, box.width)+'px';
+ this.panel.setSize(box.width, box.height-sh);
+ }
+ },
+
+
+ render : function(ct, p){
+ Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
+
+ var ps = this.position;
+
+ this.splitEl = ct.createChild({
+ cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
+ id: this.panel.id + '-xsplit'
+ });
+
+ if(this.collapseMode == 'mini'){
+ this.miniSplitEl = this.splitEl.createChild({
+ cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
+ });
+ this.miniSplitEl.addClassOnOver('x-layout-mini-over');
+ this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
+ }
+
+ var s = this.splitSettings[ps];
+
+ this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
+ this.split.tickSize = this.tickSize;
+ this.split.placement = s.placement;
+ this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
+ this.split.minSize = this.minSize || this[s.minProp];
+ this.split.on("beforeapply", this.onSplitMove, this);
+ this.split.useShim = this.useShim === true;
+ this.maxSize = this.maxSize || this[s.maxProp];
+
+ if(p.hidden){
+ this.splitEl.hide();
+ }
+
+ if(this.useSplitTips){
+ this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
+ }
+ if(this.collapsible){
+ this.splitEl.on("dblclick", this.onCollapseClick, this);
+ }
+ },
+
+
+ getSize : function(){
+ if(this.isCollapsed){
+ return this.collapsedEl.getSize();
+ }
+ var s = this.panel.getSize();
+ if(this.position == 'north' || this.position == 'south'){
+ s.height += this.splitEl.dom.offsetHeight;
+ }else{
+ s.width += this.splitEl.dom.offsetWidth;
+ }
+ return s;
+ },
+
+
+ getHMaxSize : function(){
+ var cmax = this.maxSize || 10000;
+ var center = this.layout.center;
+ return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
+ },
+
+
+ getVMaxSize : function(){
+ var cmax = this.maxSize || 10000;
+ var center = this.layout.center;
+ return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
+ },
+
+
+ onSplitMove : function(split, newSize){
+ var s = this.panel.getSize();
+ this.lastSplitSize = newSize;
+ if(this.position == 'north' || this.position == 'south'){
+ this.panel.setSize(s.width, newSize);
+ this.state.height = newSize;
+ }else{
+ this.panel.setSize(newSize, s.height);
+ this.state.width = newSize;
+ }
+ this.layout.layout();
+ this.panel.saveState();
+ return false;
+ },
+
+
+ getSplitBar : function(){
+ return this.split;
+ },
+
+
+ destroy : function() {
+ Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
+ Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
+ }
+});
+
+Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
+
+Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
+
+
+ labelSeparator : ':',
+
+
+
+
+ trackLabels: true,
+
+ type: 'form',
+
+ onRemove: function(c){
+ Ext.layout.FormLayout.superclass.onRemove.call(this, c);
+ if(this.trackLabels){
+ c.un('show', this.onFieldShow, this);
+ c.un('hide', this.onFieldHide, this);
+ }
+
+ var el = c.getPositionEl(),
+ ct = c.getItemCt && c.getItemCt();
+ if (c.rendered && ct) {
+ if (el && el.dom) {
+ el.insertAfter(ct);
+ }
+ Ext.destroy(ct);
+ Ext.destroyMembers(c, 'label', 'itemCt');
+ if (c.customItemCt) {
+ Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
+ }
+ }
+ },
+
+
+ setContainer : function(ct){
+ Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
+ ct.labelAlign = ct.labelAlign || this.labelAlign;
+ if (ct.labelAlign) {
+ ct.addClass('x-form-label-' + ct.labelAlign);
+ }
+
+ if (ct.hideLabels || this.hideLabels) {
+ Ext.apply(this, {
+ labelStyle: 'display:none',
+ elementStyle: 'padding-left:0;',
+ labelAdjust: 0
+ });
+ } else {
+ this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
+ ct.labelWidth = ct.labelWidth || this.labelWidth || 100;
+ if(Ext.isNumber(ct.labelWidth)){
+ var pad = ct.labelPad || this.labelPad;
+ pad = Ext.isNumber(pad) ? pad : 5;
+ Ext.apply(this, {
+ labelAdjust: ct.labelWidth + pad,
+ labelStyle: 'width:' + ct.labelWidth + 'px;',
+ elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
+ });
+ }
+ if(ct.labelAlign == 'top'){
+ Ext.apply(this, {
+ labelStyle: 'width:auto;',
+ labelAdjust: 0,
+ elementStyle: 'padding-left:0;'
+ });
+ }
+ }
+ },
+
+
+ isHide: function(c){
+ return c.hideLabel || this.container.hideLabels;
+ },
+
+ onFieldShow: function(c){
+ c.getItemCt().removeClass('x-hide-' + c.hideMode);
+
+
+ if (c.isComposite) {
+ c.doLayout();
+ }
+ },
+
+ onFieldHide: function(c){
+ c.getItemCt().addClass('x-hide-' + c.hideMode);
+ },
+
+
+ getLabelStyle: function(s){
+ var ls = '', items = [this.labelStyle, s];
+ for (var i = 0, len = items.length; i < len; ++i){
+ if (items[i]){
+ ls += items[i];
+ if (ls.substr(-1, 1) != ';'){
+ ls += ';';
+ }
+ }
+ }
+ return ls;
+ },
+
+
+
+
+ renderItem : function(c, position, target){
+ if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
+ var args = this.getTemplateArgs(c);
+ if(Ext.isNumber(position)){
+ position = target.dom.childNodes[position] || null;
+ }
+ if(position){
+ c.itemCt = this.fieldTpl.insertBefore(position, args, true);
+ }else{
+ c.itemCt = this.fieldTpl.append(target, args, true);
+ }
+ if(!c.getItemCt){
+
+
+ Ext.apply(c, {
+ getItemCt: function(){
+ return c.itemCt;
+ },
+ customItemCt: true
+ });
+ }
+ c.label = c.getItemCt().child('label.x-form-item-label');
+ if(!c.rendered){
+ c.render('x-form-el-' + c.id);
+ }else if(!this.isValidParent(c, target)){
+ Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
+ }
+ if(this.trackLabels){
+ if(c.hidden){
+ this.onFieldHide(c);
+ }
+ c.on({
+ scope: this,
+ show: this.onFieldShow,
+ hide: this.onFieldHide
+ });
+ }
+ this.configureItem(c);
+ }else {
+ Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
+ }
+ },
+
+
+ getTemplateArgs: function(field) {
+ var noLabelSep = !field.fieldLabel || field.hideLabel,
+ itemCls = (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : '');
+
+
+ if (Ext.isIE9 && Ext.isIEQuirks && field instanceof Ext.form.TextField) {
+ itemCls += ' x-input-wrapper';
+ }
+
+ return {
+ id : field.id,
+ label : field.fieldLabel,
+ itemCls : itemCls,
+ clearCls : field.clearCls || 'x-form-clear-left',
+ labelStyle : this.getLabelStyle(field.labelStyle),
+ elementStyle : this.elementStyle || '',
+ labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
+ };
+ },
+
+
+ adjustWidthAnchor: function(value, c){
+ if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
+ var adjust = Ext.isIE6 || Ext.isIEQuirks;
+ return value - this.labelAdjust + (adjust ? -3 : 0);
+ }
+ return value;
+ },
+
+ adjustHeightAnchor : function(value, c){
+ if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
+ return value - c.label.getHeight();
+ }
+ return value;
+ },
+
+
+ isValidParent : function(c, target){
+ return target && this.container.getEl().contains(c.getPositionEl());
+ }
+
+
+});
+
+Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
+
+Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
+
+ fill : true,
+
+ autoWidth : true,
+
+ titleCollapse : true,
+
+ hideCollapseTool : false,
+
+ collapseFirst : false,
+
+ animate : false,
+
+ sequence : false,
+
+ activeOnTop : false,
+
+ type: 'accordion',
+
+ renderItem : function(c){
+ if(this.animate === false){
+ c.animCollapse = false;
+ }
+ c.collapsible = true;
+ if(this.autoWidth){
+ c.autoWidth = true;
+ }
+ if(this.titleCollapse){
+ c.titleCollapse = true;
+ }
+ if(this.hideCollapseTool){
+ c.hideCollapseTool = true;
+ }
+ if(this.collapseFirst !== undefined){
+ c.collapseFirst = this.collapseFirst;
+ }
+ if(!this.activeItem && !c.collapsed){
+ this.setActiveItem(c, true);
+ }else if(this.activeItem && this.activeItem != c){
+ c.collapsed = true;
+ }
+ Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
+ c.header.addClass('x-accordion-hd');
+ c.on('beforeexpand', this.beforeExpand, this);
+ },
+
+ onRemove: function(c){
+ Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
+ if(c.rendered){
+ c.header.removeClass('x-accordion-hd');
+ }
+ c.un('beforeexpand', this.beforeExpand, this);
+ },
+
+
+ beforeExpand : function(p, anim){
+ var ai = this.activeItem;
+ if(ai){
+ if(this.sequence){
+ delete this.activeItem;
+ if (!ai.collapsed){
+ ai.collapse({callback:function(){
+ p.expand(anim || true);
+ }, scope: this});
+ return false;
+ }
+ }else{
+ ai.collapse(this.animate);
+ }
+ }
+ this.setActive(p);
+ if(this.activeOnTop){
+ p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
+ }
+
+ this.layout();
+ },
+
+
+ setItemSize : function(item, size){
+ if(this.fill && item){
+ var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
+
+ for (i = 0; i < len; i++) {
+ if((p = ct[i]) != item && !p.hidden){
+ hh += p.header.getHeight();
+ }
+ };
+
+ size.height -= hh;
+
+
+ item.setSize(size);
+ }
+ },
+
+
+ setActiveItem : function(item){
+ this.setActive(item, true);
+ },
+
+
+ setActive : function(item, expand){
+ var ai = this.activeItem;
+ item = this.container.getComponent(item);
+ if(ai != item){
+ if(item.rendered && item.collapsed && expand){
+ item.expand();
+ }else{
+ if(ai){
+ ai.fireEvent('deactivate', ai);
+ }
+ this.activeItem = item;
+ item.fireEvent('activate', item);
+ }
+ }
+ }
+});
+Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
+
+
+Ext.layout.Accordion = Ext.layout.AccordionLayout;
+Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+
+
+ monitorResize:false,
+
+ type: 'table',
+
+ targetCls: 'x-table-layout-ct',
+
+
+ tableAttrs:null,
+
+
+ setContainer : function(ct){
+ Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
+
+ this.currentRow = 0;
+ this.currentColumn = 0;
+ this.cells = [];
+ },
+
+
+ onLayout : function(ct, target){
+ var cs = ct.items.items, len = cs.length, c, i;
+
+ if(!this.table){
+ target.addClass('x-table-layout-ct');
+
+ this.table = target.createChild(
+ Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
+ }
+ this.renderAll(ct, target);
+ },
+
+
+ getRow : function(index){
+ var row = this.table.tBodies[0].childNodes[index];
+ if(!row){
+ row = document.createElement('tr');
+ this.table.tBodies[0].appendChild(row);
+ }
+ return row;
+ },
+
+
+ getNextCell : function(c){
+ var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
+ var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
+ for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
+ if(!this.cells[rowIndex]){
+ this.cells[rowIndex] = [];
+ }
+ for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
+ this.cells[rowIndex][colIndex] = true;
+ }
+ }
+ var td = document.createElement('td');
+ if(c.cellId){
+ td.id = c.cellId;
+ }
+ var cls = 'x-table-layout-cell';
+ if(c.cellCls){
+ cls += ' ' + c.cellCls;
+ }
+ td.className = cls;
+ if(c.colspan){
+ td.colSpan = c.colspan;
+ }
+ if(c.rowspan){
+ td.rowSpan = c.rowspan;
+ }
+ this.getRow(curRow).appendChild(td);
+ return td;
+ },
+
+
+ getNextNonSpan: function(colIndex, rowIndex){
+ var cols = this.columns;
+ while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
+ if(cols && colIndex >= cols){
+ rowIndex++;
+ colIndex = 0;
+ }else{
+ colIndex++;
+ }
+ }
+ return [colIndex, rowIndex];
+ },
+
+
+ renderItem : function(c, position, target){
+
+ if(!this.table){
+ this.table = target.createChild(
+ Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
+ }
+ if(c && !c.rendered){
+ c.render(this.getNextCell(c));
+ this.configureItem(c);
+ }else if(c && !this.isValidParent(c, target)){
+ var container = this.getNextCell(c);
+ container.insertBefore(c.getPositionEl().dom, null);
+ c.container = Ext.get(container);
+ this.configureItem(c);
+ }
+ },
+
+
+ isValidParent : function(c, target){
+ return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
+ },
+
+ destroy: function(){
+ delete this.table;
+ Ext.layout.TableLayout.superclass.destroy.call(this);
+ }
+
+
+});
+
+Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
+Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
+
+ extraCls: 'x-abs-layout-item',
+
+ type: 'absolute',
+
+ onLayout : function(ct, target){
+ target.position();
+ this.paddingLeft = target.getPadding('l');
+ this.paddingTop = target.getPadding('t');
+ Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
+ },
+
+
+ adjustWidthAnchor : function(value, comp){
+ return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
+ },
+
+
+ adjustHeightAnchor : function(value, comp){
+ return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
+ }
+
+});
+Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
+
+Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
+
+ defaultMargins : {left:0,top:0,right:0,bottom:0},
+
+ padding : '0',
+
+ pack : 'start',
+
+
+ monitorResize : true,
+ type: 'box',
+ scrollOffset : 0,
+ extraCls : 'x-box-item',
+ targetCls : 'x-box-layout-ct',
+ innerCls : 'x-box-inner',
+
+ constructor : function(config){
+ Ext.layout.BoxLayout.superclass.constructor.call(this, config);
+
+ if (Ext.isString(this.defaultMargins)) {
+ this.defaultMargins = this.parseMargins(this.defaultMargins);
+ }
+
+ var handler = this.overflowHandler;
+
+ if (typeof handler == 'string') {
+ handler = {
+ type: handler
+ };
+ }
+
+ var handlerType = 'none';
+ if (handler && handler.type != undefined) {
+ handlerType = handler.type;
+ }
+
+ var constructor = Ext.layout.boxOverflow[handlerType];
+ if (constructor[this.type]) {
+ constructor = constructor[this.type];
+ }
+
+ this.overflowHandler = new constructor(this, handler);
+ },
+
+
+ onLayout: function(container, target) {
+ Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
+
+ var tSize = this.getLayoutTargetSize(),
+ items = this.getVisibleItems(container),
+ calcs = this.calculateChildBoxes(items, tSize),
+ boxes = calcs.boxes,
+ meta = calcs.meta;
+
+
+ if (tSize.width > 0) {
+ var handler = this.overflowHandler,
+ method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';
+
+ var results = handler[method](calcs, tSize);
+
+ if (results) {
+ if (results.targetSize) {
+ tSize = results.targetSize;
+ }
+
+ if (results.recalculate) {
+ items = this.getVisibleItems(container);
+ calcs = this.calculateChildBoxes(items, tSize);
+ boxes = calcs.boxes;
+ }
+ }
+ }
+
+
+ this.layoutTargetLastSize = tSize;
+
+
+ this.childBoxCache = calcs;
+
+ this.updateInnerCtSize(tSize, calcs);
+ this.updateChildBoxes(boxes);
+
+
+ this.handleTargetOverflow(tSize, container, target);
+ },
+
+
+ updateChildBoxes: function(boxes) {
+ for (var i = 0, length = boxes.length; i < length; i++) {
+ var box = boxes[i],
+ comp = box.component;
+
+ if (box.dirtySize) {
+ comp.setSize(box.width, box.height);
+ }
+
+ if (isNaN(box.left) || isNaN(box.top)) {
+ continue;
+ }
+
+ comp.setPosition(box.left, box.top);
+ }
+ },
+
+
+ updateInnerCtSize: function(tSize, calcs) {
+ var align = this.align,
+ padding = this.padding,
+ width = tSize.width,
+ height = tSize.height;
+
+ if (this.type == 'hbox') {
+ var innerCtWidth = width,
+ innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;
+
+ if (align == 'stretch') {
+ innerCtHeight = height;
+ } else if (align == 'middle') {
+ innerCtHeight = Math.max(height, innerCtHeight);
+ }
+ } else {
+ var innerCtHeight = height,
+ innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right;
+
+ if (align == 'stretch') {
+ innerCtWidth = width;
+ } else if (align == 'center') {
+ innerCtWidth = Math.max(width, innerCtWidth);
+ }
+ }
+
+ this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
+ },
+
+
+ handleTargetOverflow: function(previousTargetSize, container, target) {
+ var overflow = target.getStyle('overflow');
+
+ if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
+ var newTargetSize = this.getLayoutTargetSize();
+ if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
+ this.adjustmentPass = true;
+ this.onLayout(container, target);
+ }
+ }
+
+ delete this.adjustmentPass;
+ },
+
+
+ isValidParent : function(c, target) {
+ return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
+ },
+
+
+ getVisibleItems: function(ct) {
+ var ct = ct || this.container,
+ t = ct.getLayoutTarget(),
+ cti = ct.items.items,
+ len = cti.length,
+
+ i, c, items = [];
+
+ for (i = 0; i < len; i++) {
+ if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){
+ items.push(c);
+ }
+ }
+
+ return items;
+ },
+
+
+ renderAll : function(ct, target) {
+ if (!this.innerCt) {
+
+ this.innerCt = target.createChild({cls:this.innerCls});
+ this.padding = this.parseMargins(this.padding);
+ }
+ Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
+ },
+
+ getLayoutTargetSize : function() {
+ var target = this.container.getLayoutTarget(), ret;
+
+ if (target) {
+ ret = target.getViewSize();
+
+
+
+
+ if (Ext.isIE9m && Ext.isStrict && ret.width == 0){
+ ret = target.getStyleSize();
+ }
+
+ ret.width -= target.getPadding('lr');
+ ret.height -= target.getPadding('tb');
+ }
+
+ return ret;
+ },
+
+
+ renderItem : function(c) {
+ if(Ext.isString(c.margins)){
+ c.margins = this.parseMargins(c.margins);
+ }else if(!c.margins){
+ c.margins = this.defaultMargins;
+ }
+ Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
+ },
+
+
+ destroy: function() {
+ Ext.destroy(this.overflowHandler);
+
+ Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
+ }
+});
+
+
+
+Ext.layout.boxOverflow.None = Ext.extend(Object, {
+ constructor: function(layout, config) {
+ this.layout = layout;
+
+ Ext.apply(this, config || {});
+ },
+
+ handleOverflow: Ext.emptyFn,
+
+ clearOverflow: Ext.emptyFn
+});
+
+
+Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;
+
+Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {
+
+ afterCls: 'x-strip-right',
+
+
+ noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
+
+ constructor: function(layout) {
+ Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);
+
+
+ this.menuItems = [];
+ },
+
+
+ createInnerElements: function() {
+ if (!this.afterCt) {
+ this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before');
+ }
+ },
+
+
+ clearOverflow: function(calculations, targetSize) {
+ var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
+ items = this.menuItems;
+
+ this.hideTrigger();
+
+ for (var index = 0, length = items.length; index < length; index++) {
+ items.pop().component.show();
+ }
+
+ return {
+ targetSize: {
+ height: targetSize.height,
+ width : newWidth
+ }
+ };
+ },
+
+
+ showTrigger: function() {
+ this.createMenu();
+ this.menuTrigger.show();
+ },
+
+
+ hideTrigger: function() {
+ if (this.menuTrigger != undefined) {
+ this.menuTrigger.hide();
+ }
+ },
+
+
+ beforeMenuShow: function(menu) {
+ var items = this.menuItems,
+ len = items.length,
+ item,
+ prev;
+
+ var needsSep = function(group, item){
+ return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
+ };
+
+ this.clearMenu();
+ menu.removeAll();
+
+ for (var i = 0; i < len; i++) {
+ item = items[i].component;
+
+ if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
+ menu.add('-');
+ }
+
+ this.addComponentToMenu(menu, item);
+ prev = item;
+ }
+
+
+ if (menu.items.length < 1) {
+ menu.add(this.noItemsMenuText);
+ }
+ },
+
+
+ createMenuConfig : function(component, hideOnClick){
+ var config = Ext.apply({}, component.initialConfig),
+ group = component.toggleGroup;
+
+ Ext.copyTo(config, component, [
+ 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
+ ]);
+
+ Ext.apply(config, {
+ text : component.overflowText || component.text,
+ hideOnClick: hideOnClick
+ });
+
+ if (group || component.enableToggle) {
+ Ext.apply(config, {
+ group : group,
+ checked: component.pressed,
+ listeners: {
+ checkchange: function(item, checked){
+ component.toggle(checked);
+ }
+ }
+ });
+ }
+
+ delete config.ownerCt;
+ delete config.xtype;
+ delete config.id;
+
+ return config;
+ },
+
+
+ addComponentToMenu : function(menu, component) {
+ if (component instanceof Ext.Toolbar.Separator) {
+ menu.add('-');
+
+ } else if (Ext.isFunction(component.isXType)) {
+ if (component.isXType('splitbutton')) {
+ menu.add(this.createMenuConfig(component, true));
+
+ } else if (component.isXType('button')) {
+ menu.add(this.createMenuConfig(component, !component.menu));
+
+ } else if (component.isXType('buttongroup')) {
+ component.items.each(function(item){
+ this.addComponentToMenu(menu, item);
+ }, this);
+ }
+ }
+ },
+
+
+ clearMenu : function(){
+ var menu = this.moreMenu;
+ if (menu && menu.items) {
+ menu.items.each(function(item){
+ delete item.menu;
+ });
+ }
+ },
+
+
+ createMenu: function() {
+ if (!this.menuTrigger) {
+ this.createInnerElements();
+
+
+ this.menu = new Ext.menu.Menu({
+ ownerCt : this.layout.container,
+ listeners: {
+ scope: this,
+ beforeshow: this.beforeMenuShow
+ }
+ });
+
+
+ this.menuTrigger = new Ext.Button({
+ iconCls : 'x-toolbar-more-icon',
+ cls : 'x-toolbar-more',
+ menu : this.menu,
+ renderTo: this.afterCt
+ });
+ }
+ },
+
+
+ destroy: function() {
+ Ext.destroy(this.menu, this.menuTrigger);
+ }
+});
+
+Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;
+
+
+
+Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {
+
+ constructor: function() {
+ Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);
+
+ var me = this,
+ layout = me.layout,
+ origFunction = layout.calculateChildBoxes;
+
+ layout.calculateChildBoxes = function(visibleItems, targetSize) {
+ var calcs = origFunction.apply(layout, arguments),
+ meta = calcs.meta,
+ items = me.menuItems;
+
+
+
+ var hiddenWidth = 0;
+ for (var index = 0, length = items.length; index < length; index++) {
+ hiddenWidth += items[index].width;
+ }
+
+ meta.minimumWidth += hiddenWidth;
+ meta.tooNarrow = meta.minimumWidth > targetSize.width;
+
+ return calcs;
+ };
+ },
+
+ handleOverflow: function(calculations, targetSize) {
+ this.showTrigger();
+
+ var newWidth = targetSize.width - this.afterCt.getWidth(),
+ boxes = calculations.boxes,
+ usedWidth = 0,
+ recalculate = false;
+
+
+ for (var index = 0, length = boxes.length; index < length; index++) {
+ usedWidth += boxes[index].width;
+ }
+
+ var spareWidth = newWidth - usedWidth,
+ showCount = 0;
+
+
+ for (var index = 0, length = this.menuItems.length; index < length; index++) {
+ var hidden = this.menuItems[index],
+ comp = hidden.component,
+ width = hidden.width;
+
+ if (width < spareWidth) {
+ comp.show();
+
+ spareWidth -= width;
+ showCount ++;
+ recalculate = true;
+ } else {
+ break;
+ }
+ }
+
+ if (recalculate) {
+ this.menuItems = this.menuItems.slice(showCount);
+ } else {
+ for (var i = boxes.length - 1; i >= 0; i--) {
+ var item = boxes[i].component,
+ right = boxes[i].left + boxes[i].width;
+
+ if (right >= newWidth) {
+ this.menuItems.unshift({
+ component: item,
+ width : boxes[i].width
+ });
+
+ item.hide();
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (this.menuItems.length == 0) {
+ this.hideTrigger();
+ }
+
+ return {
+ targetSize: {
+ height: targetSize.height,
+ width : newWidth
+ },
+ recalculate: recalculate
+ };
+ }
+});
+
+Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
+Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
+
+ animateScroll: true,
+
+
+ scrollIncrement: 100,
+
+
+ wheelIncrement: 3,
+
+
+ scrollRepeatInterval: 400,
+
+
+ scrollDuration: 0.4,
+
+
+ beforeCls: 'x-strip-left',
+
+
+ afterCls: 'x-strip-right',
+
+
+ scrollerCls: 'x-strip-scroller',
+
+
+ beforeScrollerCls: 'x-strip-scroller-left',
+
+
+ afterScrollerCls: 'x-strip-scroller-right',
+
+
+ createWheelListener: function() {
+ this.layout.innerCt.on({
+ scope : this,
+ mousewheel: function(e) {
+ e.stopEvent();
+
+ this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
+ }
+ });
+ },
+
+
+ handleOverflow: function(calculations, targetSize) {
+ this.createInnerElements();
+ this.showScrollers();
+ },
+
+
+ clearOverflow: function() {
+ this.hideScrollers();
+ },
+
+
+ showScrollers: function() {
+ this.createScrollers();
+
+ this.beforeScroller.show();
+ this.afterScroller.show();
+
+ this.updateScrollButtons();
+ },
+
+
+ hideScrollers: function() {
+ if (this.beforeScroller != undefined) {
+ this.beforeScroller.hide();
+ this.afterScroller.hide();
+ }
+ },
+
+
+ createScrollers: function() {
+ if (!this.beforeScroller && !this.afterScroller) {
+ var before = this.beforeCt.createChild({
+ cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
+ });
+
+ var after = this.afterCt.createChild({
+ cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
+ });
+
+ before.addClassOnOver(this.beforeScrollerCls + '-hover');
+ after.addClassOnOver(this.afterScrollerCls + '-hover');
+
+ before.setVisibilityMode(Ext.Element.DISPLAY);
+ after.setVisibilityMode(Ext.Element.DISPLAY);
+
+ this.beforeRepeater = new Ext.util.ClickRepeater(before, {
+ interval: this.scrollRepeatInterval,
+ handler : this.scrollLeft,
+ scope : this
+ });
+
+ this.afterRepeater = new Ext.util.ClickRepeater(after, {
+ interval: this.scrollRepeatInterval,
+ handler : this.scrollRight,
+ scope : this
+ });
+
+
+ this.beforeScroller = before;
+
+
+ this.afterScroller = after;
+ }
+ },
+
+
+ destroy: function() {
+ Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
+ },
+
+
+ scrollBy: function(delta, animate) {
+ this.scrollTo(this.getScrollPosition() + delta, animate);
+ },
+
+
+ getItem: function(item) {
+ if (Ext.isString(item)) {
+ item = Ext.getCmp(item);
+ } else if (Ext.isNumber(item)) {
+ item = this.items[item];
+ }
+
+ return item;
+ },
+
+
+ getScrollAnim: function() {
+ return {
+ duration: this.scrollDuration,
+ callback: this.updateScrollButtons,
+ scope : this
+ };
+ },
+
+
+ updateScrollButtons: function() {
+ if (this.beforeScroller == undefined || this.afterScroller == undefined) {
+ return;
+ }
+
+ var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass',
+ afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass',
+ beforeCls = this.beforeScrollerCls + '-disabled',
+ afterCls = this.afterScrollerCls + '-disabled';
+
+ this.beforeScroller[beforeMeth](beforeCls);
+ this.afterScroller[afterMeth](afterCls);
+ this.scrolling = false;
+ },
+
+
+ atExtremeBefore: function() {
+ return this.getScrollPosition() === 0;
+ },
+
+
+ scrollLeft: function(animate) {
+ this.scrollBy(-this.scrollIncrement, animate);
+ },
+
+
+ scrollRight: function(animate) {
+ this.scrollBy(this.scrollIncrement, animate);
+ },
+
+
+ scrollToItem: function(item, animate) {
+ item = this.getItem(item);
+
+ if (item != undefined) {
+ var visibility = this.getItemVisibility(item);
+
+ if (!visibility.fullyVisible) {
+ var box = item.getBox(true, true),
+ newX = box.x;
+
+ if (visibility.hiddenRight) {
+ newX -= (this.layout.innerCt.getWidth() - box.width);
+ }
+
+ this.scrollTo(newX, animate);
+ }
+ }
+ },
+
+
+ getItemVisibility: function(item) {
+ var box = this.getItem(item).getBox(true, true),
+ itemLeft = box.x,
+ itemRight = box.x + box.width,
+ scrollLeft = this.getScrollPosition(),
+ scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
+
+ return {
+ hiddenLeft : itemLeft < scrollLeft,
+ hiddenRight : itemRight > scrollRight,
+ fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
+ };
+ }
+});
+
+Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
+
+
+
+Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
+ scrollIncrement: 75,
+ wheelIncrement : 2,
+
+ handleOverflow: function(calculations, targetSize) {
+ Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
+
+ return {
+ targetSize: {
+ height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
+ width : targetSize.width
+ }
+ };
+ },
+
+
+ createInnerElements: function() {
+ var target = this.layout.innerCt;
+
+
+
+ if (!this.beforeCt) {
+ this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
+ this.afterCt = target.insertSibling({cls: this.afterCls}, 'after');
+
+ this.createWheelListener();
+ }
+ },
+
+
+ scrollTo: function(position, animate) {
+ var oldPosition = this.getScrollPosition(),
+ newPosition = position.constrain(0, this.getMaxScrollBottom());
+
+ if (newPosition != oldPosition && !this.scrolling) {
+ if (animate == undefined) {
+ animate = this.animateScroll;
+ }
+
+ this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);
+
+ if (animate) {
+ this.scrolling = true;
+ } else {
+ this.scrolling = false;
+ this.updateScrollButtons();
+ }
+ }
+ },
+
+
+ getScrollPosition: function(){
+ return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
+ },
+
+
+ getMaxScrollBottom: function() {
+ return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
+ },
+
+
+ atExtremeAfter: function() {
+ return this.getScrollPosition() >= this.getMaxScrollBottom();
+ }
+});
+
+Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
+
+
+
+Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
+ handleOverflow: function(calculations, targetSize) {
+ Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
+
+ return {
+ targetSize: {
+ height: targetSize.height,
+ width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
+ }
+ };
+ },
+
+
+ createInnerElements: function() {
+ var target = this.layout.innerCt;
+
+
+
+ if (!this.beforeCt) {
+ this.afterCt = target.insertSibling({cls: this.afterCls}, 'before');
+ this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
+
+ this.createWheelListener();
+ }
+ },
+
+
+ scrollTo: function(position, animate) {
+ var oldPosition = this.getScrollPosition(),
+ newPosition = position.constrain(0, this.getMaxScrollRight());
+
+ if (newPosition != oldPosition && !this.scrolling) {
+ if (animate == undefined) {
+ animate = this.animateScroll;
+ }
+
+ this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);
+
+ if (animate) {
+ this.scrolling = true;
+ } else {
+ this.scrolling = false;
+ this.updateScrollButtons();
+ }
+ }
+ },
+
+
+ getScrollPosition: function(){
+ return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
+ },
+
+
+ getMaxScrollRight: function() {
+ return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
+ },
+
+
+ atExtremeAfter: function() {
+ return this.getScrollPosition() >= this.getMaxScrollRight();
+ }
+});
+
+Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
+Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
+
+ align: 'top',
+
+ type : 'hbox',
+
+
+
+
+
+ calculateChildBoxes: function(visibleItems, targetSize) {
+ var visibleCount = visibleItems.length,
+
+ padding = this.padding,
+ topOffset = padding.top,
+ leftOffset = padding.left,
+ paddingVert = topOffset + padding.bottom,
+ paddingHoriz = leftOffset + padding.right,
+
+ width = targetSize.width - this.scrollOffset,
+ height = targetSize.height,
+ availHeight = Math.max(0, height - paddingVert),
+
+ isStart = this.pack == 'start',
+ isCenter = this.pack == 'center',
+ isEnd = this.pack == 'end',
+
+ nonFlexWidth = 0,
+ maxHeight = 0,
+ totalFlex = 0,
+ desiredWidth = 0,
+ minimumWidth = 0,
+
+
+ boxes = [],
+
+
+ child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
+ horizMargins, vertMargins, stretchHeight;
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ childHeight = child.height;
+ childWidth = child.width;
+ canLayout = !child.hasLayout && typeof child.doLayout == 'function';
+
+
+ if (typeof childWidth != 'number') {
+
+
+ if (child.flex && !childWidth) {
+ totalFlex += child.flex;
+
+
+ } else {
+
+
+ if (!childWidth && canLayout) {
+ child.doLayout();
+ }
+
+ childSize = child.getSize();
+ childWidth = childSize.width;
+ childHeight = childSize.height;
+ }
+ }
+
+ childMargins = child.margins;
+ horizMargins = childMargins.left + childMargins.right;
+
+ nonFlexWidth += horizMargins + (childWidth || 0);
+ desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
+ minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
+
+
+ if (typeof childHeight != 'number') {
+ if (canLayout) {
+ child.doLayout();
+ }
+ childHeight = child.getHeight();
+ }
+
+ maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
+
+
+ boxes.push({
+ component: child,
+ height : childHeight || undefined,
+ width : childWidth || undefined
+ });
+ }
+
+ var shortfall = desiredWidth - width,
+ tooNarrow = minimumWidth > width;
+
+
+ var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
+
+ if (tooNarrow) {
+ for (i = 0; i < visibleCount; i++) {
+ boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
+ }
+ } else {
+
+
+ if (shortfall > 0) {
+ var minWidths = [];
+
+
+
+
+ for (var index = 0, length = visibleCount; index < length; index++) {
+ var item = visibleItems[index],
+ minWidth = item.minWidth || 0;
+
+
+
+ if (item.flex) {
+ boxes[index].width = minWidth;
+ } else {
+ minWidths.push({
+ minWidth : minWidth,
+ available: boxes[index].width - minWidth,
+ index : index
+ });
+ }
+ }
+
+
+ minWidths.sort(function(a, b) {
+ return a.available > b.available ? 1 : -1;
+ });
+
+
+ for (var i = 0, length = minWidths.length; i < length; i++) {
+ var itemIndex = minWidths[i].index;
+
+ if (itemIndex == undefined) {
+ continue;
+ }
+
+ var item = visibleItems[itemIndex],
+ box = boxes[itemIndex],
+ oldWidth = box.width,
+ minWidth = item.minWidth,
+ newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
+ reduction = oldWidth - newWidth;
+
+ boxes[itemIndex].width = newWidth;
+ shortfall -= reduction;
+ }
+ } else {
+
+ var remainingWidth = availableWidth,
+ remainingFlex = totalFlex;
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ calcs = boxes[i];
+
+ childMargins = child.margins;
+ vertMargins = childMargins.top + childMargins.bottom;
+
+ if (isStart && child.flex && !child.width) {
+ flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
+ remainingWidth -= flexedWidth;
+ remainingFlex -= child.flex;
+
+ calcs.width = flexedWidth;
+ calcs.dirtySize = true;
+ }
+ }
+ }
+ }
+
+ if (isCenter) {
+ leftOffset += availableWidth / 2;
+ } else if (isEnd) {
+ leftOffset += availableWidth;
+ }
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ calcs = boxes[i];
+
+ childMargins = child.margins;
+ leftOffset += childMargins.left;
+ vertMargins = childMargins.top + childMargins.bottom;
+
+ calcs.left = leftOffset;
+ calcs.top = topOffset + childMargins.top;
+
+ switch (this.align) {
+ case 'stretch':
+ stretchHeight = availHeight - vertMargins;
+ calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
+ calcs.dirtySize = true;
+ break;
+ case 'stretchmax':
+ stretchHeight = maxHeight - vertMargins;
+ calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
+ calcs.dirtySize = true;
+ break;
+ case 'middle':
+ var diff = availHeight - calcs.height - vertMargins;
+ if (diff > 0) {
+ calcs.top = topOffset + vertMargins + (diff / 2);
+ }
+ }
+
+ leftOffset += calcs.width + childMargins.right;
+ }
+
+ return {
+ boxes: boxes,
+ meta : {
+ maxHeight : maxHeight,
+ nonFlexWidth: nonFlexWidth,
+ desiredWidth: desiredWidth,
+ minimumWidth: minimumWidth,
+ shortfall : desiredWidth - width,
+ tooNarrow : tooNarrow
+ }
+ };
+ }
+});
+
+Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
+Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
+
+ align : 'left',
+ type: 'vbox',
+
+
+
+
+
+
+ calculateChildBoxes: function(visibleItems, targetSize) {
+ var visibleCount = visibleItems.length,
+
+ padding = this.padding,
+ topOffset = padding.top,
+ leftOffset = padding.left,
+ paddingVert = topOffset + padding.bottom,
+ paddingHoriz = leftOffset + padding.right,
+
+ width = targetSize.width - this.scrollOffset,
+ height = targetSize.height,
+ availWidth = Math.max(0, width - paddingHoriz),
+
+ isStart = this.pack == 'start',
+ isCenter = this.pack == 'center',
+ isEnd = this.pack == 'end',
+
+ nonFlexHeight= 0,
+ maxWidth = 0,
+ totalFlex = 0,
+ desiredHeight= 0,
+ minimumHeight= 0,
+
+
+ boxes = [],
+
+
+ child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight,
+ horizMargins, vertMargins, stretchWidth, length;
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ childHeight = child.height;
+ childWidth = child.width;
+ canLayout = !child.hasLayout && typeof child.doLayout == 'function';
+
+
+ if (typeof childHeight != 'number') {
+
+
+ if (child.flex && !childHeight) {
+ totalFlex += child.flex;
+
+
+ } else {
+
+
+ if (!childHeight && canLayout) {
+ child.doLayout();
+ }
+
+ childSize = child.getSize();
+ childWidth = childSize.width;
+ childHeight = childSize.height;
+ }
+ }
+
+ childMargins = child.margins;
+ vertMargins = childMargins.top + childMargins.bottom;
+
+ nonFlexHeight += vertMargins + (childHeight || 0);
+ desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
+ minimumHeight += vertMargins + (child.minHeight || childHeight || 0);
+
+
+ if (typeof childWidth != 'number') {
+ if (canLayout) {
+ child.doLayout();
+ }
+ childWidth = child.getWidth();
+ }
+
+ maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
+
+
+ boxes.push({
+ component: child,
+ height : childHeight || undefined,
+ width : childWidth || undefined
+ });
+ }
+
+ var shortfall = desiredHeight - height,
+ tooNarrow = minimumHeight > height;
+
+
+ var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
+
+ if (tooNarrow) {
+ for (i = 0, length = visibleCount; i < length; i++) {
+ boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
+ }
+ } else {
+
+
+ if (shortfall > 0) {
+ var minHeights = [];
+
+
+
+
+ for (var index = 0, length = visibleCount; index < length; index++) {
+ var item = visibleItems[index],
+ minHeight = item.minHeight || 0;
+
+
+
+ if (item.flex) {
+ boxes[index].height = minHeight;
+ } else {
+ minHeights.push({
+ minHeight: minHeight,
+ available: boxes[index].height - minHeight,
+ index : index
+ });
+ }
+ }
+
+
+ minHeights.sort(function(a, b) {
+ return a.available > b.available ? 1 : -1;
+ });
+
+
+ for (var i = 0, length = minHeights.length; i < length; i++) {
+ var itemIndex = minHeights[i].index;
+
+ if (itemIndex == undefined) {
+ continue;
+ }
+
+ var item = visibleItems[itemIndex],
+ box = boxes[itemIndex],
+ oldHeight = box.height,
+ minHeight = item.minHeight,
+ newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
+ reduction = oldHeight - newHeight;
+
+ boxes[itemIndex].height = newHeight;
+ shortfall -= reduction;
+ }
+ } else {
+
+ var remainingHeight = availableHeight,
+ remainingFlex = totalFlex;
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ calcs = boxes[i];
+
+ childMargins = child.margins;
+ horizMargins = childMargins.left + childMargins.right;
+
+ if (isStart && child.flex && !child.height) {
+ flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
+ remainingHeight -= flexedHeight;
+ remainingFlex -= child.flex;
+
+ calcs.height = flexedHeight;
+ calcs.dirtySize = true;
+ }
+ }
+ }
+ }
+
+ if (isCenter) {
+ topOffset += availableHeight / 2;
+ } else if (isEnd) {
+ topOffset += availableHeight;
+ }
+
+
+ for (i = 0; i < visibleCount; i++) {
+ child = visibleItems[i];
+ calcs = boxes[i];
+
+ childMargins = child.margins;
+ topOffset += childMargins.top;
+ horizMargins = childMargins.left + childMargins.right;
+
+
+ calcs.left = leftOffset + childMargins.left;
+ calcs.top = topOffset;
+
+ switch (this.align) {
+ case 'stretch':
+ stretchWidth = availWidth - horizMargins;
+ calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
+ calcs.dirtySize = true;
+ break;
+ case 'stretchmax':
+ stretchWidth = maxWidth - horizMargins;
+ calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
+ calcs.dirtySize = true;
+ break;
+ case 'center':
+ var diff = availWidth - calcs.width - horizMargins;
+ if (diff > 0) {
+ calcs.left = leftOffset + horizMargins + (diff / 2);
+ }
+ }
+
+ topOffset += calcs.height + childMargins.bottom;
+ }
+
+ return {
+ boxes: boxes,
+ meta : {
+ maxWidth : maxWidth,
+ nonFlexHeight: nonFlexHeight,
+ desiredHeight: desiredHeight,
+ minimumHeight: minimumHeight,
+ shortfall : desiredHeight - height,
+ tooNarrow : tooNarrow
+ }
+ };
+ }
+});
+
+Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
+
+Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
+ monitorResize : true,
+
+ type: 'toolbar',
+
+
+ triggerWidth: 18,
+
+
+ noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
+
+
+ lastOverflow: false,
+
+
+ tableHTML: [
+ '<table cellspacing="0" class="x-toolbar-ct">',
+ '<tbody>',
+ '<tr>',
+ '<td class="x-toolbar-left" align="{0}">',
+ '<table cellspacing="0">',
+ '<tbody>',
+ '<tr class="x-toolbar-left-row"></tr>',
+ '</tbody>',
+ '</table>',
+ '</td>',
+ '<td class="x-toolbar-right" align="right">',
+ '<table cellspacing="0" class="x-toolbar-right-ct">',
+ '<tbody>',
+ '<tr>',
+ '<td>',
+ '<table cellspacing="0">',
+ '<tbody>',
+ '<tr class="x-toolbar-right-row"></tr>',
+ '</tbody>',
+ '</table>',
+ '</td>',
+ '<td>',
+ '<table cellspacing="0">',
+ '<tbody>',
+ '<tr class="x-toolbar-extras-row"></tr>',
+ '</tbody>',
+ '</table>',
+ '</td>',
+ '</tr>',
+ '</tbody>',
+ '</table>',
+ '</td>',
+ '</tr>',
+ '</tbody>',
+ '</table>'
+ ].join(""),
+
+
+ onLayout : function(ct, target) {
+
+ if (!this.leftTr) {
+ var align = ct.buttonAlign == 'center' ? 'center' : 'left';
+
+ target.addClass('x-toolbar-layout-ct');
+ target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
+
+ this.leftTr = target.child('tr.x-toolbar-left-row', true);
+ this.rightTr = target.child('tr.x-toolbar-right-row', true);
+ this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
+
+ if (this.hiddenItem == undefined) {
+
+ this.hiddenItems = [];
+ }
+ }
+
+ var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
+ items = ct.items.items,
+ position = 0;
+
+
+ for (var i = 0, len = items.length, c; i < len; i++, position++) {
+ c = items[i];
+
+ if (c.isFill) {
+ side = this.rightTr;
+ position = -1;
+ } else if (!c.rendered) {
+ c.render(this.insertCell(c, side, position));
+ this.configureItem(c);
+ } else {
+ if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
+ var td = this.insertCell(c, side, position);
+ td.appendChild(c.getPositionEl().dom);
+ c.container = Ext.get(td);
+ }
+ }
+ }
+
+
+ this.cleanup(this.leftTr);
+ this.cleanup(this.rightTr);
+ this.cleanup(this.extrasTr);
+ this.fitToSize(target);
+ },
+
+
+ cleanup : function(el) {
+ var cn = el.childNodes, i, c;
+
+ for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
+ if (!c.firstChild) {
+ el.removeChild(c);
+ }
+ }
+ },
+
+
+ insertCell : function(c, target, position) {
+ var td = document.createElement('td');
+ td.className = 'x-toolbar-cell';
+
+ target.insertBefore(td, target.childNodes[position] || null);
+
+ return td;
+ },
+
+
+ hideItem : function(item) {
+ this.hiddenItems.push(item);
+
+ item.xtbHidden = true;
+ item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
+ item.hide();
+ },
+
+
+ unhideItem : function(item) {
+ item.show();
+ item.xtbHidden = false;
+ this.hiddenItems.remove(item);
+ },
+
+
+ getItemWidth : function(c) {
+ return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
+ },
+
+
+ fitToSize : function(target) {
+ if (this.container.enableOverflow === false) {
+ return;
+ }
+
+ var width = target.dom.clientWidth,
+ tableWidth = target.dom.firstChild.offsetWidth,
+ clipWidth = width - this.triggerWidth,
+ lastWidth = this.lastWidth || 0,
+
+ hiddenItems = this.hiddenItems,
+ hasHiddens = hiddenItems.length != 0,
+ isLarger = width >= lastWidth;
+
+ this.lastWidth = width;
+
+ if (tableWidth > width || (hasHiddens && isLarger)) {
+ var items = this.container.items.items,
+ len = items.length,
+ loopWidth = 0,
+ item;
+
+ for (var i = 0; i < len; i++) {
+ item = items[i];
+
+ if (!item.isFill) {
+ loopWidth += this.getItemWidth(item);
+ if (loopWidth > clipWidth) {
+ if (!(item.hidden || item.xtbHidden)) {
+ this.hideItem(item);
+ }
+ } else if (item.xtbHidden) {
+ this.unhideItem(item);
+ }
+ }
+ }
+ }
+
+
+ hasHiddens = hiddenItems.length != 0;
+
+ if (hasHiddens) {
+ this.initMore();
+
+ if (!this.lastOverflow) {
+ this.container.fireEvent('overflowchange', this.container, true);
+ this.lastOverflow = true;
+ }
+ } else if (this.more) {
+ this.clearMenu();
+ this.more.destroy();
+ delete this.more;
+
+ if (this.lastOverflow) {
+ this.container.fireEvent('overflowchange', this.container, false);
+ this.lastOverflow = false;
+ }
+ }
+ },
+
+
+ createMenuConfig : function(component, hideOnClick){
+ var config = Ext.apply({}, component.initialConfig),
+ group = component.toggleGroup;
+
+ Ext.copyTo(config, component, [
+ 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
+ ]);
+
+ Ext.apply(config, {
+ text : component.overflowText || component.text,
+ hideOnClick: hideOnClick
+ });
+
+ if (group || component.enableToggle) {
+ Ext.apply(config, {
+ group : group,
+ checked: component.pressed,
+ listeners: {
+ checkchange: function(item, checked){
+ component.toggle(checked);
+ }
+ }
+ });
+ }
+
+ delete config.ownerCt;
+ delete config.xtype;
+ delete config.id;
+
+ return config;
+ },
+
+
+ addComponentToMenu : function(menu, component) {
+ if (component instanceof Ext.Toolbar.Separator) {
+ menu.add('-');
+
+ } else if (Ext.isFunction(component.isXType)) {
+ if (component.isXType('splitbutton')) {
+ menu.add(this.createMenuConfig(component, true));
+
+ } else if (component.isXType('button')) {
+ menu.add(this.createMenuConfig(component, !component.menu));
+
+ } else if (component.isXType('buttongroup')) {
+ component.items.each(function(item){
+ this.addComponentToMenu(menu, item);
+ }, this);
+ }
+ }
+ },
+
+
+ clearMenu : function(){
+ var menu = this.moreMenu;
+ if (menu && menu.items) {
+ menu.items.each(function(item){
+ delete item.menu;
+ });
+ }
+ },
+
+
+ beforeMoreShow : function(menu) {
+ var items = this.container.items.items,
+ len = items.length,
+ item,
+ prev;
+
+ var needsSep = function(group, item){
+ return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
+ };
+
+ this.clearMenu();
+ menu.removeAll();
+ for (var i = 0; i < len; i++) {
+ item = items[i];
+ if (item.xtbHidden) {
+ if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
+ menu.add('-');
+ }
+ this.addComponentToMenu(menu, item);
+ prev = item;
+ }
+ }
+
+
+ if (menu.items.length < 1) {
+ menu.add(this.noItemsMenuText);
+ }
+ },
+
+
+ initMore : function(){
+ if (!this.more) {
+
+ this.moreMenu = new Ext.menu.Menu({
+ ownerCt : this.container,
+ listeners: {
+ beforeshow: this.beforeMoreShow,
+ scope: this
+ }
+ });
+
+
+ this.more = new Ext.Button({
+ iconCls: 'x-toolbar-more-icon',
+ cls : 'x-toolbar-more',
+ menu : this.moreMenu,
+ ownerCt: this.container
+ });
+
+ var td = this.insertCell(this.more, this.extrasTr, 100);
+ this.more.render(td);
+ }
+ },
+
+ destroy : function(){
+ Ext.destroy(this.more, this.moreMenu);
+ delete this.leftTr;
+ delete this.rightTr;
+ delete this.extrasTr;
+ Ext.layout.ToolbarLayout.superclass.destroy.call(this);
+ }
+});
+
+Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
+
+ Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
+ monitorResize : true,
+
+ type: 'menu',
+
+ setContainer : function(ct){
+ this.monitorResize = !ct.floating;
+
+
+ ct.on('autosize', this.doAutoSize, this);
+ Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
+ },
+
+ renderItem : function(c, position, target){
+ if (!this.itemTpl) {
+ this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
+ '<li id="{itemId}" class="{itemCls}">',
+ '<tpl if="needsIcon">',
+ '<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
+ '</tpl>',
+ '</li>'
+ );
+ }
+
+ if(c && !c.rendered){
+ if(Ext.isNumber(position)){
+ position = target.dom.childNodes[position];
+ }
+ var a = this.getItemArgs(c);
+
+
+ c.render(c.positionEl = position ?
+ this.itemTpl.insertBefore(position, a, true) :
+ this.itemTpl.append(target, a, true));
+
+
+ c.positionEl.menuItemId = c.getItemId();
+
+
+
+ if (!a.isMenuItem && a.needsIcon) {
+ c.positionEl.addClass('x-menu-list-item-indent');
+ }
+ this.configureItem(c);
+ }else if(c && !this.isValidParent(c, target)){
+ if(Ext.isNumber(position)){
+ position = target.dom.childNodes[position];
+ }
+ target.dom.insertBefore(c.getActionEl().dom, position || null);
+ }
+ },
+
+ getItemArgs : function(c) {
+ var isMenuItem = c instanceof Ext.menu.Item,
+ canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);
+
+ return {
+ isMenuItem: isMenuItem,
+ needsIcon: canHaveIcon && (c.icon || c.iconCls),
+ icon: c.icon || Ext.BLANK_IMAGE_URL,
+ iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
+ itemId: 'x-menu-el-' + c.id,
+ itemCls: 'x-menu-list-item ',
+ altText: c.altText || ''
+ };
+ },
+
+
+ isValidParent : function(c, target) {
+ return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
+ },
+
+ onLayout : function(ct, target){
+ Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
+ this.doAutoSize();
+ },
+
+ doAutoSize : function(){
+ var ct = this.container, w = ct.width;
+ if(ct.floating){
+ if(w){
+ ct.setWidth(w);
+ }else if(Ext.isIE9m){
+ ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8 || Ext.isIE9) ? 'auto' : ct.minWidth);
+ var el = ct.getEl(), t = el.dom.offsetWidth;
+ ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
+ }
+ }
+ }
+});
+Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
+
+Ext.Viewport = Ext.extend(Ext.Container, {
+
+
+
+
+
+
+
+
+
+
+
+
+ initComponent : function() {
+ Ext.Viewport.superclass.initComponent.call(this);
+ document.getElementsByTagName('html')[0].className += ' x-viewport';
+ this.el = Ext.getBody();
+ this.el.setHeight = Ext.emptyFn;
+ this.el.setWidth = Ext.emptyFn;
+ this.el.setSize = Ext.emptyFn;
+ this.el.dom.scroll = 'no';
+ this.allowDomMove = false;
+ this.autoWidth = true;
+ this.autoHeight = true;
+ Ext.EventManager.onWindowResize(this.fireResize, this);
+ this.renderTo = this.el;
+ },
+
+ fireResize : function(w, h){
+ this.fireEvent('resize', this, w, h, w, h);
+ }
+});
+Ext.reg('viewport', Ext.Viewport);
+
+Ext.Panel = Ext.extend(Ext.Container, {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ baseCls : 'x-panel',
+
+ collapsedCls : 'x-panel-collapsed',
+
+ maskDisabled : true,
+
+ animCollapse : Ext.enableFx,
+
+ headerAsText : true,
+
+ buttonAlign : 'right',
+
+ collapsed : false,
+
+ collapseFirst : true,
+
+ minButtonWidth : 75,
+
+
+ elements : 'body',
+
+ preventBodyReset : false,
+
+
+ padding: undefined,
+
+
+ resizeEvent: 'bodyresize',
+
+
+
+
+ toolTarget : 'header',
+ collapseEl : 'bwrap',
+ slideAnchor : 't',
+ disabledClass : '',
+
+
+ deferHeight : true,
+
+ expandDefaults: {
+ duration : 0.25
+ },
+
+ collapseDefaults : {
+ duration : 0.25
+ },
+
+
+ initComponent : function(){
+ Ext.Panel.superclass.initComponent.call(this);
+
+ this.addEvents(
+
+ 'bodyresize',
+
+ 'titlechange',
+
+ 'iconchange',
+
+ 'collapse',
+
+ 'expand',
+
+ 'beforecollapse',
+
+ 'beforeexpand',
+
+ 'beforeclose',
+
+ 'close',
+
+ 'activate',
+
+ 'deactivate'
+ );
+
+ if(this.unstyled){
+ this.baseCls = 'x-plain';
+ }
+
+
+ this.toolbars = [];
+
+ if(this.tbar){
+ this.elements += ',tbar';
+ this.topToolbar = this.createToolbar(this.tbar);
+ this.tbar = null;
+
+ }
+ if(this.bbar){
+ this.elements += ',bbar';
+ this.bottomToolbar = this.createToolbar(this.bbar);
+ this.bbar = null;
+ }
+
+ if(this.header === true){
+ this.elements += ',header';
+ this.header = null;
+ }else if(this.headerCfg || (this.title && this.header !== false)){
+ this.elements += ',header';
+ }
+
+ if(this.footerCfg || this.footer === true){
+ this.elements += ',footer';
+ this.footer = null;
+ }
+
+ if(this.buttons){
+ this.fbar = this.buttons;
+ this.buttons = null;
+ }
+ if(this.fbar){
+ this.createFbar(this.fbar);
+ }
+ if(this.autoLoad){
+ this.on('render', this.doAutoLoad, this, {delay:10});
+ }
+ },
+
+
+ createFbar : function(fbar){
+ var min = this.minButtonWidth;
+ this.elements += ',footer';
+ this.fbar = this.createToolbar(fbar, {
+ buttonAlign: this.buttonAlign,
+ toolbarCls: 'x-panel-fbar',
+ enableOverflow: false,
+ defaults: function(c){
+ return {
+ minWidth: c.minWidth || min
+ };
+ }
+ });
+
+
+
+ this.fbar.items.each(function(c){
+ c.minWidth = c.minWidth || this.minButtonWidth;
+ }, this);
+ this.buttons = this.fbar.items.items;
+ },
+
+
+ createToolbar: function(tb, options){
+ var result;
+
+ if(Ext.isArray(tb)){
+ tb = {
+ items: tb
+ };
+ }
+ result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
+ this.toolbars.push(result);
+ return result;
+ },
+
+
+ createElement : function(name, pnode){
+ if(this[name]){
+ pnode.appendChild(this[name].dom);
+ return;
+ }
+
+ if(name === 'bwrap' || this.elements.indexOf(name) != -1){
+ if(this[name+'Cfg']){
+ this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
+ }else{
+ var el = document.createElement('div');
+ el.className = this[name+'Cls'];
+ this[name] = Ext.get(pnode.appendChild(el));
+ }
+ if(this[name+'CssClass']){
+ this[name].addClass(this[name+'CssClass']);
+ }
+ if(this[name+'Style']){
+ this[name].applyStyles(this[name+'Style']);
+ }
+ }
+ },
+
+
+ onRender : function(ct, position){
+ Ext.Panel.superclass.onRender.call(this, ct, position);
+ this.createClasses();
+
+ var el = this.el,
+ d = el.dom,
+ bw,
+ ts;
+
+
+ if(this.collapsible && !this.hideCollapseTool){
+ this.tools = this.tools ? this.tools.slice(0) : [];
+ this.tools[this.collapseFirst?'unshift':'push']({
+ id: 'toggle',
+ handler : this.toggleCollapse,
+ scope: this
+ });
+ }
+
+ if(this.tools){
+ ts = this.tools;
+ this.elements += (this.header !== false) ? ',header' : '';
+ }
+ this.tools = {};
+
+ el.addClass(this.baseCls);
+ if(d.firstChild){
+ this.header = el.down('.'+this.headerCls);
+ this.bwrap = el.down('.'+this.bwrapCls);
+ var cp = this.bwrap ? this.bwrap : el;
+ this.tbar = cp.down('.'+this.tbarCls);
+ this.body = cp.down('.'+this.bodyCls);
+ this.bbar = cp.down('.'+this.bbarCls);
+ this.footer = cp.down('.'+this.footerCls);
+ this.fromMarkup = true;
+ }
+ if (this.preventBodyReset === true) {
+ el.addClass('x-panel-reset');
+ }
+ if(this.cls){
+ el.addClass(this.cls);
+ }
+
+ if(this.buttons){
+ this.elements += ',footer';
+ }
+
+
+
+
+ if(this.frame){
+ el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
+
+ this.createElement('header', d.firstChild.firstChild.firstChild);
+ this.createElement('bwrap', d);
+
+
+ bw = this.bwrap.dom;
+ var ml = d.childNodes[1], bl = d.childNodes[2];
+ bw.appendChild(ml);
+ bw.appendChild(bl);
+
+ var mc = bw.firstChild.firstChild.firstChild;
+ this.createElement('tbar', mc);
+ this.createElement('body', mc);
+ this.createElement('bbar', mc);
+ this.createElement('footer', bw.lastChild.firstChild.firstChild);
+
+ if(!this.footer){
+ this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
+ }
+
+ this.ft = Ext.get(this.bwrap.dom.lastChild);
+ this.mc = Ext.get(mc);
+ }else{
+ this.createElement('header', d);
+ this.createElement('bwrap', d);
+
+
+ bw = this.bwrap.dom;
+ this.createElement('tbar', bw);
+ this.createElement('body', bw);
+ this.createElement('bbar', bw);
+ this.createElement('footer', bw);
+
+ if(!this.header){
+ this.body.addClass(this.bodyCls + '-noheader');
+ if(this.tbar){
+ this.tbar.addClass(this.tbarCls + '-noheader');
+ }
+ }
+ }
+
+ if(Ext.isDefined(this.padding)){
+ this.body.setStyle('padding', this.body.addUnits(this.padding));
+ }
+
+ if(this.border === false){
+ this.el.addClass(this.baseCls + '-noborder');
+ this.body.addClass(this.bodyCls + '-noborder');
+ if(this.header){
+ this.header.addClass(this.headerCls + '-noborder');
+ }
+ if(this.footer){
+ this.footer.addClass(this.footerCls + '-noborder');
+ }
+ if(this.tbar){
+ this.tbar.addClass(this.tbarCls + '-noborder');
+ }
+ if(this.bbar){
+ this.bbar.addClass(this.bbarCls + '-noborder');
+ }
+ }
+
+ if(this.bodyBorder === false){
+ this.body.addClass(this.bodyCls + '-noborder');
+ }
+
+ this.bwrap.enableDisplayMode('block');
+
+ if(this.header){
+ this.header.unselectable();
+
+
+ if(this.headerAsText){
+ this.header.dom.innerHTML =
+ '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
+
+ if(this.iconCls){
+ this.setIconClass(this.iconCls);
+ }
+ }
+ }
+
+ if(this.floating){
+ this.makeFloating(this.floating);
+ }
+
+ if(this.collapsible && this.titleCollapse && this.header){
+ this.mon(this.header, 'click', this.toggleCollapse, this);
+ this.header.setStyle('cursor', 'pointer');
+ }
+ if(ts){
+ this.addTool.apply(this, ts);
+ }
+
+
+ if(this.fbar){
+ this.footer.addClass('x-panel-btns');
+ this.fbar.ownerCt = this;
+ this.fbar.render(this.footer);
+ this.footer.createChild({cls:'x-clear'});
+ }
+ if(this.tbar && this.topToolbar){
+ this.topToolbar.ownerCt = this;
+ this.topToolbar.render(this.tbar);
+ }
+ if(this.bbar && this.bottomToolbar){
+ this.bottomToolbar.ownerCt = this;
+ this.bottomToolbar.render(this.bbar);
+ }
+ },
+
+
+ setIconClass : function(cls){
+ var old = this.iconCls;
+ this.iconCls = cls;
+ if(this.rendered && this.header){
+ if(this.frame){
+ this.header.addClass('x-panel-icon');
+ this.header.replaceClass(old, this.iconCls);
+ }else{
+ var hd = this.header,
+ img = hd.child('img.x-panel-inline-icon');
+ if(img){
+ Ext.fly(img).replaceClass(old, this.iconCls);
+ }else{
+ var hdspan = hd.child('span.' + this.headerTextCls);
+ if (hdspan) {
+ Ext.DomHelper.insertBefore(hdspan.dom, {
+ tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
+ });
+ }
+ }
+ }
+ }
+ this.fireEvent('iconchange', this, cls, old);
+ },
+
+
+ makeFloating : function(cfg){
+ this.floating = true;
+ this.el = new Ext.Layer(Ext.apply({}, cfg, {
+ shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
+ shadowOffset: this.shadowOffset,
+ constrain:false,
+ shim: this.shim === false ? false : undefined
+ }), this.el);
+ },
+
+
+ getTopToolbar : function(){
+ return this.topToolbar;
+ },
+
+
+ getBottomToolbar : function(){
+ return this.bottomToolbar;
+ },
+
+
+ getFooterToolbar : function() {
+ return this.fbar;
+ },
+
+
+ addButton : function(config, handler, scope){
+ if(!this.fbar){
+ this.createFbar([]);
+ }
+ if(handler){
+ if(Ext.isString(config)){
+ config = {text: config};
+ }
+ config = Ext.apply({
+ handler: handler,
+ scope: scope
+ }, config);
+ }
+ return this.fbar.add(config);
+ },
+
+
+ addTool : function(){
+ if(!this.rendered){
+ if(!this.tools){
+ this.tools = [];
+ }
+ Ext.each(arguments, function(arg){
+ this.tools.push(arg);
+ }, this);
+ return;
+ }
+
+ if(!this[this.toolTarget]){
+ return;
+ }
+ if(!this.toolTemplate){
+
+ var tt = new Ext.Template(
+ '<div class="x-tool x-tool-{id}">&#160;</div>'
+ );
+ tt.disableFormats = true;
+ tt.compile();
+ Ext.Panel.prototype.toolTemplate = tt;
+ }
+ for(var i = 0, a = arguments, len = a.length; i < len; i++) {
+ var tc = a[i];
+ if(!this.tools[tc.id]){
+ var overCls = 'x-tool-'+tc.id+'-over';
+ var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
+ this.tools[tc.id] = t;
+ t.enableDisplayMode('block');
+ this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
+ if(tc.on){
+ this.mon(t, tc.on);
+ }
+ if(tc.hidden){
+ t.hide();
+ }
+ if(tc.qtip){
+ if(Ext.isObject(tc.qtip)){
+ Ext.QuickTips.register(Ext.apply({
+ target: t.id
+ }, tc.qtip));
+ } else {
+ t.dom.qtip = tc.qtip;
+ }
+ }
+ t.addClassOnOver(overCls);
+ }
+ }
+ },
+
+ onLayout : function(shallow, force){
+ Ext.Panel.superclass.onLayout.apply(this, arguments);
+ if(this.hasLayout && this.toolbars.length > 0){
+ Ext.each(this.toolbars, function(tb){
+ tb.doLayout(undefined, force);
+ });
+ this.syncHeight();
+ }
+ },
+
+ syncHeight : function(){
+ var h = this.toolbarHeight,
+ bd = this.body,
+ lsh = this.lastSize.height,
+ sz;
+
+ if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
+ return;
+ }
+
+
+ if(h != this.getToolbarHeight()){
+ h = Math.max(0, lsh - this.getFrameHeight());
+ bd.setHeight(h);
+ sz = bd.getSize();
+ this.toolbarHeight = this.getToolbarHeight();
+ this.onBodyResize(sz.width, sz.height);
+ }
+ },
+
+
+ onShow : function(){
+ if(this.floating){
+ return this.el.show();
+ }
+ Ext.Panel.superclass.onShow.call(this);
+ },
+
+
+ onHide : function(){
+ if(this.floating){
+ return this.el.hide();
+ }
+ Ext.Panel.superclass.onHide.call(this);
+ },
+
+
+ createToolHandler : function(t, tc, overCls, panel){
+ return function(e){
+ t.removeClass(overCls);
+ if(tc.stopEvent !== false){
+ e.stopEvent();
+ }
+ if(tc.handler){
+ tc.handler.call(tc.scope || t, e, t, panel, tc);
+ }
+ };
+ },
+
+
+ afterRender : function(){
+ if(this.floating && !this.hidden){
+ this.el.show();
+ }
+ if(this.title){
+ this.setTitle(this.title);
+ }
+ Ext.Panel.superclass.afterRender.call(this);
+ if (this.collapsed) {
+ this.collapsed = false;
+ this.collapse(false);
+ }
+ this.initEvents();
+ },
+
+
+ getKeyMap : function(){
+ if(!this.keyMap){
+ this.keyMap = new Ext.KeyMap(this.el, this.keys);
+ }
+ return this.keyMap;
+ },
+
+
+ initEvents : function(){
+ if(this.keys){
+ this.getKeyMap();
+ }
+ if(this.draggable){
+ this.initDraggable();
+ }
+ if(this.toolbars.length > 0){
+ Ext.each(this.toolbars, function(tb){
+ tb.doLayout();
+ tb.on({
+ scope: this,
+ afterlayout: this.syncHeight,
+ remove: this.syncHeight
+ });
+ }, this);
+ this.syncHeight();
+ }
+
+ },
+
+
+ initDraggable : function(){
+
+ this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
+ },
+
+
+ beforeEffect : function(anim){
+ if(this.floating){
+ this.el.beforeAction();
+ }
+ if(anim !== false){
+ this.el.addClass('x-panel-animated');
+ }
+ },
+
+
+ afterEffect : function(anim){
+ this.syncShadow();
+ this.el.removeClass('x-panel-animated');
+ },
+
+
+ createEffect : function(a, cb, scope){
+ var o = {
+ scope:scope,
+ block:true
+ };
+ if(a === true){
+ o.callback = cb;
+ return o;
+ }else if(!a.callback){
+ o.callback = cb;
+ }else {
+ o.callback = function(){
+ cb.call(scope);
+ Ext.callback(a.callback, a.scope);
+ };
+ }
+ return Ext.applyIf(o, a);
+ },
+
+
+ collapse : function(animate){
+ if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
+ return;
+ }
+ var doAnim = animate === true || (animate !== false && this.animCollapse);
+ this.beforeEffect(doAnim);
+ this.onCollapse(doAnim, animate);
+ return this;
+ },
+
+
+ onCollapse : function(doAnim, animArg){
+ if(doAnim){
+ this[this.collapseEl].slideOut(this.slideAnchor,
+ Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
+ this.collapseDefaults));
+ }else{
+ this[this.collapseEl].hide(this.hideMode);
+ this.afterCollapse(false);
+ }
+ },
+
+
+ afterCollapse : function(anim){
+ this.collapsed = true;
+ this.el.addClass(this.collapsedCls);
+ if(anim !== false){
+ this[this.collapseEl].hide(this.hideMode);
+ }
+ this.afterEffect(anim);
+
+
+ this.cascade(function(c) {
+ if (c.lastSize) {
+ c.lastSize = { width: undefined, height: undefined };
+ }
+ });
+ this.fireEvent('collapse', this);
+ },
+
+
+ expand : function(animate){
+ if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
+ return;
+ }
+ var doAnim = animate === true || (animate !== false && this.animCollapse);
+ this.el.removeClass(this.collapsedCls);
+ this.beforeEffect(doAnim);
+ this.onExpand(doAnim, animate);
+ return this;
+ },
+
+
+ onExpand : function(doAnim, animArg){
+ if(doAnim){
+ this[this.collapseEl].slideIn(this.slideAnchor,
+ Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
+ this.expandDefaults));
+ }else{
+ this[this.collapseEl].show(this.hideMode);
+ this.afterExpand(false);
+ }
+ },
+
+
+ afterExpand : function(anim){
+ this.collapsed = false;
+ if(anim !== false){
+ this[this.collapseEl].show(this.hideMode);
+ }
+ this.afterEffect(anim);
+ if (this.deferLayout) {
+ delete this.deferLayout;
+ this.doLayout(true);
+ }
+ this.fireEvent('expand', this);
+ },
+
+
+ toggleCollapse : function(animate){
+ this[this.collapsed ? 'expand' : 'collapse'](animate);
+ return this;
+ },
+
+
+ onDisable : function(){
+ if(this.rendered && this.maskDisabled){
+ this.el.mask();
+ }
+ Ext.Panel.superclass.onDisable.call(this);
+ },
+
+
+ onEnable : function(){
+ if(this.rendered && this.maskDisabled){
+ this.el.unmask();
+ }
+ Ext.Panel.superclass.onEnable.call(this);
+ },
+
+
+ onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
+ var w = adjWidth,
+ h = adjHeight;
+
+ if(Ext.isDefined(w) || Ext.isDefined(h)){
+ if(!this.collapsed){
+
+
+
+
+ if(Ext.isNumber(w)){
+ this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
+ } else if (w == 'auto') {
+ w = this.body.setWidth('auto').dom.offsetWidth;
+ } else {
+ w = this.body.dom.offsetWidth;
+ }
+
+ if(this.tbar){
+ this.tbar.setWidth(w);
+ if(this.topToolbar){
+ this.topToolbar.setSize(w);
+ }
+ }
+ if(this.bbar){
+ this.bbar.setWidth(w);
+ if(this.bottomToolbar){
+ this.bottomToolbar.setSize(w);
+
+ if (Ext.isIE9m) {
+ this.bbar.setStyle('position', 'static');
+ this.bbar.setStyle('position', '');
+ }
+ }
+ }
+ if(this.footer){
+ this.footer.setWidth(w);
+ if(this.fbar){
+ this.fbar.setSize(Ext.isIE9m ? (w - this.footer.getFrameWidth('lr')) : 'auto');
+ }
+ }
+
+
+ if(Ext.isNumber(h)){
+ h = Math.max(0, h - this.getFrameHeight());
+
+ this.body.setHeight(h);
+ }else if(h == 'auto'){
+ this.body.setHeight(h);
+ }
+
+ if(this.disabled && this.el._mask){
+ this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
+ }
+ }else{
+
+ this.queuedBodySize = {width: w, height: h};
+ if(!this.queuedExpand && this.allowQueuedExpand !== false){
+ this.queuedExpand = true;
+ this.on('expand', function(){
+ delete this.queuedExpand;
+ this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
+ }, this, {single:true});
+ }
+ }
+ this.onBodyResize(w, h);
+ }
+ this.syncShadow();
+ Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
+
+ },
+
+
+ onBodyResize: function(w, h){
+ this.fireEvent('bodyresize', this, w, h);
+ },
+
+
+ getToolbarHeight: function(){
+ var h = 0;
+ if(this.rendered){
+ Ext.each(this.toolbars, function(tb){
+ h += tb.getHeight();
+ }, this);
+ }
+ return h;
+ },
+
+
+ adjustBodyHeight : function(h){
+ return h;
+ },
+
+
+ adjustBodyWidth : function(w){
+ return w;
+ },
+
+
+ onPosition : function(){
+ this.syncShadow();
+ },
+
+
+ getFrameWidth : function(){
+ var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
+
+ if(this.frame){
+ var l = this.bwrap.dom.firstChild;
+ w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
+ w += this.mc.getFrameWidth('lr');
+ }
+ return w;
+ },
+
+
+ getFrameHeight : function() {
+ var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
+ h += (this.tbar ? this.tbar.getHeight() : 0) +
+ (this.bbar ? this.bbar.getHeight() : 0);
+
+ if(this.frame){
+ h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
+ }else{
+ h += (this.header ? this.header.getHeight() : 0) +
+ (this.footer ? this.footer.getHeight() : 0);
+ }
+ return h;
+ },
+
+
+ getInnerWidth : function(){
+ return this.getSize().width - this.getFrameWidth();
+ },
+
+
+ getInnerHeight : function(){
+ return this.body.getHeight();
+
+ },
+
+
+ syncShadow : function(){
+ if(this.floating){
+ this.el.sync(true);
+ }
+ },
+
+
+ getLayoutTarget : function(){
+ return this.body;
+ },
+
+
+ getContentTarget : function(){
+ return this.body;
+ },
+
+
+ setTitle : function(title, iconCls){
+ this.title = title;
+ if(this.header && this.headerAsText){
+ this.header.child('span').update(title);
+ }
+ if(iconCls){
+ this.setIconClass(iconCls);
+ }
+ this.fireEvent('titlechange', this, title);
+ return this;
+ },
+
+
+ getUpdater : function(){
+ return this.body.getUpdater();
+ },
+
+
+ load : function(){
+ var um = this.body.getUpdater();
+ um.update.apply(um, arguments);
+ return this;
+ },
+
+
+ beforeDestroy : function(){
+ Ext.Panel.superclass.beforeDestroy.call(this);
+ if(this.header){
+ this.header.removeAllListeners();
+ }
+ if(this.tools){
+ for(var k in this.tools){
+ Ext.destroy(this.tools[k]);
+ }
+ }
+ if(this.toolbars.length > 0){
+ Ext.each(this.toolbars, function(tb){
+ tb.un('afterlayout', this.syncHeight, this);
+ tb.un('remove', this.syncHeight, this);
+ }, this);
+ }
+ if(Ext.isArray(this.buttons)){
+ while(this.buttons.length) {
+ Ext.destroy(this.buttons[0]);
+ }
+ }
+ if(this.rendered){
+ Ext.destroy(
+ this.ft,
+ this.header,
+ this.footer,
+ this.tbar,
+ this.bbar,
+ this.body,
+ this.mc,
+ this.bwrap,
+ this.dd
+ );
+ if (this.fbar) {
+ Ext.destroy(
+ this.fbar,
+ this.fbar.el
+ );
+ }
+ }
+ Ext.destroy(this.toolbars);
+ },
+
+
+ createClasses : function(){
+ this.headerCls = this.baseCls + '-header';
+ this.headerTextCls = this.baseCls + '-header-text';
+ this.bwrapCls = this.baseCls + '-bwrap';
+ this.tbarCls = this.baseCls + '-tbar';
+ this.bodyCls = this.baseCls + '-body';
+ this.bbarCls = this.baseCls + '-bbar';
+ this.footerCls = this.baseCls + '-footer';
+ },
+
+
+ createGhost : function(cls, useShim, appendTo){
+ var el = document.createElement('div');
+ el.className = 'x-panel-ghost ' + (cls ? cls : '');
+ if(this.header){
+ el.appendChild(this.el.dom.firstChild.cloneNode(true));
+ }
+ Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
+ el.style.width = this.el.dom.offsetWidth + 'px';;
+ if(!appendTo){
+ this.container.dom.appendChild(el);
+ }else{
+ Ext.getDom(appendTo).appendChild(el);
+ }
+ if(useShim !== false && this.el.useShim !== false){
+ var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
+ layer.show();
+ return layer;
+ }else{
+ return new Ext.Element(el);
+ }
+ },
+
+
+ doAutoLoad : function(){
+ var u = this.body.getUpdater();
+ if(this.renderer){
+ u.setRenderer(this.renderer);
+ }
+ u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
+ },
+
+
+ getTool : function(id) {
+ return this.tools[id];
+ }
+
+
+});
+Ext.reg('panel', Ext.Panel);
+
+Ext.Editor = function(field, config){
+ if(field.field){
+ this.field = Ext.create(field.field, 'textfield');
+ config = Ext.apply({}, field);
+ delete config.field;
+ }else{
+ this.field = field;
+ }
+ Ext.Editor.superclass.constructor.call(this, config);
+};
+
+Ext.extend(Ext.Editor, Ext.Component, {
+
+
+ allowBlur: true,
+
+
+
+
+
+ value : "",
+
+ alignment: "c-c?",
+
+ offsets: [0, 0],
+
+ shadow : "frame",
+
+ constrain : false,
+
+ swallowKeys : true,
+
+ completeOnEnter : true,
+
+ cancelOnEsc : true,
+
+ updateEl : false,
+
+ initComponent : function(){
+ Ext.Editor.superclass.initComponent.call(this);
+ this.addEvents(
+
+ "beforestartedit",
+
+ "startedit",
+
+ "beforecomplete",
+
+ "complete",
+
+ "canceledit",
+
+ "specialkey"
+ );
+ },
+
+
+ onRender : function(ct, position){
+ this.el = new Ext.Layer({
+ shadow: this.shadow,
+ cls: "x-editor",
+ parentEl : ct,
+ shim : this.shim,
+ shadowOffset: this.shadowOffset || 4,
+ id: this.id,
+ constrain: this.constrain
+ });
+ if(this.zIndex){
+ this.el.setZIndex(this.zIndex);
+ }
+ this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
+ if(this.field.msgTarget != 'title'){
+ this.field.msgTarget = 'qtip';
+ }
+ this.field.inEditor = true;
+ this.mon(this.field, {
+ scope: this,
+ blur: this.onBlur,
+ specialkey: this.onSpecialKey
+ });
+ if(this.field.grow){
+ this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
+ }
+ this.field.render(this.el).show();
+ this.field.getEl().dom.name = '';
+ if(this.swallowKeys){
+ this.field.el.swallowEvent([
+ 'keypress',
+ 'keydown'
+ ]);
+ }
+ },
+
+
+ onSpecialKey : function(field, e){
+ var key = e.getKey(),
+ complete = this.completeOnEnter && key == e.ENTER,
+ cancel = this.cancelOnEsc && key == e.ESC;
+ if(complete || cancel){
+ e.stopEvent();
+ if(complete){
+ this.completeEdit();
+ }else{
+ this.cancelEdit();
+ }
+ if(field.triggerBlur){
+ field.triggerBlur();
+ }
+ }
+ this.fireEvent('specialkey', field, e);
+ },
+
+
+ startEdit : function(el, value){
+ if(this.editing){
+ this.completeEdit();
+ }
+ this.boundEl = Ext.get(el);
+ var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
+ if(!this.rendered){
+ this.render(this.parentEl || document.body);
+ }
+ if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
+ this.startValue = v;
+ this.field.reset();
+ this.field.setValue(v);
+ this.realign(true);
+ this.editing = true;
+ this.show();
+ }
+ },
+
+
+ doAutoSize : function(){
+ if(this.autoSize){
+ var sz = this.boundEl.getSize(),
+ fs = this.field.getSize();
+
+ switch(this.autoSize){
+ case "width":
+ this.setSize(sz.width, fs.height);
+ break;
+ case "height":
+ this.setSize(fs.width, sz.height);
+ break;
+ case "none":
+ this.setSize(fs.width, fs.height);
+ break;
+ default:
+ this.setSize(sz.width, sz.height);
+ }
+ }
+ },
+
+
+ setSize : function(w, h){
+ delete this.field.lastSize;
+ this.field.setSize(w, h);
+ if(this.el){
+
+ if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
+
+ this.el.setSize(w, h);
+ }
+ this.el.sync();
+ }
+ },
+
+
+ realign : function(autoSize){
+ if(autoSize === true){
+ this.doAutoSize();
+ }
+ this.el.alignTo(this.boundEl, this.alignment, this.offsets);
+ },
+
+
+ completeEdit : function(remainVisible){
+ if(!this.editing){
+ return;
+ }
+
+ if (this.field.assertValue) {
+ this.field.assertValue();
+ }
+ var v = this.getValue();
+ if(!this.field.isValid()){
+ if(this.revertInvalid !== false){
+ this.cancelEdit(remainVisible);
+ }
+ return;
+ }
+ if(String(v) === String(this.startValue) && this.ignoreNoChange){
+ this.hideEdit(remainVisible);
+ return;
+ }
+ if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
+ v = this.getValue();
+ if(this.updateEl && this.boundEl){
+ this.boundEl.update(v);
+ }
+ this.hideEdit(remainVisible);
+ this.fireEvent("complete", this, v, this.startValue);
+ }
+ },
+
+
+ onShow : function(){
+ this.el.show();
+ if(this.hideEl !== false){
+ this.boundEl.hide();
+ }
+ this.field.show().focus(false, true);
+ this.fireEvent("startedit", this.boundEl, this.startValue);
+ },
+
+
+ cancelEdit : function(remainVisible){
+ if(this.editing){
+ var v = this.getValue();
+ this.setValue(this.startValue);
+ this.hideEdit(remainVisible);
+ this.fireEvent("canceledit", this, v, this.startValue);
+ }
+ },
+
+
+ hideEdit: function(remainVisible){
+ if(remainVisible !== true){
+ this.editing = false;
+ this.hide();
+ }
+ },
+
+
+ onBlur : function(){
+
+ if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
+ 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();
+ }
+ },
+
+
+ setValue : function(v){
+ this.field.setValue(v);
+ },
+
+
+ getValue : function(){
+ return this.field.getValue();
+ },
+
+ beforeDestroy : function(){
+ Ext.destroyMembers(this, 'field');
+
+ delete this.parentEl;
+ delete this.boundEl;
+ }
+});
+Ext.reg('editor', Ext.Editor);
+
+Ext.ColorPalette = Ext.extend(Ext.Component, {
+
+
+ itemCls : 'x-color-palette',
+
+ value : null,
+
+ clickEvent :'click',
+
+ ctype : 'Ext.ColorPalette',
+
+
+ allowReselect : false,
+
+
+ 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'
+ ],
+
+
+
+
+
+ initComponent : function(){
+ Ext.ColorPalette.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'select'
+ );
+
+ if(this.handler){
+ this.on('select', this.handler, this.scope, true);
+ }
+ },
+
+
+ onRender : function(container, position){
+ this.autoEl = {
+ tag: 'div',
+ cls: this.itemCls
+ };
+ Ext.ColorPalette.superclass.onRender.call(this, container, position);
+ var t = this.tpl || new Ext.XTemplate(
+ '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" class="x-unselectable" unselectable="on">&#160;</span></em></a></tpl>'
+ );
+ t.overwrite(this.el, this.colors);
+ this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
+ if(this.clickEvent != 'click'){
+ this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
+ }
+ },
+
+
+ afterRender : function(){
+ Ext.ColorPalette.superclass.afterRender.call(this);
+ if(this.value){
+ var s = this.value;
+ this.value = null;
+ this.select(s, true);
+ }
+ },
+
+
+ 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(color, suppressEvent){
+ color = color.replace('#', '');
+ if(color != this.value || this.allowReselect){
+ var el = this.el;
+ if(this.value){
+ el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
+ }
+ el.child('a.color-'+color).addClass('x-color-palette-sel');
+ this.value = color;
+ if(suppressEvent !== true){
+ this.fireEvent('select', this, color);
+ }
+ }
+ }
+
+
+});
+Ext.reg('colorpalette', Ext.ColorPalette);
+Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
+
+ todayText : 'Today',
+
+ okText : '&#160;OK&#160;',
+
+ cancelText : 'Cancel',
+
+
+
+ todayTip : '{0} (Spacebar)',
+
+ minText : 'This date is before the minimum date',
+
+ maxText : 'This date is after the maximum date',
+
+ format : 'm/d/y',
+
+ disabledDaysText : 'Disabled',
+
+ disabledDatesText : 'Disabled',
+
+ 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,
+
+ showToday : true,
+
+
+
+
+
+
+
+
+ focusOnSelect: true,
+
+
+
+ initHour: 12,
+
+
+ initComponent : function(){
+ Ext.DatePicker.superclass.initComponent.call(this);
+
+ this.value = this.value ?
+ this.value.clearTime(true) : new Date().clearTime();
+
+ this.addEvents(
+
+ 'select'
+ );
+
+ if(this.handler){
+ this.on('select', this.handler, this.scope || this);
+ }
+
+ this.initDisabledDays();
+ },
+
+
+ initDisabledDays : function(){
+ if(!this.disabledDatesRE && this.disabledDates){
+ var dd = this.disabledDates,
+ len = dd.length - 1,
+ re = '(?:';
+
+ Ext.each(dd, function(d, i){
+ re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
+ if(i != len){
+ re += '|';
+ }
+ }, this);
+ this.disabledDatesRE = new RegExp(re + ')');
+ }
+ },
+
+
+ setDisabledDates : function(dd){
+ if(Ext.isArray(dd)){
+ this.disabledDates = dd;
+ this.disabledDatesRE = null;
+ }else{
+ this.disabledDatesRE = dd;
+ }
+ this.initDisabledDays();
+ this.update(this.value, true);
+ },
+
+
+ setDisabledDays : function(dd){
+ this.disabledDays = dd;
+ this.update(this.value, true);
+ },
+
+
+ setMinDate : function(dt){
+ this.minDate = dt;
+ this.update(this.value, true);
+ },
+
+
+ setMaxDate : function(dt){
+ this.maxDate = dt;
+ this.update(this.value, true);
+ },
+
+
+ setValue : function(value){
+ this.value = value.clearTime(true);
+ this.update(this.value);
+ },
+
+
+ getValue : function(){
+ return this.value;
+ },
+
+
+ focus : function(){
+ this.update(this.activeDate);
+ },
+
+
+ onEnable: function(initial){
+ Ext.DatePicker.superclass.onEnable.call(this);
+ this.doDisabled(false);
+ this.update(initial ? this.value : this.activeDate);
+ if(Ext.isIE9m){
+ this.el.repaint();
+ }
+
+ },
+
+
+ onDisable : function(){
+ Ext.DatePicker.superclass.onDisable.call(this);
+ this.doDisabled(true);
+ if(Ext.isIE9m && !Ext.isIE8){
+
+ Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
+ Ext.fly(el).repaint();
+ });
+ }
+ },
+
+
+ doDisabled : function(disabled){
+ this.keyNav.setDisabled(disabled);
+ this.prevRepeater.setDisabled(disabled);
+ this.nextRepeater.setDisabled(disabled);
+ if(this.showToday){
+ this.todayKeyListener.setDisabled(disabled);
+ this.todayBtn.setDisabled(disabled);
+ }
+ },
+
+
+ onRender : function(container, position){
+ 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>'],
+ dn = this.dayNames,
+ i;
+ for(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(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.push('</tr></tbody></table></td></tr>',
+ this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
+ '</table><div class="x-date-mp"></div>');
+
+ var el = document.createElement('div');
+ el.className = 'x-date-picker';
+ el.innerHTML = m.join('');
+
+ container.dom.insertBefore(el, position);
+
+ this.el = Ext.get(el);
+ this.eventEl = Ext.get(el.firstChild);
+
+ this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
+ handler: this.showPrevMonth,
+ scope: this,
+ preventDefault:true,
+ stopDefault:true
+ });
+
+ this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
+ handler: this.showNextMonth,
+ scope: this,
+ preventDefault:true,
+ stopDefault:true
+ });
+
+ this.monthPicker = this.el.down('div.x-date-mp');
+ this.monthPicker.enableDisplayMode('block');
+
+ this.keyNav = new Ext.KeyNav(this.eventEl, {
+ 'left' : function(e){
+ if(e.ctrlKey){
+ this.showPrevMonth();
+ }else{
+ this.update(this.activeDate.add('d', -1));
+ }
+ },
+
+ 'right' : function(e){
+ if(e.ctrlKey){
+ this.showNextMonth();
+ }else{
+ this.update(this.activeDate.add('d', 1));
+ }
+ },
+
+ 'up' : function(e){
+ if(e.ctrlKey){
+ this.showNextYear();
+ }else{
+ this.update(this.activeDate.add('d', -7));
+ }
+ },
+
+ 'down' : function(e){
+ if(e.ctrlKey){
+ this.showPrevYear();
+ }else{
+ 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.unselectable();
+
+ this.cells = this.el.select('table.x-date-inner tbody td');
+ this.textNodes = this.el.query('table.x-date-inner tbody span');
+
+ this.mbtn = new Ext.Button({
+ text: '&#160;',
+ tooltip: this.monthYearText,
+ renderTo: this.el.child('td.x-date-middle', true)
+ });
+ this.mbtn.el.child('em').addClass('x-btn-arrow');
+
+ if(this.showToday){
+ this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
+ var today = (new Date()).dateFormat(this.format);
+ this.todayBtn = new Ext.Button({
+ renderTo: this.el.child('td.x-date-bottom', true),
+ text: String.format(this.todayText, today),
+ tooltip: String.format(this.todayTip, today),
+ handler: this.selectToday,
+ scope: this
+ });
+ }
+ this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
+ this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'});
+ this.mon(this.mbtn, 'click', this.showMonthPicker, this);
+ this.onEnable(true);
+ },
+
+
+ createMonthPicker : function(){
+ if(!this.monthPicker.dom.firstChild){
+ var buf = ['<table border="0" cellspacing="0">'];
+ for(var i = 0; i < 6; i++){
+ buf.push(
+ '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
+ '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
+ i === 0 ?
+ '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
+ '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
+ );
+ }
+ buf.push(
+ '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
+ this.okText,
+ '</button><button type="button" class="x-date-mp-cancel">',
+ this.cancelText,
+ '</button></td></tr>',
+ '</table>'
+ );
+ this.monthPicker.update(buf.join(''));
+
+ this.mon(this.monthPicker, 'click', this.onMonthClick, this);
+ this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
+
+ this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
+ this.mpYears = this.monthPicker.select('td.x-date-mp-year');
+
+ this.mpMonths.each(function(m, a, i){
+ i += 1;
+ if((i%2) === 0){
+ m.dom.xmonth = 5 + Math.round(i * 0.5);
+ }else{
+ m.dom.xmonth = Math.round((i-1) * 0.5);
+ }
+ });
+ }
+ },
+
+
+ showMonthPicker : function(){
+ if(!this.disabled){
+ this.createMonthPicker();
+ var size = this.el.getSize();
+ this.monthPicker.setSize(size);
+ this.monthPicker.child('table').setSize(size);
+
+ this.mpSelMonth = (this.activeDate || this.value).getMonth();
+ this.updateMPMonth(this.mpSelMonth);
+ this.mpSelYear = (this.activeDate || this.value).getFullYear();
+ this.updateMPYear(this.mpSelYear);
+
+ this.monthPicker.slideIn('t', {duration:0.2});
+ }
+ },
+
+
+ updateMPYear : function(y){
+ this.mpyear = y;
+ var ys = this.mpYears.elements;
+ for(var i = 1; i <= 10; i++){
+ var td = ys[i-1], y2;
+ if((i%2) === 0){
+ y2 = y + Math.round(i * 0.5);
+ td.firstChild.innerHTML = y2;
+ td.xyear = y2;
+ }else{
+ y2 = y - (5-Math.round(i * 0.5));
+ td.firstChild.innerHTML = y2;
+ td.xyear = y2;
+ }
+ this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
+ }
+ },
+
+
+ updateMPMonth : function(sm){
+ this.mpMonths.each(function(m, a, i){
+ m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
+ });
+ },
+
+
+ selectMPMonth : function(m){
+
+ },
+
+
+ onMonthClick : function(e, t){
+ e.stopEvent();
+ var el = new Ext.Element(t), pn;
+ if(el.is('button.x-date-mp-cancel')){
+ this.hideMonthPicker();
+ }
+ else if(el.is('button.x-date-mp-ok')){
+ var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
+ if(d.getMonth() != this.mpSelMonth){
+
+ d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
+ }
+ this.update(d);
+ this.hideMonthPicker();
+ }
+ else if((pn = el.up('td.x-date-mp-month', 2))){
+ this.mpMonths.removeClass('x-date-mp-sel');
+ pn.addClass('x-date-mp-sel');
+ this.mpSelMonth = pn.dom.xmonth;
+ }
+ else if((pn = el.up('td.x-date-mp-year', 2))){
+ this.mpYears.removeClass('x-date-mp-sel');
+ pn.addClass('x-date-mp-sel');
+ this.mpSelYear = pn.dom.xyear;
+ }
+ else if(el.is('a.x-date-mp-prev')){
+ this.updateMPYear(this.mpyear-10);
+ }
+ else if(el.is('a.x-date-mp-next')){
+ this.updateMPYear(this.mpyear+10);
+ }
+ },
+
+
+ onMonthDblClick : function(e, t){
+ e.stopEvent();
+ var el = new Ext.Element(t), pn;
+ if((pn = el.up('td.x-date-mp-month', 2))){
+ this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
+ this.hideMonthPicker();
+ }
+ else if((pn = el.up('td.x-date-mp-year', 2))){
+ this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
+ this.hideMonthPicker();
+ }
+ },
+
+
+ hideMonthPicker : function(disableAnim){
+ if(this.monthPicker){
+ if(disableAnim === true){
+ this.monthPicker.hide();
+ }else{
+ this.monthPicker.slideOut('t', {duration:0.2});
+ }
+ }
+ },
+
+
+ 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){
+ e.stopEvent();
+ if(!this.disabled){
+ var delta = e.getWheelDelta();
+ if(delta > 0){
+ this.showPrevMonth();
+ } else if(delta < 0){
+ this.showNextMonth();
+ }
+ }
+ },
+
+
+ handleDateClick : function(e, t){
+ e.stopEvent();
+ if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
+ this.cancelFocus = this.focusOnSelect === false;
+ this.setValue(new Date(t.dateValue));
+ delete this.cancelFocus;
+ this.fireEvent('select', this, this.value);
+ }
+ },
+
+
+ selectToday : function(){
+ if(this.todayBtn && !this.todayBtn.disabled){
+ this.setValue(new Date().clearTime());
+ this.fireEvent('select', this, this.value);
+ }
+ },
+
+
+ update : function(date, forceRefresh){
+ if(this.rendered){
+ var vd = this.activeDate, vis = this.isVisible();
+ this.activeDate = date;
+ if(!forceRefresh && vd && this.el){
+ var t = date.getTime();
+ if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
+ this.cells.removeClass('x-date-selected');
+ this.cells.each(function(c){
+ if(c.dom.firstChild.dateValue == t){
+ c.addClass('x-date-selected');
+ if(vis && !this.cancelFocus){
+ Ext.fly(c.dom.firstChild).focus(50);
+ }
+ return false;
+ }
+ }, this);
+ return;
+ }
+ }
+ var days = date.getDaysInMonth(),
+ firstOfMonth = date.getFirstDateOfMonth(),
+ startingPos = firstOfMonth.getDay()-this.startDay;
+
+ if(startingPos < 0){
+ startingPos += 7;
+ }
+ days += startingPos;
+
+ var pm = date.add('mo', -1),
+ prevStart = pm.getDaysInMonth()-startingPos,
+ cells = this.cells.elements,
+ textEls = this.textNodes,
+
+ d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
+ today = new Date().clearTime().getTime(),
+ sel = date.clearTime(true).getTime(),
+ min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
+ max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
+ ddMatch = this.disabledDatesRE,
+ ddText = this.disabledDatesText,
+ ddays = this.disabledDays ? this.disabledDays.join('') : false,
+ ddaysText = this.disabledDaysText,
+ format = this.format;
+
+ if(this.showToday){
+ var td = new Date().clearTime(),
+ disable = (td < min || td > max ||
+ (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
+ (ddays && ddays.indexOf(td.getDay()) != -1));
+
+ if(!this.disabled){
+ this.todayBtn.setDisabled(disable);
+ this.todayKeyListener[disable ? 'disable' : 'enable']();
+ }
+ }
+
+ var setCellClass = function(cal, cell){
+ cell.title = '';
+ var t = d.clearTime(true).getTime();
+ cell.firstChild.dateValue = t;
+ if(t == today){
+ cell.className += ' x-date-today';
+ cell.title = cal.todayText;
+ }
+ if(t == sel){
+ cell.className += ' x-date-selected';
+ if(vis){
+ Ext.fly(cell.firstChild).focus(50);
+ }
+ }
+
+ if(t < min) {
+ cell.className = ' x-date-disabled';
+ cell.title = cal.minText;
+ return;
+ }
+ if(t > max) {
+ cell.className = ' x-date-disabled';
+ cell.title = cal.maxText;
+ return;
+ }
+ if(ddays){
+ if(ddays.indexOf(d.getDay()) != -1){
+ cell.title = ddaysText;
+ cell.className = ' x-date-disabled';
+ }
+ }
+ if(ddMatch && format){
+ var fvalue = d.dateFormat(format);
+ if(ddMatch.test(fvalue)){
+ cell.title = ddText.replace('%0', fvalue);
+ cell.className = ' x-date-disabled';
+ }
+ }
+ };
+
+ var i = 0;
+ for(; i < startingPos; i++) {
+ textEls[i].innerHTML = (++prevStart);
+ d.setDate(d.getDate()+1);
+ cells[i].className = 'x-date-prevday';
+ setCellClass(this, cells[i]);
+ }
+ for(; i < days; i++){
+ var intDay = i - startingPos + 1;
+ textEls[i].innerHTML = (intDay);
+ d.setDate(d.getDate()+1);
+ cells[i].className = 'x-date-active';
+ setCellClass(this, cells[i]);
+ }
+ var extraDays = 0;
+ for(; i < 42; i++) {
+ textEls[i].innerHTML = (++extraDays);
+ d.setDate(d.getDate()+1);
+ cells[i].className = 'x-date-nextday';
+ setCellClass(this, cells[i]);
+ }
+
+ this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
+
+ if(!this.internalRender){
+ var main = this.el.dom.firstChild,
+ w = main.offsetWidth;
+ this.el.setWidth(w + this.el.getBorderWidth('lr'));
+ Ext.fly(main).setWidth(w);
+ this.internalRender = true;
+
+
+
+ if(Ext.isOpera && !this.secondPass){
+ main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
+ this.secondPass = true;
+ this.update.defer(10, this, [date]);
+ }
+ }
+ }
+ },
+
+
+ beforeDestroy : function() {
+ if(this.rendered){
+ Ext.destroy(
+ this.keyNav,
+ this.monthPicker,
+ this.eventEl,
+ this.mbtn,
+ this.nextRepeater,
+ this.prevRepeater,
+ this.cells.el,
+ this.todayBtn
+ );
+ delete this.textNodes;
+ delete this.cells.elements;
+ }
+ }
+
+
+});
+
+Ext.reg('datepicker', Ext.DatePicker);
+
+Ext.LoadMask = function(el, config){
+ this.el = Ext.get(el);
+ Ext.apply(this, config);
+ if(this.store){
+ this.store.on({
+ scope: this,
+ beforeload: this.onBeforeLoad,
+ load: this.onLoad,
+ exception: this.onLoad
+ });
+ this.removeMask = Ext.value(this.removeMask, false);
+ }else{
+ var um = this.el.getUpdater();
+ um.showLoadIndicator = false;
+ um.on({
+ scope: this,
+ beforeupdate: this.onBeforeLoad,
+ update: this.onLoad,
+ failure: this.onLoad
+ });
+ this.removeMask = Ext.value(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);
+ }
+ },
+
+
+ show: function(){
+ this.onBeforeLoad();
+ },
+
+
+ hide: function(){
+ this.onLoad();
+ },
+
+
+ destroy : function(){
+ if(this.store){
+ this.store.un('beforeload', this.onBeforeLoad, this);
+ this.store.un('load', this.onLoad, this);
+ this.store.un('exception', this.onLoad, this);
+ }else{
+ var um = this.el.getUpdater();
+ um.un('beforeupdate', this.onBeforeLoad, this);
+ um.un('update', this.onLoad, this);
+ um.un('failure', this.onLoad, this);
+ }
+ }
+};
+Ext.slider.Thumb = Ext.extend(Object, {
+
+
+ dragging: false,
+
+
+ constructor: function(config) {
+
+ Ext.apply(this, config || {}, {
+ cls: 'x-slider-thumb',
+
+
+ constrain: false
+ });
+
+ Ext.slider.Thumb.superclass.constructor.call(this, config);
+
+ if (this.slider.vertical) {
+ Ext.apply(this, Ext.slider.Thumb.Vertical);
+ }
+ },
+
+
+ render: function() {
+ this.el = this.slider.innerEl.insertFirst({cls: this.cls});
+
+ this.initEvents();
+ },
+
+
+ enable: function() {
+ this.disabled = false;
+ this.el.removeClass(this.slider.disabledClass);
+ },
+
+
+ disable: function() {
+ this.disabled = true;
+ this.el.addClass(this.slider.disabledClass);
+ },
+
+
+ initEvents: function() {
+ var el = this.el;
+
+ el.addClassOnOver('x-slider-thumb-over');
+
+ this.tracker = new Ext.dd.DragTracker({
+ onBeforeStart: this.onBeforeDragStart.createDelegate(this),
+ onStart : this.onDragStart.createDelegate(this),
+ onDrag : this.onDrag.createDelegate(this),
+ onEnd : this.onDragEnd.createDelegate(this),
+ tolerance : 3,
+ autoStart : 300
+ });
+
+ this.tracker.initEl(el);
+ },
+
+
+ onBeforeDragStart : function(e) {
+ if (this.disabled) {
+ return false;
+ } else {
+ this.slider.promoteThumb(this);
+ return true;
+ }
+ },
+
+
+ onDragStart: function(e){
+ this.el.addClass('x-slider-thumb-drag');
+ this.dragging = true;
+ this.dragStartValue = this.value;
+
+ this.slider.fireEvent('dragstart', this.slider, e, this);
+ },
+
+
+ onDrag: function(e) {
+ var slider = this.slider,
+ index = this.index,
+ newValue = this.getNewValue();
+
+ if (this.constrain) {
+ var above = slider.thumbs[index + 1],
+ below = slider.thumbs[index - 1];
+
+ if (below != undefined && newValue <= below.value) newValue = below.value;
+ if (above != undefined && newValue >= above.value) newValue = above.value;
+ }
+
+ slider.setValue(index, newValue, false);
+ slider.fireEvent('drag', slider, e, this);
+ },
+
+ getNewValue: function() {
+ var slider = this.slider,
+ pos = slider.innerEl.translatePoints(this.tracker.getXY());
+
+ return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
+ },
+
+
+ onDragEnd: function(e) {
+ var slider = this.slider,
+ value = this.value;
+
+ this.el.removeClass('x-slider-thumb-drag');
+
+ this.dragging = false;
+ slider.fireEvent('dragend', slider, e);
+
+ if (this.dragStartValue != value) {
+ slider.fireEvent('changecomplete', slider, value, this);
+ }
+ },
+
+
+ destroy: function(){
+ Ext.destroyMembers(this, 'tracker', 'el');
+ }
+});
+
+
+Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
+
+
+ vertical: false,
+
+ minValue: 0,
+
+ maxValue: 100,
+
+ decimalPrecision: 0,
+
+ keyIncrement: 1,
+
+ increment: 0,
+
+
+ clickRange: [5,15],
+
+
+ clickToChange : true,
+
+ animate: true,
+
+ constrainThumbs: true,
+
+
+ topThumbZIndex: 10000,
+
+
+ initComponent : function(){
+ if(!Ext.isDefined(this.value)){
+ this.value = this.minValue;
+ }
+
+
+ this.thumbs = [];
+
+ Ext.slider.MultiSlider.superclass.initComponent.call(this);
+
+ this.keyIncrement = Math.max(this.increment, this.keyIncrement);
+ this.addEvents(
+
+ 'beforechange',
+
+
+ 'change',
+
+
+ 'changecomplete',
+
+
+ 'dragstart',
+
+
+ 'drag',
+
+
+ 'dragend'
+ );
+
+
+ if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
+
+ var values = this.values;
+
+ for (var i=0; i < values.length; i++) {
+ this.addThumb(values[i]);
+ }
+
+ if(this.vertical){
+ Ext.apply(this, Ext.slider.Vertical);
+ }
+ },
+
+
+ addThumb: function(value) {
+ var thumb = new Ext.slider.Thumb({
+ value : value,
+ slider : this,
+ index : this.thumbs.length,
+ constrain: this.constrainThumbs
+ });
+ this.thumbs.push(thumb);
+
+
+ if (this.rendered) thumb.render();
+ },
+
+
+ promoteThumb: function(topThumb) {
+ var thumbs = this.thumbs,
+ zIndex, thumb;
+
+ for (var i = 0, j = thumbs.length; i < j; i++) {
+ thumb = thumbs[i];
+
+ if (thumb == topThumb) {
+ zIndex = this.topThumbZIndex;
+ } else {
+ zIndex = '';
+ }
+
+ thumb.el.setStyle('zIndex', zIndex);
+ }
+ },
+
+
+ onRender : function() {
+ this.autoEl = {
+ cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
+ cn : {
+ cls: 'x-slider-end',
+ cn : {
+ cls:'x-slider-inner',
+ cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
+ }
+ }
+ };
+
+ Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
+
+ this.endEl = this.el.first();
+ this.innerEl = this.endEl.first();
+ this.focusEl = this.innerEl.child('.x-slider-focus');
+
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ this.thumbs[i].render();
+ }
+
+
+ var thumb = this.innerEl.child('.x-slider-thumb');
+ this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
+
+ this.initEvents();
+ },
+
+
+ initEvents : function(){
+ this.mon(this.el, {
+ scope : this,
+ mousedown: this.onMouseDown,
+ keydown : this.onKeyDown
+ });
+
+ this.focusEl.swallowEvent("click", true);
+ },
+
+
+ onMouseDown : function(e){
+ if(this.disabled){
+ return;
+ }
+
+
+ var thumbClicked = false;
+ for (var i=0; i < this.thumbs.length; i++) {
+ thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
+ }
+
+ if (this.clickToChange && !thumbClicked) {
+ var local = this.innerEl.translatePoints(e.getXY());
+ this.onClickChange(local);
+ }
+ this.focus();
+ },
+
+
+ onClickChange : function(local) {
+ if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
+
+ var thumb = this.getNearest(local, 'left'),
+ index = thumb.index;
+
+ this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
+ }
+ },
+
+
+ getNearest: function(local, prop) {
+ var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
+ clickValue = this.reverseValue(localValue),
+ nearestDistance = (this.maxValue - this.minValue) + 5,
+ index = 0,
+ nearest = null;
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ var thumb = this.thumbs[i],
+ value = thumb.value,
+ dist = Math.abs(value - clickValue);
+
+ if (Math.abs(dist <= nearestDistance)) {
+ nearest = thumb;
+ index = i;
+ nearestDistance = dist;
+ }
+ }
+ return nearest;
+ },
+
+
+ onKeyDown : function(e){
+
+ if(this.disabled || this.thumbs.length !== 1){
+ e.preventDefault();
+ return;
+ }
+ var k = e.getKey(),
+ val;
+ switch(k){
+ case e.UP:
+ case e.RIGHT:
+ e.stopEvent();
+ val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
+ this.setValue(0, val, undefined, true);
+ break;
+ case e.DOWN:
+ case e.LEFT:
+ e.stopEvent();
+ val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
+ this.setValue(0, val, undefined, true);
+ break;
+ default:
+ e.preventDefault();
+ }
+ },
+
+
+ doSnap : function(value){
+ if (!(this.increment && value)) {
+ return value;
+ }
+ var newValue = value,
+ inc = this.increment,
+ m = value % inc;
+ if (m != 0) {
+ newValue -= m;
+ if (m * 2 >= inc) {
+ newValue += inc;
+ } else if (m * 2 < -inc) {
+ newValue -= inc;
+ }
+ }
+ return newValue.constrain(this.minValue, this.maxValue);
+ },
+
+
+ afterRender : function(){
+ Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ var thumb = this.thumbs[i];
+
+ if (thumb.value !== undefined) {
+ var v = this.normalizeValue(thumb.value);
+
+ if (v !== thumb.value) {
+
+ this.setValue(i, v, false);
+ } else {
+ this.moveThumb(i, this.translateValue(v), false);
+ }
+ }
+ };
+ },
+
+
+ getRatio : function(){
+ var w = this.innerEl.getWidth(),
+ v = this.maxValue - this.minValue;
+ return v == 0 ? w : (w/v);
+ },
+
+
+ normalizeValue : function(v){
+ v = this.doSnap(v);
+ v = Ext.util.Format.round(v, this.decimalPrecision);
+ v = v.constrain(this.minValue, this.maxValue);
+ return v;
+ },
+
+
+ setMinValue : function(val){
+ this.minValue = val;
+ var i = 0,
+ thumbs = this.thumbs,
+ len = thumbs.length,
+ t;
+
+ for(; i < len; ++i){
+ t = thumbs[i];
+ t.value = t.value < val ? val : t.value;
+ }
+ this.syncThumb();
+ },
+
+
+ setMaxValue : function(val){
+ this.maxValue = val;
+ var i = 0,
+ thumbs = this.thumbs,
+ len = thumbs.length,
+ t;
+
+ for(; i < len; ++i){
+ t = thumbs[i];
+ t.value = t.value > val ? val : t.value;
+ }
+ this.syncThumb();
+ },
+
+
+ setValue : function(index, v, animate, changeComplete) {
+ var thumb = this.thumbs[index],
+ el = thumb.el;
+
+ v = this.normalizeValue(v);
+
+ if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
+ thumb.value = v;
+ if(this.rendered){
+ this.moveThumb(index, this.translateValue(v), animate !== false);
+ this.fireEvent('change', this, v, thumb);
+ if(changeComplete){
+ this.fireEvent('changecomplete', this, v, thumb);
+ }
+ }
+ }
+ },
+
+
+ translateValue : function(v) {
+ var ratio = this.getRatio();
+ return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
+ },
+
+
+ reverseValue : function(pos){
+ var ratio = this.getRatio();
+ return (pos + (this.minValue * ratio)) / ratio;
+ },
+
+
+ moveThumb: function(index, v, animate){
+ var thumb = this.thumbs[index].el;
+
+ if(!animate || this.animate === false){
+ thumb.setLeft(v);
+ }else{
+ thumb.shift({left: v, stopFx: true, duration:.35});
+ }
+ },
+
+
+ focus : function(){
+ this.focusEl.focus(10);
+ },
+
+
+ onResize : function(w, h){
+ var thumbs = this.thumbs,
+ len = thumbs.length,
+ i = 0;
+
+
+ for(; i < len; ++i){
+ thumbs[i].el.stopFx();
+ }
+
+ if(Ext.isNumber(w)){
+ this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
+ }
+ this.syncThumb();
+ Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
+ },
+
+
+ onDisable: function(){
+ Ext.slider.MultiSlider.superclass.onDisable.call(this);
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ var thumb = this.thumbs[i],
+ el = thumb.el;
+
+ thumb.disable();
+
+ if(Ext.isIE){
+
+
+ var xy = el.getXY();
+ el.hide();
+
+ this.innerEl.addClass(this.disabledClass).dom.disabled = true;
+
+ if (!this.thumbHolder) {
+ this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
+ }
+
+ this.thumbHolder.show().setXY(xy);
+ }
+ }
+ },
+
+
+ onEnable: function(){
+ Ext.slider.MultiSlider.superclass.onEnable.call(this);
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ var thumb = this.thumbs[i],
+ el = thumb.el;
+
+ thumb.enable();
+
+ if (Ext.isIE) {
+ this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
+
+ if (this.thumbHolder) this.thumbHolder.hide();
+
+ el.show();
+ this.syncThumb();
+ }
+ }
+ },
+
+
+ syncThumb : function() {
+ if (this.rendered) {
+ for (var i=0; i < this.thumbs.length; i++) {
+ this.moveThumb(i, this.translateValue(this.thumbs[i].value));
+ }
+ }
+ },
+
+
+ getValue : function(index) {
+ return this.thumbs[index].value;
+ },
+
+
+ getValues: function() {
+ var values = [];
+
+ for (var i=0; i < this.thumbs.length; i++) {
+ values.push(this.thumbs[i].value);
+ }
+
+ return values;
+ },
+
+
+ beforeDestroy : function(){
+ var thumbs = this.thumbs;
+ for(var i = 0, len = thumbs.length; i < len; ++i){
+ thumbs[i].destroy();
+ thumbs[i] = null;
+ }
+ Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
+ Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
+ }
+});
+
+Ext.reg('multislider', Ext.slider.MultiSlider);
+
+
+Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
+ constructor: function(config) {
+ config = config || {};
+
+ Ext.applyIf(config, {
+ values: [config.value || 0]
+ });
+
+ Ext.slider.SingleSlider.superclass.constructor.call(this, config);
+ },
+
+
+ getValue: function() {
+
+ return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
+ },
+
+
+ setValue: function(value, animate) {
+ var args = Ext.toArray(arguments),
+ len = args.length;
+
+
+
+
+ if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
+ args.unshift(0);
+ }
+
+ return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
+ },
+
+
+ syncThumb : function() {
+ return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
+ },
+
+
+ getNearest : function(){
+
+ return this.thumbs[0];
+ }
+});
+
+
+Ext.Slider = Ext.slider.SingleSlider;
+
+Ext.reg('slider', Ext.slider.SingleSlider);
+
+
+Ext.slider.Vertical = {
+ onResize : function(w, h){
+ this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
+ this.syncThumb();
+ },
+
+ getRatio : function(){
+ var h = this.innerEl.getHeight(),
+ v = this.maxValue - this.minValue;
+ return h/v;
+ },
+
+ moveThumb: function(index, v, animate) {
+ var thumb = this.thumbs[index],
+ el = thumb.el;
+
+ if (!animate || this.animate === false) {
+ el.setBottom(v);
+ } else {
+ el.shift({bottom: v, stopFx: true, duration:.35});
+ }
+ },
+
+ onClickChange : function(local) {
+ if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
+ var thumb = this.getNearest(local, 'top'),
+ index = thumb.index,
+ value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
+
+ this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
+ }
+ }
+};
+
+
+Ext.slider.Thumb.Vertical = {
+ getNewValue: function() {
+ var slider = this.slider,
+ innerEl = slider.innerEl,
+ pos = innerEl.translatePoints(this.tracker.getXY()),
+ bottom = innerEl.getHeight() - pos.top;
+
+ return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
+ }
+};
+
+Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
+
+ baseCls : 'x-progress',
+
+
+ animate : false,
+
+
+ waitTimer : null,
+
+
+ initComponent : function(){
+ Ext.ProgressBar.superclass.initComponent.call(this);
+ this.addEvents(
+
+ "update"
+ );
+ },
+
+
+ onRender : function(ct, position){
+ var tpl = new Ext.Template(
+ '<div class="{cls}-wrap">',
+ '<div class="{cls}-inner">',
+ '<div class="{cls}-bar">',
+ '<div class="{cls}-text">',
+ '<div>&#160;</div>',
+ '</div>',
+ '</div>',
+ '<div class="{cls}-text {cls}-text-back">',
+ '<div>&#160;</div>',
+ '</div>',
+ '</div>',
+ '</div>'
+ );
+
+ this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
+ : tpl.append(ct, {cls: this.baseCls}, true);
+
+ if(this.id){
+ this.el.dom.id = this.id;
+ }
+ var inner = this.el.dom.firstChild;
+ this.progressBar = Ext.get(inner.firstChild);
+
+ if(this.textEl){
+
+ this.textEl = Ext.get(this.textEl);
+ delete this.textTopEl;
+ }else{
+
+ this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
+ var textBackEl = Ext.get(inner.childNodes[1]);
+ this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
+ this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
+ this.textEl.setWidth(inner.offsetWidth);
+ }
+ this.progressBar.setHeight(inner.offsetHeight);
+ },
+
+
+ afterRender : function(){
+ Ext.ProgressBar.superclass.afterRender.call(this);
+ if(this.value){
+ this.updateProgress(this.value, this.text);
+ }else{
+ this.updateText(this.text);
+ }
+ },
+
+
+ updateProgress : function(value, text, animate){
+ this.value = value || 0;
+ if(text){
+ this.updateText(text);
+ }
+ if(this.rendered && !this.isDestroyed){
+ var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
+ this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
+ if(this.textTopEl){
+
+ this.textTopEl.removeClass('x-hidden').setWidth(w);
+ }
+ }
+ this.fireEvent('update', this, value, text);
+ return this;
+ },
+
+
+ wait : function(o){
+ if(!this.waitTimer){
+ var scope = this;
+ o = o || {};
+ this.updateText(o.text);
+ this.waitTimer = Ext.TaskMgr.start({
+ run: function(i){
+ var inc = o.increment || 10;
+ i -= 1;
+ this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
+ },
+ interval: o.interval || 1000,
+ duration: o.duration,
+ onStop: function(){
+ if(o.fn){
+ o.fn.apply(o.scope || this);
+ }
+ this.reset();
+ },
+ scope: scope
+ });
+ }
+ return this;
+ },
+
+
+ isWaiting : function(){
+ return this.waitTimer !== null;
+ },
+
+
+ updateText : function(text){
+ this.text = text || '&#160;';
+ if(this.rendered){
+ this.textEl.update(this.text);
+ }
+ return this;
+ },
+
+
+ syncProgressBar : function(){
+ if(this.value){
+ this.updateProgress(this.value, this.text);
+ }
+ return this;
+ },
+
+
+ setSize : function(w, h){
+ Ext.ProgressBar.superclass.setSize.call(this, w, h);
+ if(this.textTopEl){
+ var inner = this.el.dom.firstChild;
+ this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
+ }
+ this.syncProgressBar();
+ return this;
+ },
+
+
+ reset : function(hide){
+ this.updateProgress(0);
+ if(this.textTopEl){
+ this.textTopEl.addClass('x-hidden');
+ }
+ this.clearTimer();
+ if(hide === true){
+ this.hide();
+ }
+ return this;
+ },
+
+
+ clearTimer : function(){
+ if(this.waitTimer){
+ this.waitTimer.onStop = null;
+ Ext.TaskMgr.stop(this.waitTimer);
+ this.waitTimer = null;
+ }
+ },
+
+ onDestroy: function(){
+ this.clearTimer();
+ if(this.rendered){
+ if(this.textEl.isComposite){
+ this.textEl.clear();
+ }
+ Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
+ }
+ Ext.ProgressBar.superclass.onDestroy.call(this);
+ }
+});
+Ext.reg('progress', Ext.ProgressBar);
+
+(function() {
+
+var Event=Ext.EventManager;
+var Dom=Ext.lib.Dom;
+
+
+Ext.dd.DragDrop = function(id, sGroup, config) {
+ if(id) {
+ this.init(id, sGroup, config);
+ }
+};
+
+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;
+ },
+
+
+ moveOnly: false,
+
+
+ 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(constrainTo, pad, inContent){
+ if(Ext.isNumber(pad)){
+ pad = {left: pad, right:pad, top:pad, bottom:pad};
+ }
+ pad = pad || this.defaultPadding;
+ var b = Ext.get(this.getEl()).getBox(),
+ ce = Ext.get(constrainTo),
+ s = ce.getScroll(),
+ c,
+ cd = ce.dom;
+ if(cd == document.body){
+ c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
+ }else{
+ var xy = ce.getXY();
+ c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
+ }
+
+
+ var topSpace = b.y - c.y,
+ leftSpace = b.x - c.x;
+
+ this.resetConstraints();
+ this.setXConstraint(leftSpace - (pad.left||0),
+ c.width - leftSpace - b.width - (pad.right||0),
+ this.xTickSize
+ );
+ this.setYConstraint(topSpace - (pad.top||0),
+ c.height - topSpace - b.height - (pad.bottom||0),
+ this.yTickSize
+ );
+ },
+
+
+ getEl: function() {
+ if (!this._domRef) {
+ this._domRef = Ext.getDom(this.id);
+ }
+
+ return this._domRef;
+ },
+
+
+ getDragEl: function() {
+ return Ext.getDom(this.dragElId);
+ },
+
+
+ init: function(id, sGroup, config) {
+ this.initTarget(id, sGroup, config);
+ Event.on(this.id, "mousedown", this.handleMouseDown, this);
+
+ },
+
+
+ initTarget: function(id, sGroup, config) {
+
+
+ this.config = config || {};
+
+
+ this.DDM = Ext.dd.DDM;
+
+ this.groups = {};
+
+
+
+ if (typeof id !== "string") {
+ id = Ext.id(id);
+ }
+
+
+ this.id = id;
+
+
+ this.addToGroup((sGroup) ? sGroup : "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(iTop, iRight, iBot, iLeft) {
+
+ if (!iRight && 0 !== iRight) {
+ this.padding = [iTop, iTop, iTop, iTop];
+ } else if (!iBot && 0 !== iBot) {
+ this.padding = [iTop, iRight, iTop, iRight];
+ } else {
+ this.padding = [iTop, iRight, iBot, iLeft];
+ }
+ },
+
+
+ setInitPosition: function(diffX, diffY) {
+ var el = this.getEl();
+
+ if (!this.DDM.verifyEl(el)) {
+ return;
+ }
+
+ var dx = diffX || 0;
+ var dy = diffY || 0;
+
+ var p = Dom.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 || Dom.getXY( this.getEl() );
+ this.deltaSetXY = null;
+
+ this.startPageX = p[0];
+ this.startPageY = p[1];
+ },
+
+
+ addToGroup: function(sGroup) {
+ this.groups[sGroup] = true;
+ this.DDM.regDragDrop(this, sGroup);
+ },
+
+
+ removeFromGroup: function(sGroup) {
+ if (this.groups[sGroup]) {
+ delete this.groups[sGroup];
+ }
+
+ this.DDM.removeDDFromGroup(this, sGroup);
+ },
+
+
+ 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);
+ }
+ Event.on(id, "mousedown",
+ this.handleMouseDown, this);
+ this.setHandleElId(id);
+
+ this.hasOuterHandles = true;
+ },
+
+
+ unreg: function() {
+ Event.un(this.id, "mousedown",
+ this.handleMouseDown);
+ this._domRef = null;
+ this.DDM._remove(this);
+ },
+
+ destroy : function(){
+ this.unreg();
+ },
+
+
+ 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);
+
+ if (this.preventDefault || this.stopPropagation) {
+ if (this.preventDefault) {
+ e.preventDefault();
+ }
+ if (this.stopPropagation) {
+ e.stopPropagation();
+ }
+ } else {
+ this.DDM.stopEvent(e);
+ }
+ } else {
+
+
+ }
+ }
+ },
+
+ clickValidator: function(e) {
+ var target = e.getTarget();
+ return ( this.isValidHandleChild(target) &&
+ (this.id == this.handleElId ||
+ this.DDM.handleWasClicked(target, this.id)) );
+ },
+
+
+ addInvalidHandleType: function(tagName) {
+ var type = tagName.toUpperCase();
+ this.invalidHandleTypes[type] = type;
+ },
+
+
+ addInvalidHandleId: function(id) {
+ if (typeof id !== "string") {
+ id = Ext.id(id);
+ }
+ this.invalidHandleIds[id] = id;
+ },
+
+
+ addInvalidHandleClass: function(cssClass) {
+ this.invalidHandleClasses.push(cssClass);
+ },
+
+
+ removeInvalidHandleType: function(tagName) {
+ var type = tagName.toUpperCase();
+
+ delete this.invalidHandleTypes[type];
+ },
+
+
+ removeInvalidHandleId: function(id) {
+ if (typeof id !== "string") {
+ id = Ext.id(id);
+ }
+ delete this.invalidHandleIds[id];
+ },
+
+
+ removeInvalidHandleClass: function(cssClass) {
+ for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
+ if (this.invalidHandleClasses[i] == cssClass) {
+ delete this.invalidHandleClasses[i];
+ }
+ }
+ },
+
+
+ isValidHandleChild: function(node) {
+
+ var valid = true;
+
+ var nodeName;
+ try {
+ nodeName = node.nodeName.toUpperCase();
+ } catch(e) {
+ nodeName = node.nodeName;
+ }
+ valid = valid && !this.invalidHandleTypes[nodeName];
+ valid = valid && !this.invalidHandleIds[node.id];
+
+ for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
+ valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
+ }
+
+
+ return valid;
+
+ },
+
+
+ setXTicks: function(iStartX, iTickSize) {
+ this.xTicks = [];
+ this.xTickSize = iTickSize;
+
+ var tickMap = {};
+
+ for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
+ if (!tickMap[i]) {
+ this.xTicks[this.xTicks.length] = i;
+ tickMap[i] = true;
+ }
+ }
+
+ for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
+ if (!tickMap[i]) {
+ this.xTicks[this.xTicks.length] = i;
+ tickMap[i] = true;
+ }
+ }
+
+ this.xTicks.sort(this.DDM.numericSort) ;
+ },
+
+
+ setYTicks: function(iStartY, iTickSize) {
+ this.yTicks = [];
+ this.yTickSize = iTickSize;
+
+ var tickMap = {};
+
+ for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
+ if (!tickMap[i]) {
+ this.yTicks[this.yTicks.length] = i;
+ tickMap[i] = true;
+ }
+ }
+
+ for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
+ if (!tickMap[i]) {
+ this.yTicks[this.yTicks.length] = i;
+ tickMap[i] = true;
+ }
+ }
+
+ this.yTicks.sort(this.DDM.numericSort) ;
+ },
+
+
+ setXConstraint: function(iLeft, iRight, iTickSize) {
+ this.leftConstraint = iLeft;
+ this.rightConstraint = iRight;
+
+ this.minX = this.initPageX - iLeft;
+ this.maxX = this.initPageX + iRight;
+ if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
+
+ 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, iDown, iTickSize) {
+ this.topConstraint = iUp;
+ this.bottomConstraint = iDown;
+
+ this.minY = this.initPageY - iUp;
+ this.maxY = this.initPageY + iDown;
+ if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
+
+ 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, tickArray) {
+ if (!tickArray) {
+
+
+ return val;
+ } else if (tickArray[0] >= val) {
+
+
+ return tickArray[0];
+ } else {
+ for (var i=0, len=tickArray.length; i<len; ++i) {
+ var next = i + 1;
+ if (tickArray[next] && tickArray[next] >= val) {
+ var diff1 = val - tickArray[i];
+ var diff2 = tickArray[next] - val;
+ return (diff2 > diff1) ? tickArray[i] : tickArray[next];
+ }
+ }
+
+
+
+ return tickArray[tickArray.length - 1];
+ }
+ },
+
+
+ toString: function() {
+ return ("DragDrop " + this.id);
+ }
+
+};
+
+})();
+
+
+
+
+if (!Ext.dd.DragDropMgr) {
+
+
+Ext.dd.DragDropMgr = function() {
+
+ var Event = Ext.EventManager;
+
+ return {
+
+
+ ids: {},
+
+
+ handleIds: {},
+
+
+ dragCurrent: null,
+
+
+ dragOvers: {},
+
+
+ deltaX: 0,
+
+
+ deltaY: 0,
+
+
+ preventDefault: true,
+
+
+ stopPropagation: true,
+
+
+ initialized: false,
+
+
+ locked: false,
+
+
+ init: function() {
+ this.initialized = true;
+ },
+
+
+ POINT: 0,
+
+
+ INTERSECT: 1,
+
+
+ mode: 0,
+
+
+ notifyOccluded: false,
+
+
+ _execOnAll: function(sMethod, args) {
+ 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[sMethod].apply(oDD, args);
+ }
+ }
+ },
+
+
+ _onLoad: function() {
+
+ this.init();
+
+
+ Event.on(document, "mouseup", this.handleMouseUp, this, true);
+ Event.on(document, "mousemove", this.handleMouseMove, this, true);
+ Event.on(window, "unload", this._onUnload, this, true);
+ Event.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, sGroup) {
+ if (!this.initialized) { this.init(); }
+
+ if (!this.ids[sGroup]) {
+ this.ids[sGroup] = {};
+ }
+ this.ids[sGroup][oDD.id] = oDD;
+ },
+
+
+ removeDDFromGroup: function(oDD, sGroup) {
+ if (!this.ids[sGroup]) {
+ this.ids[sGroup] = {};
+ }
+
+ var obj = this.ids[sGroup];
+ if (obj && obj[oDD.id]) {
+ delete obj[oDD.id];
+ }
+ },
+
+
+ _remove: function(oDD) {
+ for (var g in oDD.groups) {
+ if (g && this.ids[g] && this.ids[g][oDD.id]) {
+ delete this.ids[g][oDD.id];
+ }
+ }
+ delete this.handleIds[oDD.id];
+ },
+
+
+ regHandle: function(sDDId, sHandleId) {
+ if (!this.handleIds[sDDId]) {
+ this.handleIds[sDDId] = {};
+ }
+ this.handleIds[sDDId][sHandleId] = sHandleId;
+ },
+
+
+ isDragDrop: function(id) {
+ return ( this.getDDById(id) ) ? true : false;
+ },
+
+
+ getRelated: function(p_oDD, bTargetsOnly) {
+ var oDDs = [];
+ for (var i in p_oDD.groups) {
+ for (var j in this.ids[i]) {
+ var dd = this.ids[i][j];
+ if (! this.isTypeOfDD(dd)) {
+ continue;
+ }
+ if (!bTargetsOnly || dd.isTarget) {
+ oDDs[oDDs.length] = dd;
+ }
+ }
+ }
+
+ return oDDs;
+ },
+
+
+ isLegalTarget: function (oDD, oTargetDD) {
+ var targets = this.getRelated(oDD, true);
+ for (var i=0, len=targets.length;i<len;++i) {
+ if (targets[i].id == oTargetDD.id) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+
+ isTypeOfDD: function (oDD) {
+ return (oDD && oDD.__ygDragDrop);
+ },
+
+
+ isHandle: function(sDDId, sHandleId) {
+ return ( this.handleIds[sDDId] &&
+ this.handleIds[sDDId][sHandleId] );
+ },
+
+
+ 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) {
+ if(Ext.QuickTips){
+ Ext.QuickTips.ddDisable();
+ }
+ if(this.dragCurrent){
+
+
+ this.handleMouseUp(e);
+ }
+
+ this.currentTarget = e.getTarget();
+ this.dragCurrent = oDD;
+
+ var el = oDD.getEl();
+
+
+ this.startX = e.getPageX();
+ this.startY = e.getPageY();
+
+ 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(Ext.QuickTips){
+ Ext.QuickTips.ddEnable();
+ }
+ 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 diffX = Math.abs(this.startX - e.getPageX());
+ var diffY = Math.abs(this.startY - e.getPageY());
+ if (diffX > this.clickPixelThresh ||
+ diffY > this.clickPixelThresh) {
+ this.startDrag(this.startX, this.startY);
+ }
+ }
+
+ if (this.dragThreshMet) {
+ this.dragCurrent.b4Drag(e);
+ this.dragCurrent.onDrag(e);
+ if(!this.dragCurrent.moveOnly){
+ this.fireEvents(e, false);
+ }
+ }
+
+ this.stopEvent(e);
+
+ return true;
+ },
+
+
+ fireEvents: function(e, isDrop) {
+ var me = this,
+ dragCurrent = me.dragCurrent,
+ mousePoint = e.getPoint(),
+ overTarget,
+ overTargetEl,
+ allTargets = [],
+ oldOvers = [],
+ outEvts = [],
+ overEvts = [],
+ dropEvts = [],
+ enterEvts = [],
+ needsSort,
+ i,
+ len,
+ sGroup;
+
+
+
+ if (!dragCurrent || dragCurrent.isLocked()) {
+ return;
+ }
+
+
+
+ for (i in me.dragOvers) {
+ overTarget = me.dragOvers[i];
+
+ if (! me.isTypeOfDD(overTarget)) {
+ continue;
+ }
+
+ if (! this.isOverTarget(mousePoint, overTarget, me.mode)) {
+ outEvts.push( overTarget );
+ }
+
+ oldOvers[i] = true;
+ delete me.dragOvers[i];
+ }
+
+
+
+
+ for (sGroup in dragCurrent.groups) {
+
+ if ("string" != typeof sGroup) {
+ continue;
+ }
+
+
+ for (i in me.ids[sGroup]) {
+ overTarget = me.ids[sGroup][i];
+
+
+
+
+
+
+ if (me.isTypeOfDD(overTarget) &&
+ (overTargetEl = overTarget.getEl()) &&
+ (overTarget.isTarget) &&
+ (!overTarget.isLocked()) &&
+ ((overTarget != dragCurrent) || (dragCurrent.ignoreSelf === false))) {
+
+
+ if ((overTarget.zIndex = me.getZIndex(overTargetEl)) !== -1) {
+ needsSort = true;
+ }
+ allTargets.push(overTarget);
+ }
+ }
+ }
+
+
+ if (needsSort) {
+ allTargets.sort(me.byZIndex);
+ }
+
+
+
+ for (i = 0, len = allTargets.length; i < len; i++) {
+ overTarget = allTargets[i];
+
+
+ if (me.isOverTarget(mousePoint, overTarget, me.mode)) {
+
+ if (isDrop) {
+ dropEvts.push( overTarget );
+
+ } else {
+
+ if (!oldOvers[overTarget.id]) {
+ enterEvts.push( overTarget );
+
+ } else {
+ overEvts.push( overTarget );
+ }
+ me.dragOvers[overTarget.id] = overTarget;
+ }
+
+
+ if (!me.notifyOccluded) {
+ break;
+ }
+ }
+ }
+
+ if (me.mode) {
+ if (outEvts.length) {
+ dragCurrent.b4DragOut(e, outEvts);
+ dragCurrent.onDragOut(e, outEvts);
+ }
+
+ if (enterEvts.length) {
+ dragCurrent.onDragEnter(e, enterEvts);
+ }
+
+ if (overEvts.length) {
+ dragCurrent.b4DragOver(e, overEvts);
+ dragCurrent.onDragOver(e, overEvts);
+ }
+
+ if (dropEvts.length) {
+ dragCurrent.b4DragDrop(e, dropEvts);
+ dragCurrent.onDragDrop(e, dropEvts);
+ }
+
+ } else {
+
+ for (i=0, len=outEvts.length; i<len; ++i) {
+ dragCurrent.b4DragOut(e, outEvts[i].id);
+ dragCurrent.onDragOut(e, outEvts[i].id);
+ }
+
+
+ for (i=0,len=enterEvts.length; i<len; ++i) {
+
+ dragCurrent.onDragEnter(e, enterEvts[i].id);
+ }
+
+
+ for (i=0,len=overEvts.length; i<len; ++i) {
+ dragCurrent.b4DragOver(e, overEvts[i].id);
+ dragCurrent.onDragOver(e, overEvts[i].id);
+ }
+
+
+ for (i=0, len=dropEvts.length; i<len; ++i) {
+ dragCurrent.b4DragDrop(e, dropEvts[i].id);
+ dragCurrent.onDragDrop(e, dropEvts[i].id);
+ }
+
+ }
+
+
+ if (isDrop && !dropEvts.length) {
+ dragCurrent.onInvalidDrop(e);
+ }
+ },
+
+
+ getZIndex: function(element) {
+ var body = document.body,
+ z,
+ zIndex = -1;
+
+ element = Ext.getDom(element);
+ while (element !== body) {
+ if (!isNaN(z = Number(Ext.fly(element).getStyle('zIndex')))) {
+ zIndex = z;
+ }
+ element = element.parentNode;
+ }
+ return zIndex;
+ },
+
+
+ byZIndex: function(d1, d2) {
+ return d1.zIndex < d2.zIndex;
+ },
+
+
+ getBestMatch: function(dds) {
+ var winner = null;
+
+
+
+
+
+
+ var len = dds.length;
+
+ if (len == 1) {
+ winner = dds[0];
+ } else {
+
+ for (var i=0; i<len; ++i) {
+ var dd = dds[i];
+
+
+
+ if (dd.cursorIsOver) {
+ winner = dd;
+ break;
+
+ } else {
+ if (!winner ||
+ winner.overlap.getArea() < dd.overlap.getArea()) {
+ winner = dd;
+ }
+ }
+ }
+ }
+
+ return winner;
+ },
+
+
+ refreshCache: function(groups) {
+ for (var sGroup in groups) {
+ if ("string" != typeof sGroup) {
+ continue;
+ }
+ for (var i in this.ids[sGroup]) {
+ var oDD = this.ids[sGroup][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) {
+ if (el) {
+ var parent;
+ if(Ext.isIE){
+ try{
+ parent = el.offsetParent;
+ }catch(e){}
+ }else{
+ parent = el.offsetParent;
+ }
+ if (parent) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+
+ getLocation: function(oDD) {
+ if (! this.isTypeOfDD(oDD)) {
+ return null;
+ }
+
+ var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l, region;
+
+ 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, oTarget, intersect) {
+
+ var loc = this.locationCache[oTarget.id];
+ if (!loc || !this.useCache) {
+ loc = this.getLocation(oTarget);
+ this.locationCache[oTarget.id] = loc;
+
+ }
+
+ if (!loc) {
+ return false;
+ }
+
+ oTarget.cursorIsOver = loc.contains( pt );
+
+
+
+
+
+
+ var dc = this.dragCurrent;
+ if (!dc || !dc.getTargetCoord ||
+ (!intersect && !dc.constrainX && !dc.constrainY)) {
+ return oTarget.cursorIsOver;
+ }
+
+ oTarget.overlap = null;
+
+
+
+
+
+ var pos = dc.getTargetCoord(pt.x, pt.y);
+
+ var el = dc.getDragEl();
+ var curRegion = new Ext.lib.Region( pos.y,
+ pos.x + el.offsetWidth,
+ pos.y + el.offsetHeight,
+ pos.x );
+
+ var overlap = curRegion.intersect(loc);
+
+ if (overlap) {
+ oTarget.overlap = overlap;
+ return (intersect) ? true : oTarget.cursorIsOver;
+ } else {
+ return false;
+ }
+ },
+
+
+ _onUnload: function(e, me) {
+ Event.removeListener(document, "mouseup", this.handleMouseUp, this);
+ Event.removeListener(document, "mousemove", this.handleMouseMove, this);
+ Event.removeListener(window, "resize", this._onResize, this);
+ Ext.dd.DragDropMgr.unregAll();
+ },
+
+
+ unregAll: function() {
+
+ if (this.dragCurrent) {
+ this.stopDrag();
+ this.dragCurrent = null;
+ }
+
+ this._execOnAll("unreg", []);
+
+ for (var i in this.elementCache) {
+ delete this.elementCache[i];
+ }
+
+ this.elementCache = {};
+ this.ids = {};
+ },
+
+
+ elementCache: {},
+
+
+ getElWrapper: function(id) {
+ var oWrapper = this.elementCache[id];
+ if (!oWrapper || !oWrapper.el) {
+ oWrapper = this.elementCache[id] =
+ new this.ElementWrapper(Ext.getDom(id));
+ }
+ return oWrapper;
+ },
+
+
+ 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, styleProp) {
+ return Ext.fly(el).getStyle(styleProp);
+ },
+
+
+ getScrollTop: function () {
+ return this.getScroll().top;
+ },
+
+
+ getScrollLeft: function () {
+ return this.getScroll().left;
+ },
+
+
+ moveToEl: function (moveEl, targetEl) {
+ var aCoord = Ext.lib.Dom.getXY(targetEl);
+ Ext.lib.Dom.setXY(moveEl, aCoord);
+ },
+
+
+ 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(node, id) {
+ if (this.isHandle(id, node.id)) {
+ return true;
+ } else {
+
+ var p = node.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, sGroup, config) {
+ if (id) {
+ this.init(id, sGroup, config);
+ }
+};
+
+Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
+
+
+ scroll: true,
+
+
+ autoOffset: function(iPageX, iPageY) {
+ var x = iPageX - this.startPageX;
+ var y = iPageY - this.startPageY;
+ this.setDelta(x, y);
+ },
+
+
+ setDelta: function(iDeltaX, iDeltaY) {
+ this.deltaX = iDeltaX;
+ this.deltaY = iDeltaY;
+ },
+
+
+ setDragElPos: function(iPageX, iPageY) {
+
+
+
+ var el = this.getDragEl();
+ this.alignElWithMouse(el, iPageX, iPageY);
+ },
+
+
+ alignElWithMouse: function(el, iPageX, iPageY) {
+ var oCoord = this.getTargetCoord(iPageX, iPageY);
+ var fly = el.dom ? el : Ext.fly(el, '_dd');
+ if (!this.deltaSetXY) {
+ var aCoord = [oCoord.x, oCoord.y];
+ fly.setXY(aCoord);
+ var newLeft = fly.getLeft(true);
+ var newTop = fly.getTop(true);
+ this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
+ } else {
+ fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
+ }
+
+ this.cachePosition(oCoord.x, oCoord.y);
+ this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
+ return oCoord;
+ },
+
+
+ cachePosition: function(iPageX, iPageY) {
+ if (iPageX) {
+ this.lastPageX = iPageX;
+ this.lastPageY = iPageY;
+ } else {
+ var aCoord = Ext.lib.Dom.getXY(this.getEl());
+ this.lastPageX = aCoord[0];
+ this.lastPageY = aCoord[1];
+ }
+ },
+
+
+ autoScroll: function(x, y, h, w) {
+
+ if (this.scroll) {
+
+ var clientH = Ext.lib.Dom.getViewHeight();
+
+
+ var clientW = Ext.lib.Dom.getViewWidth();
+
+
+ var st = this.DDM.getScrollTop();
+
+
+ var sl = this.DDM.getScrollLeft();
+
+
+ var bot = h + y;
+
+
+ var right = w + x;
+
+
+
+
+ var toBot = (clientH + st - y - this.deltaY);
+
+
+ var toRight = (clientW + sl - x - this.deltaX);
+
+
+
+
+ var thresh = 40;
+
+
+
+
+ var scrAmt = (document.all) ? 80 : 30;
+
+
+
+ if ( bot > clientH && toBot < thresh ) {
+ window.scrollTo(sl, st + scrAmt);
+ }
+
+
+
+ if ( y < st && st > 0 && y - st < thresh ) {
+ window.scrollTo(sl, st - scrAmt);
+ }
+
+
+
+ if ( right > clientW && toRight < thresh ) {
+ window.scrollTo(sl + scrAmt, st);
+ }
+
+
+
+ if ( x < sl && sl > 0 && x - sl < thresh ) {
+ window.scrollTo(sl - scrAmt, st);
+ }
+ }
+ },
+
+
+ getTargetCoord: function(iPageX, iPageY) {
+ var x = iPageX - this.deltaX;
+ var y = iPageY - 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(e.getPageX(),
+ e.getPageY());
+ },
+
+
+ b4Drag: function(e) {
+ this.setDragElPos(e.getPageX(),
+ e.getPageY());
+ },
+
+ toString: function() {
+ return ("DD " + this.id);
+ }
+
+
+
+
+
+
+});
+
+Ext.dd.DDProxy = function(id, sGroup, config) {
+ if (id) {
+ this.init(id, sGroup, config);
+ 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(iPageX, iPageY) {
+ var el = this.getEl();
+ var dragEl = this.getDragEl();
+ var s = dragEl.style;
+
+ this._resizeProxy();
+
+ if (this.centerFrame) {
+ this.setDelta( Math.round(parseInt(s.width, 10)/2),
+ Math.round(parseInt(s.height, 10)/2) );
+ }
+
+ this.setDragElPos(iPageX, iPageY);
+
+ Ext.fly(dragEl).show();
+ },
+
+
+ _resizeProxy: function() {
+ if (this.resizeFrame) {
+ var el = this.getEl();
+ Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
+ }
+ },
+
+
+ b4MouseDown: function(e) {
+ var x = e.getPageX();
+ var y = e.getPageY();
+ 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 = "";
+
+ this.beforeMove();
+
+
+ lel.style.visibility = "hidden";
+ Ext.dd.DDM.moveToEl(lel, del);
+ del.style.visibility = "hidden";
+ lel.style.visibility = "";
+
+ this.afterDrag();
+ },
+
+ beforeMove : function(){
+
+ },
+
+ afterDrag : function(){
+
+ },
+
+ toString: function() {
+ return ("DDProxy " + this.id);
+ }
+
+});
+
+Ext.dd.DDTarget = function(id, sGroup, config) {
+ if (id) {
+ this.initTarget(id, sGroup, config);
+ }
+};
+
+
+Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
+
+ getDragEl: Ext.emptyFn,
+
+ isValidHandleChild: Ext.emptyFn,
+
+ startDrag: Ext.emptyFn,
+
+ endDrag: Ext.emptyFn,
+
+ onDrag: Ext.emptyFn,
+
+ onDragDrop: Ext.emptyFn,
+
+ onDragEnter: Ext.emptyFn,
+
+ onDragOut: Ext.emptyFn,
+
+ onDragOver: Ext.emptyFn,
+
+ onInvalidDrop: Ext.emptyFn,
+
+ onMouseDown: Ext.emptyFn,
+
+ onMouseUp: Ext.emptyFn,
+
+ setXConstraint: Ext.emptyFn,
+
+ setYConstraint: Ext.emptyFn,
+
+ resetConstraints: Ext.emptyFn,
+
+ clearConstraints: Ext.emptyFn,
+
+ clearTicks: Ext.emptyFn,
+
+ setInitPosition: Ext.emptyFn,
+
+ setDragElId: Ext.emptyFn,
+
+ setHandleElId: Ext.emptyFn,
+
+ setOuterHandleElId: Ext.emptyFn,
+
+ addInvalidHandleClass: Ext.emptyFn,
+
+ addInvalidHandleId: Ext.emptyFn,
+
+ addInvalidHandleType: Ext.emptyFn,
+
+ removeInvalidHandleClass: Ext.emptyFn,
+
+ removeInvalidHandleId: Ext.emptyFn,
+
+ removeInvalidHandleType: Ext.emptyFn,
+
+ toString: function() {
+ return ("DDTarget " + this.id);
+ }
+});
+Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, {
+
+ active: false,
+
+ tolerance: 5,
+
+ autoStart: false,
+
+ constructor : function(config){
+ Ext.apply(this, config);
+ this.addEvents(
+
+ 'mousedown',
+
+ 'mouseup',
+
+ 'mousemove',
+
+ 'dragstart',
+
+ 'dragend',
+
+ 'drag'
+ );
+
+ this.dragRegion = new Ext.lib.Region(0,0,0,0);
+
+ if(this.el){
+ this.initEl(this.el);
+ }
+ Ext.dd.DragTracker.superclass.constructor.call(this, config);
+ },
+
+ initEl: function(el){
+ this.el = Ext.get(el);
+ el.on('mousedown', this.onMouseDown, this,
+ this.delegate ? {delegate: this.delegate} : undefined);
+ },
+
+ destroy : function(){
+ this.el.un('mousedown', this.onMouseDown, this);
+ delete this.el;
+ },
+
+ onMouseDown: function(e, target){
+ if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
+ this.startXY = this.lastXY = e.getXY();
+ this.dragTarget = this.delegate ? target : this.el.dom;
+ if(this.preventDefault !== false){
+ e.preventDefault();
+ }
+ Ext.getDoc().on({
+ scope: this,
+ mouseup: this.onMouseUp,
+ mousemove: this.onMouseMove,
+ selectstart: this.stopSelect
+ });
+ if(this.autoStart){
+ this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
+ }
+ }
+ },
+
+ onMouseMove: function(e, target){
+
+ var ieCheck = Ext.isIE6 || Ext.isIE7 || Ext.isIE8;
+ if(this.active && ieCheck && !e.browserEvent.button){
+ e.preventDefault();
+ this.onMouseUp(e);
+ return;
+ }
+
+ e.preventDefault();
+ var xy = e.getXY(), s = this.startXY;
+ this.lastXY = xy;
+ if(!this.active){
+ if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
+ this.triggerStart(e);
+ }else{
+ return;
+ }
+ }
+ this.fireEvent('mousemove', this, e);
+ this.onDrag(e);
+ this.fireEvent('drag', this, e);
+ },
+
+ onMouseUp: function(e) {
+ var doc = Ext.getDoc(),
+ wasActive = this.active;
+
+ doc.un('mousemove', this.onMouseMove, this);
+ doc.un('mouseup', this.onMouseUp, this);
+ doc.un('selectstart', this.stopSelect, this);
+ e.preventDefault();
+ this.clearStart();
+ this.active = false;
+ delete this.elRegion;
+ this.fireEvent('mouseup', this, e);
+ if(wasActive){
+ this.onEnd(e);
+ this.fireEvent('dragend', this, e);
+ }
+ },
+
+ triggerStart: function(e) {
+ this.clearStart();
+ this.active = true;
+ this.onStart(e);
+ this.fireEvent('dragstart', this, e);
+ },
+
+ clearStart : function() {
+ if(this.timer){
+ clearTimeout(this.timer);
+ delete this.timer;
+ }
+ },
+
+ stopSelect : function(e) {
+ e.stopEvent();
+ return false;
+ },
+
+
+ onBeforeStart : function(e) {
+
+ },
+
+
+ onStart : function(xy) {
+
+ },
+
+
+ onDrag : function(e) {
+
+ },
+
+
+ onEnd : function(e) {
+
+ },
+
+
+ getDragTarget : function(){
+ return this.dragTarget;
+ },
+
+ getDragCt : function(){
+ return this.el;
+ },
+
+ getXY : function(constrain){
+ return constrain ?
+ this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
+ },
+
+ getOffset : function(constrain){
+ var xy = this.getXY(constrain),
+ s = this.startXY;
+ return [s[0]-xy[0], s[1]-xy[1]];
+ },
+
+ constrainModes: {
+ 'point' : function(xy){
+
+ if(!this.elRegion){
+ this.elRegion = this.getDragCt().getRegion();
+ }
+
+ var dr = this.dragRegion;
+
+ dr.left = xy[0];
+ dr.top = xy[1];
+ dr.right = xy[0];
+ dr.bottom = xy[1];
+
+ dr.constrainTo(this.elRegion);
+
+ return [dr.left, dr.top];
+ }
+ }
+});
+Ext.dd.ScrollManager = function(){
+ var ddm = Ext.dd.DragDropMgr;
+ var els = {};
+ var dragEl = null;
+ var proc = {};
+
+ var onStop = function(e){
+ dragEl = null;
+ clearProc();
+ };
+
+ var triggerRefresh = function(){
+ if(ddm.dragCurrent){
+ ddm.refreshCache(ddm.dragCurrent.groups);
+ }
+ };
+
+ var doScroll = function(){
+ if(ddm.dragCurrent){
+ var dds = Ext.dd.ScrollManager;
+ var inc = proc.el.ddScrollConfig ?
+ proc.el.ddScrollConfig.increment : dds.increment;
+ if(!dds.animate){
+ if(proc.el.scroll(proc.dir, inc)){
+ triggerRefresh();
+ }
+ }else{
+ proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
+ }
+ }
+ };
+
+ var clearProc = function(){
+ if(proc.id){
+ clearInterval(proc.id);
+ }
+ proc.id = 0;
+ proc.el = null;
+ proc.dir = "";
+ };
+
+ var startProc = function(el, dir){
+ clearProc();
+ proc.el = el;
+ proc.dir = dir;
+ var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
+ freq = (el.ddScrollConfig && el.ddScrollConfig.frequency)
+ ? el.ddScrollConfig.frequency
+ : Ext.dd.ScrollManager.frequency;
+
+ if (group === undefined || ddm.dragCurrent.ddGroup == group) {
+ proc.id = setInterval(doScroll, freq);
+ }
+ };
+
+ var onFire = function(e, isDrop){
+ if(isDrop || !ddm.dragCurrent){ return; }
+ var dds = Ext.dd.ScrollManager;
+ if(!dragEl || dragEl != ddm.dragCurrent){
+ dragEl = ddm.dragCurrent;
+
+ dds.refreshCache();
+ }
+
+ var xy = Ext.lib.Event.getXY(e);
+ var pt = new Ext.lib.Point(xy[0], xy[1]);
+ for(var id in els){
+ var el = els[id], r = el._region;
+ var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
+ if(r && r.contains(pt) && el.isScrollable()){
+ if(r.bottom - pt.y <= c.vthresh){
+ if(proc.el != el){
+ startProc(el, "down");
+ }
+ return;
+ }else if(r.right - pt.x <= c.hthresh){
+ if(proc.el != el){
+ startProc(el, "left");
+ }
+ return;
+ }else if(pt.y - r.top <= c.vthresh){
+ if(proc.el != el){
+ startProc(el, "up");
+ }
+ return;
+ }else if(pt.x - r.left <= c.hthresh){
+ if(proc.el != el){
+ startProc(el, "right");
+ }
+ return;
+ }
+ }
+ }
+ clearProc();
+ };
+
+ ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
+ ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
+
+ return {
+
+ register : function(el){
+ if(Ext.isArray(el)){
+ for(var i = 0, len = el.length; i < len; i++) {
+ this.register(el[i]);
+ }
+ }else{
+ el = Ext.get(el);
+ els[el.id] = el;
+ }
+ },
+
+
+ unregister : function(el){
+ if(Ext.isArray(el)){
+ for(var i = 0, len = el.length; i < len; i++) {
+ this.unregister(el[i]);
+ }
+ }else{
+ el = Ext.get(el);
+ delete els[el.id];
+ }
+ },
+
+
+ vthresh : 25,
+
+ hthresh : 25,
+
+
+ increment : 100,
+
+
+ frequency : 500,
+
+
+ animate: true,
+
+
+ animDuration: .4,
+
+
+ ddGroup: undefined,
+
+
+ refreshCache : function(){
+ for(var id in els){
+ if(typeof els[id] == 'object'){
+ els[id]._region = els[id].getRegion();
+ }
+ }
+ }
+ };
+}();
+Ext.dd.Registry = function(){
+ var elements = {};
+ var handles = {};
+ var autoIdSeed = 0;
+
+ var getId = function(el, autogen){
+ if(typeof el == "string"){
+ return el;
+ }
+ var id = el.id;
+ if(!id && autogen !== false){
+ id = "extdd-" + (++autoIdSeed);
+ el.id = id;
+ }
+ return id;
+ };
+
+ return {
+
+ register : function(el, data){
+ data = data || {};
+ if(typeof el == "string"){
+ el = document.getElementById(el);
+ }
+ data.ddel = el;
+ elements[getId(el)] = data;
+ if(data.isHandle !== false){
+ handles[data.ddel.id] = data;
+ }
+ if(data.handles){
+ var hs = data.handles;
+ for(var i = 0, len = hs.length; i < len; i++){
+ handles[getId(hs[i])] = data;
+ }
+ }
+ },
+
+
+ unregister : function(el){
+ var id = getId(el, false);
+ var data = elements[id];
+ if(data){
+ delete elements[id];
+ if(data.handles){
+ var hs = data.handles;
+ for(var i = 0, len = hs.length; i < len; i++){
+ delete handles[getId(hs[i], false)];
+ }
+ }
+ }
+ },
+
+
+ getHandle : function(id){
+ if(typeof id != "string"){
+ id = id.id;
+ }
+ return handles[id];
+ },
+
+
+ getHandleFromEvent : function(e){
+ var t = Ext.lib.Event.getTarget(e);
+ return t ? handles[t.id] : null;
+ },
+
+
+ getTarget : function(id){
+ if(typeof id != "string"){
+ id = id.id;
+ }
+ return elements[id];
+ },
+
+
+ getTargetFromEvent : function(e){
+ var t = Ext.lib.Event.getTarget(e);
+ return t ? elements[t.id] || handles[t.id] : null;
+ }
+ };
+}();
+Ext.dd.StatusProxy = function(config){
+ Ext.apply(this, config);
+ 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: !config || config.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(cssClass){
+ cssClass = cssClass || this.dropNotAllowed;
+ if(this.dropStatus != cssClass){
+ this.el.replaceClass(this.dropStatus, cssClass);
+ this.dropStatus = cssClass;
+ }
+ },
+
+
+ reset : function(clearGhost){
+ this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
+ this.dropStatus = this.dropNotAllowed;
+ if(clearGhost){
+ this.ghost.update("");
+ }
+ },
+
+
+ update : function(html){
+ if(typeof html == "string"){
+ this.ghost.update(html);
+ }else{
+ this.ghost.update("");
+ html.style.margin = "0";
+ this.ghost.dom.appendChild(html);
+ }
+ var el = this.ghost.dom.firstChild;
+ if(el){
+ Ext.fly(el).setStyle('float', 'none');
+ }
+ },
+
+
+ getEl : function(){
+ return this.el;
+ },
+
+
+ getGhost : function(){
+ return this.ghost;
+ },
+
+
+ hide : function(clear){
+ this.el.hide();
+ if(clear){
+ 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, callback, scope){
+ this.callback = callback;
+ this.scope = scope;
+ if(xy && this.animRepair !== false){
+ this.el.addClass("x-dd-drag-repair");
+ this.el.hideUnders(true);
+ this.anim = this.el.shift({
+ duration: this.repairDuration || .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;
+ },
+
+ destroy: function(){
+ Ext.destroy(this.ghost, this.el);
+ }
+};
+Ext.dd.DragSource = function(el, config){
+ this.el = Ext.get(el);
+ if(!this.dragData){
+ this.dragData = {};
+ }
+
+ Ext.apply(this, config);
+
+ if(!this.proxy){
+ this.proxy = new Ext.dd.StatusProxy();
+ }
+ 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 target = Ext.dd.DragDropMgr.getDDById(id);
+ this.cachedTarget = target;
+ if(this.beforeDragEnter(target, e, id) !== false){
+ if(target.isNotifyTarget){
+ var status = target.notifyEnter(this, e, this.dragData);
+ this.proxy.setStatus(status);
+ }else{
+ this.proxy.setStatus(this.dropAllowed);
+ }
+
+ if(this.afterDragEnter){
+
+ this.afterDragEnter(target, e, id);
+ }
+ }
+ },
+
+
+ beforeDragEnter : function(target, e, id){
+ return true;
+ },
+
+
+ alignElWithMouse: function() {
+ Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
+ this.proxy.sync();
+ },
+
+
+ onDragOver : function(e, id){
+ var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
+ if(this.beforeDragOver(target, e, id) !== false){
+ if(target.isNotifyTarget){
+ var status = target.notifyOver(this, e, this.dragData);
+ this.proxy.setStatus(status);
+ }
+
+ if(this.afterDragOver){
+
+ this.afterDragOver(target, e, id);
+ }
+ }
+ },
+
+
+ beforeDragOver : function(target, e, id){
+ return true;
+ },
+
+
+ onDragOut : function(e, id){
+ var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
+ if(this.beforeDragOut(target, e, id) !== false){
+ if(target.isNotifyTarget){
+ target.notifyOut(this, e, this.dragData);
+ }
+ this.proxy.reset();
+ if(this.afterDragOut){
+
+ this.afterDragOut(target, e, id);
+ }
+ }
+ this.cachedTarget = null;
+ },
+
+
+ beforeDragOut : function(target, e, id){
+ return true;
+ },
+
+
+ onDragDrop : function(e, id){
+ var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
+ if(this.beforeDragDrop(target, e, id) !== false){
+ if(target.isNotifyTarget){
+ if(target.notifyDrop(this, e, this.dragData)){
+ this.onValidDrop(target, e, id);
+ }else{
+ this.onInvalidDrop(target, e, id);
+ }
+ }else{
+ this.onValidDrop(target, e, id);
+ }
+
+ if(this.afterDragDrop){
+
+ this.afterDragDrop(target, e, id);
+ }
+ }
+ delete this.cachedTarget;
+ },
+
+
+ beforeDragDrop : function(target, e, id){
+ return true;
+ },
+
+
+ onValidDrop : function(target, e, id){
+ this.hideProxy();
+ if(this.afterValidDrop){
+
+ this.afterValidDrop(target, e, id);
+ }
+ },
+
+
+ getRepairXY : function(e, data){
+ return this.el.getXY();
+ },
+
+
+ onInvalidDrop : function(target, e, id){
+ this.beforeInvalidDrop(target, 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(target, e, id){
+ return true;
+ },
+
+
+ handleMouseDown : function(e){
+ if(this.dragging) {
+ return;
+ }
+ var data = this.getDragData(e);
+ if(data && this.onBeforeDrag(data, e) !== false){
+ this.dragData = data;
+ this.proxy.stop();
+ Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
+ }
+ },
+
+
+ onBeforeDrag : function(data, e){
+ return true;
+ },
+
+
+ onStartDrag : Ext.emptyFn,
+
+
+ startDrag : function(x, y){
+ this.proxy.reset();
+ this.dragging = true;
+ this.proxy.update("");
+ this.onInitDrag(x, y);
+ this.proxy.show();
+ },
+
+
+ onInitDrag : function(x, y){
+ var clone = this.el.dom.cloneNode(true);
+ clone.id = Ext.id();
+ this.proxy.update(clone);
+ this.onStartDrag(x, y);
+ 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(data, e){
+ },
+
+
+ autoOffset : function(x, y) {
+ this.setDelta(-12, -20);
+ },
+
+ destroy: function(){
+ Ext.dd.DragSource.superclass.destroy.call(this);
+ Ext.destroy(this.proxy);
+ }
+});
+Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
+
+ constructor : function(el, config){
+ this.el = Ext.get(el);
+
+ Ext.apply(this, config);
+
+ 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});
+ },
+
+
+
+
+ dropAllowed : "x-dd-drop-ok",
+
+ dropNotAllowed : "x-dd-drop-nodrop",
+
+
+ isTarget : true,
+
+
+ isNotifyTarget : true,
+
+
+ notifyEnter : function(dd, e, data){
+ if(this.overClass){
+ this.el.addClass(this.overClass);
+ }
+ return this.dropAllowed;
+ },
+
+
+ notifyOver : function(dd, e, data){
+ return this.dropAllowed;
+ },
+
+
+ notifyOut : function(dd, e, data){
+ if(this.overClass){
+ this.el.removeClass(this.overClass);
+ }
+ },
+
+
+ notifyDrop : function(dd, e, data){
+ return false;
+ },
+
+ destroy : function(){
+ Ext.dd.DropTarget.superclass.destroy.call(this);
+ if(this.containerScroll){
+ Ext.dd.ScrollManager.unregister(this.el);
+ }
+ }
+});
+Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
+
+ constructor : function(el, config){
+ Ext.dd.DragZone.superclass.constructor.call(this, el, config);
+ if(this.containerScroll){
+ Ext.dd.ScrollManager.register(this.el);
+ }
+ },
+
+
+
+
+
+
+ getDragData : function(e){
+ return Ext.dd.Registry.getHandleFromEvent(e);
+ },
+
+
+ onInitDrag : function(x, y){
+ this.proxy.update(this.dragData.ddel.cloneNode(true));
+ this.onStartDrag(x, y);
+ 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();
+ },
+
+ destroy : function(){
+ Ext.dd.DragZone.superclass.destroy.call(this);
+ if(this.containerScroll){
+ Ext.dd.ScrollManager.unregister(this.el);
+ }
+ }
+});
+Ext.dd.DropZone = function(el, config){
+ Ext.dd.DropZone.superclass.constructor.call(this, el, config);
+};
+
+Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
+
+ getTargetFromEvent : function(e){
+ return Ext.dd.Registry.getTargetFromEvent(e);
+ },
+
+
+ onNodeEnter : function(n, dd, e, data){
+
+ },
+
+
+ onNodeOver : function(n, dd, e, data){
+ return this.dropAllowed;
+ },
+
+
+ onNodeOut : function(n, dd, e, data){
+
+ },
+
+
+ onNodeDrop : function(n, dd, e, data){
+ return false;
+ },
+
+
+ onContainerOver : function(dd, e, data){
+ return this.dropNotAllowed;
+ },
+
+
+ onContainerDrop : function(dd, e, data){
+ return false;
+ },
+
+
+ notifyEnter : function(dd, e, data){
+ return this.dropNotAllowed;
+ },
+
+
+ notifyOver : function(dd, e, data){
+ var n = this.getTargetFromEvent(e);
+ if(!n){
+ if(this.lastOverNode){
+ this.onNodeOut(this.lastOverNode, dd, e, data);
+ this.lastOverNode = null;
+ }
+ return this.onContainerOver(dd, e, data);
+ }
+ if(this.lastOverNode != n){
+ if(this.lastOverNode){
+ this.onNodeOut(this.lastOverNode, dd, e, data);
+ }
+ this.onNodeEnter(n, dd, e, data);
+ this.lastOverNode = n;
+ }
+ return this.onNodeOver(n, dd, e, data);
+ },
+
+
+ notifyOut : function(dd, e, data){
+ if(this.lastOverNode){
+ this.onNodeOut(this.lastOverNode, dd, e, data);
+ this.lastOverNode = null;
+ }
+ },
+
+
+ notifyDrop : function(dd, e, data){
+ if(this.lastOverNode){
+ this.onNodeOut(this.lastOverNode, dd, e, data);
+ this.lastOverNode = null;
+ }
+ var n = this.getTargetFromEvent(e);
+ return n ?
+ this.onNodeDrop(n, dd, e, data) :
+ this.onContainerDrop(dd, e, data);
+ },
+
+
+ triggerCacheRefresh : function(){
+ Ext.dd.DDM.refreshCache(this.groups);
+ }
+});
+Ext.Element.addMethods({
+
+ initDD : function(group, config, overrides){
+ var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
+ return Ext.apply(dd, overrides);
+ },
+
+
+ initDDProxy : function(group, config, overrides){
+ var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
+ return Ext.apply(dd, overrides);
+ },
+
+
+ initDDTarget : function(group, config, overrides){
+ var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
+ return Ext.apply(dd, overrides);
+ }
+});
+
+Ext.data.Api = (function() {
+
+
+
+
+
+ var validActions = {};
+
+ return {
+
+ actions : {
+ create : 'create',
+ read : 'read',
+ update : 'update',
+ destroy : 'destroy'
+ },
+
+
+ restActions : {
+ create : 'POST',
+ read : 'GET',
+ update : 'PUT',
+ destroy : 'DELETE'
+ },
+
+
+ isAction : function(action) {
+ return (Ext.data.Api.actions[action]) ? true : false;
+ },
+
+
+ getVerb : function(name) {
+ if (validActions[name]) {
+ return validActions[name];
+ }
+ for (var verb in this.actions) {
+ if (this.actions[verb] === name) {
+ validActions[name] = verb;
+ break;
+ }
+ }
+ return (validActions[name] !== undefined) ? validActions[name] : null;
+ },
+
+
+ isValid : function(api){
+ var invalid = [];
+ var crud = this.actions;
+ for (var action in api) {
+ if (!(action in crud)) {
+ invalid.push(action);
+ }
+ }
+ return (!invalid.length) ? true : invalid;
+ },
+
+
+ hasUniqueUrl : function(proxy, verb) {
+ var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
+ var unique = true;
+ for (var action in proxy.api) {
+ if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
+ break;
+ }
+ }
+ return unique;
+ },
+
+
+ prepare : function(proxy) {
+ if (!proxy.api) {
+ proxy.api = {};
+ }
+ for (var verb in this.actions) {
+ var action = this.actions[verb];
+ proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
+ if (typeof(proxy.api[action]) == 'string') {
+ proxy.api[action] = {
+ url: proxy.api[action],
+ method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
+ };
+ }
+ }
+ },
+
+
+ restify : function(proxy) {
+ proxy.restful = true;
+ for (var verb in this.restActions) {
+ proxy.api[this.actions[verb]].method ||
+ (proxy.api[this.actions[verb]].method = this.restActions[verb]);
+ }
+
+
+ proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
+ var reader = o.reader;
+ var res = new Ext.data.Response({
+ action: action,
+ raw: response
+ });
+
+ switch (response.status) {
+ case 200:
+ return true;
+ break;
+ case 201:
+ if (Ext.isEmpty(res.raw.responseText)) {
+ res.success = true;
+ } else {
+
+ return true;
+ }
+ break;
+ case 204:
+ res.success = true;
+ res.data = null;
+ break;
+ default:
+ return true;
+ break;
+ }
+ if (res.success === true) {
+ this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
+ } else {
+ this.fireEvent('exception', this, 'remote', action, o, res, rs);
+ }
+ o.request.callback.call(o.request.scope, res.data, res, res.success);
+
+ return false;
+ }, proxy);
+ }
+ };
+})();
+
+
+Ext.data.Response = function(params, response) {
+ Ext.apply(this, params, {
+ raw: response
+ });
+};
+Ext.data.Response.prototype = {
+ message : null,
+ success : false,
+ status : null,
+ root : null,
+ raw : null,
+
+ getMessage : function() {
+ return this.message;
+ },
+ getSuccess : function() {
+ return this.success;
+ },
+ getStatus : function() {
+ return this.status;
+ },
+ getRoot : function() {
+ return this.root;
+ },
+ getRawResponse : function() {
+ return this.raw;
+ }
+};
+
+
+Ext.data.Api.Error = Ext.extend(Ext.Error, {
+ constructor : function(message, arg) {
+ this.arg = arg;
+ Ext.Error.call(this, message);
+ },
+ name: 'Ext.data.Api'
+});
+Ext.apply(Ext.data.Api.Error.prototype, {
+ lang: {
+ 'action-url-undefined': 'No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.',
+ 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
+ 'invalid-url': 'Invalid url. Please review your proxy configuration.',
+ 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
+ }
+});
+
+
+
+
+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(Ext.isDate(s)){
+ return s.getTime();
+ }
+ return Date.parse(String(s));
+ },
+
+
+ asFloat : function(s) {
+ var val = parseFloat(String(s).replace(/,/g, ""));
+ return isNaN(val) ? 0 : val;
+ },
+
+
+ asInt : function(s) {
+ var val = parseInt(String(s).replace(/,/g, ""), 10);
+ return isNaN(val) ? 0 : val;
+ }
+};
+Ext.data.Record = function(data, id){
+
+ this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
+ this.data = data || {};
+};
+
+
+Ext.data.Record.create = function(o){
+ var f = Ext.extend(Ext.data.Record, {});
+ var p = f.prototype;
+ p.fields = new Ext.util.MixedCollection(false, function(field){
+ return field.name;
+ });
+ for(var i = 0, len = o.length; i < len; i++){
+ p.fields.add(new Ext.data.Field(o[i]));
+ }
+ f.getField = function(name){
+ return p.fields.get(name);
+ };
+ return f;
+};
+
+Ext.data.Record.PREFIX = 'ext-record';
+Ext.data.Record.AUTO_ID = 1;
+Ext.data.Record.EDIT = 'edit';
+Ext.data.Record.REJECT = 'reject';
+Ext.data.Record.COMMIT = 'commit';
+
+
+
+Ext.data.Record.id = function(rec) {
+ rec.phantom = true;
+ return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
+};
+
+Ext.data.Record.prototype = {
+
+
+
+
+
+
+ dirty : false,
+ editing : false,
+ error : null,
+
+ modified : null,
+
+ phantom : false,
+
+
+ join : function(store){
+
+ this.store = store;
+ },
+
+
+ set : function(name, value){
+ var encode = Ext.isPrimitive(value) ? String : Ext.encode;
+ if(encode(this.data[name]) == encode(value)) {
+ return;
+ }
+ this.dirty = true;
+ if(!this.modified){
+ this.modified = {};
+ }
+ if(this.modified[name] === undefined){
+ this.modified[name] = this.data[name];
+ }
+ this.data[name] = value;
+ if(!this.editing){
+ this.afterEdit();
+ }
+ },
+
+
+ afterEdit : function(){
+ if (this.store != undefined && typeof this.store.afterEdit == "function") {
+ this.store.afterEdit(this);
+ }
+ },
+
+
+ afterReject : function(){
+ if(this.store){
+ this.store.afterReject(this);
+ }
+ },
+
+
+ afterCommit : function(){
+ if(this.store){
+ this.store.afterCommit(this);
+ }
+ },
+
+
+ get : function(name){
+ return this.data[name];
+ },
+
+
+ beginEdit : function(){
+ this.editing = true;
+ this.modified = this.modified || {};
+ },
+
+
+ cancelEdit : function(){
+ this.editing = false;
+ delete this.modified;
+ },
+
+
+ endEdit : function(){
+ this.editing = false;
+ if(this.dirty){
+ this.afterEdit();
+ }
+ },
+
+
+ reject : function(silent){
+ 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(silent !== true){
+ this.afterReject();
+ }
+ },
+
+
+ commit : function(silent){
+ this.dirty = false;
+ delete this.modified;
+ this.editing = false;
+ if(silent !== true){
+ this.afterCommit();
+ }
+ },
+
+
+ getChanges : function(){
+ var m = this.modified, cs = {};
+ for(var n in m){
+ if(m.hasOwnProperty(n)){
+ cs[n] = this.data[n];
+ }
+ }
+ return cs;
+ },
+
+
+ hasError : function(){
+ return this.error !== null;
+ },
+
+
+ clearError : function(){
+ this.error = null;
+ },
+
+
+ copy : function(newId) {
+ return new this.constructor(Ext.apply({}, this.data), newId || this.id);
+ },
+
+
+ isModified : function(fieldName){
+ return !!(this.modified && this.modified.hasOwnProperty(fieldName));
+ },
+
+
+ isValid : function() {
+ return this.fields.find(function(f) {
+ return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
+ },this) ? false : true;
+ },
+
+
+ markDirty : function(){
+ this.dirty = true;
+ if(!this.modified){
+ this.modified = {};
+ }
+ this.fields.each(function(f) {
+ this.modified[f.name] = this.data[f.name];
+ },this);
+ }
+};
+
+Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
+
+
+
+ register : function(){
+ for(var i = 0, s; (s = arguments[i]); i++){
+ this.add(s);
+ }
+ },
+
+
+ unregister : function(){
+ for(var i = 0, s; (s = arguments[i]); i++){
+ this.remove(this.lookup(s));
+ }
+ },
+
+
+ lookup : function(id){
+ if(Ext.isArray(id)){
+ var fields = ['field1'], expand = !Ext.isArray(id[0]);
+ if(!expand){
+ for(var i = 2, len = id[0].length; i <= len; ++i){
+ fields.push('field' + i);
+ }
+ }
+ return new Ext.data.ArrayStore({
+ fields: fields,
+ data: id,
+ expandData: expand,
+ autoDestroy: true,
+ autoCreated: true
+
+ });
+ }
+ return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
+ },
+
+
+ getKey : function(o){
+ return o.storeId;
+ }
+});
+Ext.data.Store = Ext.extend(Ext.util.Observable, {
+
+
+
+
+
+
+
+ writer : undefined,
+
+
+
+ remoteSort : false,
+
+
+ autoDestroy : false,
+
+
+ pruneModifiedRecords : false,
+
+
+ lastOptions : null,
+
+
+ autoSave : true,
+
+
+ batch : true,
+
+
+ restful: false,
+
+
+ paramNames : undefined,
+
+
+ defaultParamNames : {
+ start : 'start',
+ limit : 'limit',
+ sort : 'sort',
+ dir : 'dir'
+ },
+
+ isDestroyed: false,
+ hasMultiSort: false,
+
+
+ batchKey : '_ext_batch_',
+
+ constructor : function(config){
+
+
+
+
+ this.data = new Ext.util.MixedCollection(false);
+ this.data.getKey = function(o){
+ return o.id;
+ };
+
+
+
+ this.removed = [];
+
+ if(config && config.data){
+ this.inlineData = config.data;
+ delete config.data;
+ }
+
+ Ext.apply(this, config);
+
+
+ this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
+
+ this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
+
+ if((this.url || this.api) && !this.proxy){
+ this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
+ }
+
+ if (this.restful === true && this.proxy) {
+
+
+ this.batch = false;
+ Ext.data.Api.restify(this.proxy);
+ }
+
+ if(this.reader){
+ if(!this.recordType){
+ this.recordType = this.reader.recordType;
+ }
+ if(this.reader.onMetaChange){
+ this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
+ }
+ if (this.writer) {
+ if (this.writer instanceof(Ext.data.DataWriter) === false) {
+ this.writer = this.buildWriter(this.writer);
+ }
+ this.writer.meta = this.reader.meta;
+ this.pruneModifiedRecords = true;
+ }
+ }
+
+
+
+ if(this.recordType){
+
+ this.fields = this.recordType.prototype.fields;
+ }
+ this.modified = [];
+
+ this.addEvents(
+
+ 'datachanged',
+
+ 'metachange',
+
+ 'add',
+
+ 'remove',
+
+ 'update',
+
+ 'clear',
+
+ 'exception',
+
+ 'beforeload',
+
+ 'load',
+
+ 'loadexception',
+
+ 'beforewrite',
+
+ 'write',
+
+ 'beforesave',
+
+ 'save'
+
+ );
+
+ if(this.proxy){
+
+ this.relayEvents(this.proxy, ['loadexception', 'exception']);
+ }
+
+ if (this.writer) {
+ this.on({
+ scope: this,
+ add: this.createRecords,
+ remove: this.destroyRecord,
+ update: this.updateRecord,
+ clear: this.onClear
+ });
+ }
+
+ this.sortToggle = {};
+ if(this.sortField){
+ this.setDefaultSort(this.sortField, this.sortDir);
+ }else if(this.sortInfo){
+ this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
+ }
+
+ Ext.data.Store.superclass.constructor.call(this);
+
+ if(this.id){
+ this.storeId = this.id;
+ delete this.id;
+ }
+ if(this.storeId){
+ Ext.StoreMgr.register(this);
+ }
+ if(this.inlineData){
+ this.loadData(this.inlineData);
+ delete this.inlineData;
+ }else if(this.autoLoad){
+ this.load.defer(10, this, [
+ typeof this.autoLoad == 'object' ?
+ this.autoLoad : undefined]);
+ }
+
+ this.batchCounter = 0;
+ this.batches = {};
+ },
+
+
+ buildWriter : function(config) {
+ var klass = undefined,
+ type = (config.format || 'json').toLowerCase();
+ switch (type) {
+ case 'json':
+ klass = Ext.data.JsonWriter;
+ break;
+ case 'xml':
+ klass = Ext.data.XmlWriter;
+ break;
+ default:
+ klass = Ext.data.JsonWriter;
+ }
+ return new klass(config);
+ },
+
+
+ destroy : function(){
+ if(!this.isDestroyed){
+ if(this.storeId){
+ Ext.StoreMgr.unregister(this);
+ }
+ this.clearData();
+ this.data = null;
+ Ext.destroy(this.proxy);
+ this.reader = this.writer = null;
+ this.purgeListeners();
+ this.isDestroyed = true;
+ }
+ },
+
+
+ add : function(records) {
+ var i, len, record, index;
+
+ records = [].concat(records);
+ if (records.length < 1) {
+ return;
+ }
+
+ for (i = 0, len = records.length; i < len; i++) {
+ record = records[i];
+
+ record.join(this);
+
+ if (record.dirty || record.phantom) {
+ this.modified.push(record);
+ }
+ }
+
+ index = this.data.length;
+ this.data.addAll(records);
+
+ if (this.snapshot) {
+ this.snapshot.addAll(records);
+ }
+
+ this.fireEvent('add', this, records, index);
+ },
+
+
+ addSorted : function(record){
+ var index = this.findInsertIndex(record);
+ this.insert(index, record);
+ },
+
+
+ doUpdate: function(rec){
+ var id = rec.id;
+
+ this.getById(id).join(null);
+
+ this.data.replace(id, rec);
+ if (this.snapshot) {
+ this.snapshot.replace(id, rec);
+ }
+ rec.join(this);
+ this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
+ },
+
+
+ remove : function(record){
+ if(Ext.isArray(record)){
+ Ext.each(record, function(r){
+ this.remove(r);
+ }, this);
+ return;
+ }
+ var index = this.data.indexOf(record);
+ if(index > -1){
+ record.join(null);
+ this.data.removeAt(index);
+ }
+ if(this.pruneModifiedRecords){
+ this.modified.remove(record);
+ }
+ if(this.snapshot){
+ this.snapshot.remove(record);
+ }
+ if(index > -1){
+ this.fireEvent('remove', this, record, index);
+ }
+ },
+
+
+ removeAt : function(index){
+ this.remove(this.getAt(index));
+ },
+
+
+ removeAll : function(silent){
+ var items = [];
+ this.each(function(rec){
+ items.push(rec);
+ });
+ this.clearData();
+ if(this.snapshot){
+ this.snapshot.clear();
+ }
+ if(this.pruneModifiedRecords){
+ this.modified = [];
+ }
+ if (silent !== true) {
+ this.fireEvent('clear', this, items);
+ }
+ },
+
+
+ onClear: function(store, records){
+ Ext.each(records, function(rec, index){
+ this.destroyRecord(this, rec, index);
+ }, this);
+ },
+
+
+ insert : function(index, records) {
+ var i, len, record;
+
+ records = [].concat(records);
+ for (i = 0, len = records.length; i < len; i++) {
+ record = records[i];
+
+ this.data.insert(index + i, record);
+ record.join(this);
+
+ if (record.dirty || record.phantom) {
+ this.modified.push(record);
+ }
+ }
+
+ if (this.snapshot) {
+ this.snapshot.addAll(records);
+ }
+
+ this.fireEvent('add', this, records, index);
+ },
+
+
+ indexOf : function(record){
+ return this.data.indexOf(record);
+ },
+
+
+ indexOfId : function(id){
+ return this.data.indexOfKey(id);
+ },
+
+
+ getById : function(id){
+ return (this.snapshot || this.data).key(id);
+ },
+
+
+ getAt : function(index){
+ return this.data.itemAt(index);
+ },
+
+
+ getRange : function(start, end){
+ return this.data.getRange(start, end);
+ },
+
+
+ storeOptions : function(o){
+ o = Ext.apply({}, o);
+ delete o.callback;
+ delete o.scope;
+ this.lastOptions = o;
+ },
+
+
+ clearData: function(){
+ this.data.each(function(rec) {
+ rec.join(null);
+ });
+ this.data.clear();
+ },
+
+
+ load : function(options) {
+ options = Ext.apply({}, options);
+ this.storeOptions(options);
+ if(this.sortInfo && this.remoteSort){
+ var pn = this.paramNames;
+ options.params = Ext.apply({}, options.params);
+ options.params[pn.sort] = this.sortInfo.field;
+ options.params[pn.dir] = this.sortInfo.direction;
+ }
+ try {
+ return this.execute('read', null, options);
+ } catch(e) {
+ this.handleException(e);
+ return false;
+ }
+ },
+
+
+ updateRecord : function(store, record, action) {
+ if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
+ this.save();
+ }
+ },
+
+
+ createRecords : function(store, records, index) {
+ var modified = this.modified,
+ length = records.length,
+ record, i;
+
+ for (i = 0; i < length; i++) {
+ record = records[i];
+
+ if (record.phantom && record.isValid()) {
+ record.markDirty();
+
+ if (modified.indexOf(record) == -1) {
+ modified.push(record);
+ }
+ }
+ }
+ if (this.autoSave === true) {
+ this.save();
+ }
+ },
+
+
+ destroyRecord : function(store, record, index) {
+ if (this.modified.indexOf(record) != -1) {
+ this.modified.remove(record);
+ }
+ if (!record.phantom) {
+ this.removed.push(record);
+
+
+
+
+ record.lastIndex = index;
+
+ if (this.autoSave === true) {
+ this.save();
+ }
+ }
+ },
+
+
+ execute : function(action, rs, options, batch) {
+
+ if (!Ext.data.Api.isAction(action)) {
+ throw new Ext.data.Api.Error('execute', action);
+ }
+
+ options = Ext.applyIf(options||{}, {
+ params: {}
+ });
+ if(batch !== undefined){
+ this.addToBatch(batch);
+ }
+
+
+ var doRequest = true;
+
+ if (action === 'read') {
+ doRequest = this.fireEvent('beforeload', this, options);
+ Ext.applyIf(options.params, this.baseParams);
+ }
+ else {
+
+
+ if (this.writer.listful === true && this.restful !== true) {
+ rs = (Ext.isArray(rs)) ? rs : [rs];
+ }
+
+ else if (Ext.isArray(rs) && rs.length == 1) {
+ rs = rs.shift();
+ }
+
+ if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
+ this.writer.apply(options.params, this.baseParams, action, rs);
+ }
+ }
+ if (doRequest !== false) {
+
+ if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
+ options.params.xaction = action;
+ }
+
+
+
+
+
+ this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
+ }
+ return doRequest;
+ },
+
+
+ save : function() {
+ if (!this.writer) {
+ throw new Ext.data.Store.Error('writer-undefined');
+ }
+
+ var queue = [],
+ len,
+ trans,
+ batch,
+ data = {},
+ i;
+
+ if(this.removed.length){
+ queue.push(['destroy', this.removed]);
+ }
+
+
+ var rs = [].concat(this.getModifiedRecords());
+ if(rs.length){
+
+ var phantoms = [];
+ for(i = rs.length-1; i >= 0; i--){
+ if(rs[i].phantom === true){
+ var rec = rs.splice(i, 1).shift();
+ if(rec.isValid()){
+ phantoms.push(rec);
+ }
+ }else if(!rs[i].isValid()){
+ rs.splice(i,1);
+ }
+ }
+
+ if(phantoms.length){
+ queue.push(['create', phantoms]);
+ }
+
+
+ if(rs.length){
+ queue.push(['update', rs]);
+ }
+ }
+ len = queue.length;
+ if(len){
+ batch = ++this.batchCounter;
+ for(i = 0; i < len; ++i){
+ trans = queue[i];
+ data[trans[0]] = trans[1];
+ }
+ if(this.fireEvent('beforesave', this, data) !== false){
+ for(i = 0; i < len; ++i){
+ trans = queue[i];
+ this.doTransaction(trans[0], trans[1], batch);
+ }
+ return batch;
+ }
+ }
+ return -1;
+ },
+
+
+ doTransaction : function(action, rs, batch) {
+ function transaction(records) {
+ try{
+ this.execute(action, records, undefined, batch);
+ }catch (e){
+ this.handleException(e);
+ }
+ }
+ if(this.batch === false){
+ for(var i = 0, len = rs.length; i < len; i++){
+ transaction.call(this, rs[i]);
+ }
+ }else{
+ transaction.call(this, rs);
+ }
+ },
+
+
+ addToBatch : function(batch){
+ var b = this.batches,
+ key = this.batchKey + batch,
+ o = b[key];
+
+ if(!o){
+ b[key] = o = {
+ id: batch,
+ count: 0,
+ data: {}
+ };
+ }
+ ++o.count;
+ },
+
+ removeFromBatch : function(batch, action, data){
+ var b = this.batches,
+ key = this.batchKey + batch,
+ o = b[key],
+ arr;
+
+
+ if(o){
+ arr = o.data[action] || [];
+ o.data[action] = arr.concat(data);
+ if(o.count === 1){
+ data = o.data;
+ delete b[key];
+ this.fireEvent('save', this, batch, data);
+ }else{
+ --o.count;
+ }
+ }
+ },
+
+
+
+ createCallback : function(action, rs, batch) {
+ var actions = Ext.data.Api.actions;
+ return (action == 'read') ? this.loadRecords : function(data, response, success) {
+
+ this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
+
+ if (success === true) {
+ this.fireEvent('write', this, action, data, response, rs);
+ }
+ this.removeFromBatch(batch, action, data);
+ };
+ },
+
+
+
+
+ clearModified : function(rs) {
+ if (Ext.isArray(rs)) {
+ for (var n=rs.length-1;n>=0;n--) {
+ this.modified.splice(this.modified.indexOf(rs[n]), 1);
+ }
+ } else {
+ this.modified.splice(this.modified.indexOf(rs), 1);
+ }
+ },
+
+
+ reMap : function(record) {
+ if (Ext.isArray(record)) {
+ for (var i = 0, len = record.length; i < len; i++) {
+ this.reMap(record[i]);
+ }
+ } else {
+ delete this.data.map[record._phid];
+ this.data.map[record.id] = record;
+ var index = this.data.keys.indexOf(record._phid);
+ this.data.keys.splice(index, 1, record.id);
+ delete record._phid;
+ }
+ },
+
+
+ onCreateRecords : function(success, rs, data) {
+ if (success === true) {
+ try {
+ this.reader.realize(rs, data);
+ }
+ catch (e) {
+ this.handleException(e);
+ if (Ext.isArray(rs)) {
+
+ this.onCreateRecords(success, rs, data);
+ }
+ }
+ }
+ },
+
+
+ onUpdateRecords : function(success, rs, data) {
+ if (success === true) {
+ try {
+ this.reader.update(rs, data);
+ } catch (e) {
+ this.handleException(e);
+ if (Ext.isArray(rs)) {
+
+ this.onUpdateRecords(success, rs, data);
+ }
+ }
+ }
+ },
+
+
+ onDestroyRecords : function(success, rs, data) {
+
+ rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
+ for (var i=0,len=rs.length;i<len;i++) {
+ this.removed.splice(this.removed.indexOf(rs[i]), 1);
+ }
+ if (success === false) {
+
+
+ for (i=rs.length-1;i>=0;i--) {
+ this.insert(rs[i].lastIndex, rs[i]);
+ }
+ }
+ },
+
+
+ handleException : function(e) {
+
+ Ext.handleError(e);
+ },
+
+
+ reload : function(options){
+ this.load(Ext.applyIf(options||{}, this.lastOptions));
+ },
+
+
+
+ loadRecords : function(o, options, success){
+ var i, len;
+
+ if (this.isDestroyed === true) {
+ return;
+ }
+ if(!o || success === false){
+ if(success !== false){
+ this.fireEvent('load', this, [], options);
+ }
+ if(options.callback){
+ options.callback.call(options.scope || this, [], options, false, o);
+ }
+ return;
+ }
+ var r = o.records, t = o.totalRecords || r.length;
+ if(!options || options.add !== true){
+ if(this.pruneModifiedRecords){
+ this.modified = [];
+ }
+ for(i = 0, len = r.length; i < len; i++){
+ r[i].join(this);
+ }
+ if(this.snapshot){
+ this.data = this.snapshot;
+ delete this.snapshot;
+ }
+ this.clearData();
+ this.data.addAll(r);
+ this.totalLength = t;
+ this.applySort();
+ this.fireEvent('datachanged', this);
+ }else{
+ var toAdd = [],
+ rec,
+ cnt = 0;
+ for(i = 0, len = r.length; i < len; ++i){
+ rec = r[i];
+ if(this.indexOfId(rec.id) > -1){
+ this.doUpdate(rec);
+ }else{
+ toAdd.push(rec);
+ ++cnt;
+ }
+ }
+ this.totalLength = Math.max(t, this.data.length + cnt);
+ this.add(toAdd);
+ }
+ this.fireEvent('load', this, r, options);
+ if(options.callback){
+ options.callback.call(options.scope || this, r, options, true);
+ }
+ },
+
+
+ loadData : function(o, append){
+ var r = this.reader.readRecords(o);
+ this.loadRecords(r, {add: append}, 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.multiSortInfo) && !this.remoteSort) {
+ this.sortData();
+ }
+ },
+
+
+ sortData : function() {
+ var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
+ direction = sortInfo.direction || "ASC",
+ sorters = sortInfo.sorters,
+ sortFns = [];
+
+
+ if (!this.hasMultiSort) {
+ sorters = [{direction: direction, field: sortInfo.field}];
+ }
+
+
+ for (var i=0, j = sorters.length; i < j; i++) {
+ sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
+ }
+
+ if (sortFns.length == 0) {
+ return;
+ }
+
+
+
+ var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
+
+
+ var fn = function(r1, r2) {
+ var result = sortFns[0].call(this, r1, r2);
+
+
+ if (sortFns.length > 1) {
+ for (var i=1, j = sortFns.length; i < j; i++) {
+ result = result || sortFns[i].call(this, r1, r2);
+ }
+ }
+
+ return directionModifier * result;
+ };
+
+
+ this.data.sort(direction, fn);
+ if (this.snapshot && this.snapshot != this.data) {
+ this.snapshot.sort(direction, fn);
+ }
+ },
+
+
+ createSortFunction: function(field, direction) {
+ direction = direction || "ASC";
+ var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
+
+ var sortType = this.fields.get(field).sortType;
+
+
+
+ return function(r1, r2) {
+ var v1 = sortType(r1.data[field]),
+ v2 = sortType(r2.data[field]);
+
+ return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
+ };
+ },
+
+
+ setDefaultSort : function(field, dir) {
+ dir = dir ? dir.toUpperCase() : 'ASC';
+ this.sortInfo = {field: field, direction: dir};
+ this.sortToggle[field] = dir;
+ },
+
+
+ sort : function(fieldName, dir) {
+ if (Ext.isArray(arguments[0])) {
+ return this.multiSort.call(this, fieldName, dir);
+ } else {
+ return this.singleSort(fieldName, dir);
+ }
+ },
+
+
+ singleSort: function(fieldName, dir) {
+ var field = this.fields.get(fieldName);
+ if (!field) {
+ return false;
+ }
+
+ var name = field.name,
+ sortInfo = this.sortInfo || null,
+ sortToggle = this.sortToggle ? this.sortToggle[name] : null;
+
+ if (!dir) {
+ if (sortInfo && sortInfo.field == name) {
+ dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
+ } else {
+ dir = field.sortDir;
+ }
+ }
+
+ this.sortToggle[name] = dir;
+ this.sortInfo = {field: name, direction: dir};
+ this.hasMultiSort = false;
+
+ if (this.remoteSort) {
+ if (!this.load(this.lastOptions)) {
+ if (sortToggle) {
+ this.sortToggle[name] = sortToggle;
+ }
+ if (sortInfo) {
+ this.sortInfo = sortInfo;
+ }
+ }
+ } else {
+ this.applySort();
+ this.fireEvent('datachanged', this);
+ }
+ return true;
+ },
+
+
+ multiSort: function(sorters, direction) {
+ this.hasMultiSort = true;
+ direction = direction || "ASC";
+
+
+ if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
+ direction = direction.toggle("ASC", "DESC");
+ }
+
+
+ this.multiSortInfo = {
+ sorters : sorters,
+ direction: direction
+ };
+
+ if (this.remoteSort) {
+ this.singleSort(sorters[0].field, sorters[0].direction);
+
+ } else {
+ this.applySort();
+ this.fireEvent('datachanged', this);
+ }
+ },
+
+
+ each : function(fn, scope){
+ this.data.each(fn, scope);
+ },
+
+
+ getModifiedRecords : function(){
+ return this.modified;
+ },
+
+
+ sum : function(property, start, end){
+ var rs = this.data.items, v = 0;
+ start = start || 0;
+ end = (end || end === 0) ? end : rs.length-1;
+
+ for(var i = start; i <= end; i++){
+ v += (rs[i].data[property] || 0);
+ }
+ return v;
+ },
+
+
+ createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
+ if(Ext.isEmpty(value, false)){
+ return false;
+ }
+ value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
+ return function(r) {
+ return value.test(r.data[property]);
+ };
+ },
+
+
+ createMultipleFilterFn: function(filters) {
+ return function(record) {
+ var isMatch = true;
+
+ for (var i=0, j = filters.length; i < j; i++) {
+ var filter = filters[i],
+ fn = filter.fn,
+ scope = filter.scope;
+
+ isMatch = isMatch && fn.call(scope, record);
+ }
+
+ return isMatch;
+ };
+ },
+
+
+ filter : function(property, value, anyMatch, caseSensitive, exactMatch){
+ var fn;
+
+ if (Ext.isObject(property)) {
+ property = [property];
+ }
+
+ if (Ext.isArray(property)) {
+ var filters = [];
+
+
+ for (var i=0, j = property.length; i < j; i++) {
+ var filter = property[i],
+ func = filter.fn,
+ scope = filter.scope || this;
+
+
+ if (!Ext.isFunction(func)) {
+ func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
+ }
+
+ filters.push({fn: func, scope: scope});
+ }
+
+ fn = this.createMultipleFilterFn(filters);
+ } else {
+
+ fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
+ }
+
+ return fn ? this.filterBy(fn) : this.clearFilter();
+ },
+
+
+ filterBy : function(fn, scope){
+ this.snapshot = this.snapshot || this.data;
+ this.data = this.queryBy(fn, scope || this);
+ this.fireEvent('datachanged', this);
+ },
+
+
+ clearFilter : function(suppressEvent){
+ if(this.isFiltered()){
+ this.data = this.snapshot;
+ delete this.snapshot;
+ if(suppressEvent !== true){
+ this.fireEvent('datachanged', this);
+ }
+ }
+ },
+
+
+ isFiltered : function(){
+ return !!this.snapshot && this.snapshot != this.data;
+ },
+
+
+ query : function(property, value, anyMatch, caseSensitive){
+ var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
+ return fn ? this.queryBy(fn) : this.data.clone();
+ },
+
+
+ queryBy : function(fn, scope){
+ var data = this.snapshot || this.data;
+ return data.filterBy(fn, scope||this);
+ },
+
+
+ find : function(property, value, start, anyMatch, caseSensitive){
+ var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
+ return fn ? this.data.findIndexBy(fn, null, start) : -1;
+ },
+
+
+ findExact: function(property, value, start){
+ return this.data.findIndexBy(function(rec){
+ return rec.get(property) === value;
+ }, this, start);
+ },
+
+
+ findBy : function(fn, scope, start){
+ return this.data.findIndexBy(fn, scope, start);
+ },
+
+
+ collect : function(dataIndex, allowNull, bypassFilter){
+ var d = (bypassFilter === true && this.snapshot) ?
+ this.snapshot.items : this.data.items;
+ var v, sv, r = [], l = {};
+ for(var i = 0, len = d.length; i < len; i++){
+ v = d[i].data[dataIndex];
+ sv = String(v);
+ if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
+ l[sv] = true;
+ r[r.length] = v;
+ }
+ }
+ return r;
+ },
+
+
+ afterEdit : function(record){
+ if(this.modified.indexOf(record) == -1){
+ this.modified.push(record);
+ }
+ this.fireEvent('update', this, record, Ext.data.Record.EDIT);
+ },
+
+
+ afterReject : function(record){
+ this.modified.remove(record);
+ this.fireEvent('update', this, record, Ext.data.Record.REJECT);
+ },
+
+
+ afterCommit : function(record){
+ this.modified.remove(record);
+ this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
+ },
+
+
+ commitChanges : function(){
+ var modified = this.modified.slice(0),
+ length = modified.length,
+ i;
+
+ for (i = 0; i < length; i++){
+ modified[i].commit();
+ }
+
+ this.modified = [];
+ this.removed = [];
+ },
+
+
+ rejectChanges : function() {
+ var modified = this.modified.slice(0),
+ removed = this.removed.slice(0).reverse(),
+ mLength = modified.length,
+ rLength = removed.length,
+ i;
+
+ for (i = 0; i < mLength; i++) {
+ modified[i].reject();
+ }
+
+ for (i = 0; i < rLength; i++) {
+ this.insert(removed[i].lastIndex || 0, removed[i]);
+ removed[i].reject();
+ }
+
+ this.modified = [];
+ this.removed = [];
+ },
+
+
+ onMetaChange : function(meta){
+ this.recordType = this.reader.recordType;
+ this.fields = this.recordType.prototype.fields;
+ delete this.snapshot;
+ if(this.reader.meta.sortInfo){
+ this.sortInfo = this.reader.meta.sortInfo;
+ }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
+ delete this.sortInfo;
+ }
+ if(this.writer){
+ this.writer.meta = this.reader.meta;
+ }
+ this.modified = [];
+ this.fireEvent('metachange', this, this.reader.meta);
+ },
+
+
+ findInsertIndex : function(record){
+ this.suspendEvents();
+ var data = this.data.clone();
+ this.data.add(record);
+ this.applySort();
+ var index = this.data.indexOf(record);
+ this.data = data;
+ this.resumeEvents();
+ return index;
+ },
+
+
+ setBaseParam : function (name, value){
+ this.baseParams = this.baseParams || {};
+ this.baseParams[name] = value;
+ }
+});
+
+Ext.reg('store', Ext.data.Store);
+
+
+Ext.data.Store.Error = Ext.extend(Ext.Error, {
+ name: 'Ext.data.Store'
+});
+Ext.apply(Ext.data.Store.Error.prototype, {
+ lang: {
+ 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
+ }
+});
+
+Ext.data.Field = Ext.extend(Object, {
+
+ constructor : function(config){
+ if(Ext.isString(config)){
+ config = {name: config};
+ }
+ Ext.apply(this, config);
+
+ var types = Ext.data.Types,
+ st = this.sortType,
+ t;
+
+ if(this.type){
+ if(Ext.isString(this.type)){
+ this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
+ }
+ }else{
+ this.type = types.AUTO;
+ }
+
+
+ if(Ext.isString(st)){
+ this.sortType = Ext.data.SortTypes[st];
+ }else if(Ext.isEmpty(st)){
+ this.sortType = this.type.sortType;
+ }
+
+ if(!this.convert){
+ this.convert = this.type.convert;
+ }
+ },
+
+
+
+
+
+ dateFormat: null,
+
+
+ useNull: false,
+
+
+ defaultValue: "",
+
+ mapping: null,
+
+ sortType : null,
+
+ sortDir : "ASC",
+
+ allowBlank : true
+});
+
+Ext.data.DataReader = function(meta, recordType){
+
+ this.meta = meta;
+
+ this.recordType = Ext.isArray(recordType) ?
+ Ext.data.Record.create(recordType) : recordType;
+
+
+ if (this.recordType){
+ this.buildExtractors();
+ }
+};
+
+Ext.data.DataReader.prototype = {
+
+
+ getTotal: Ext.emptyFn,
+
+ getRoot: Ext.emptyFn,
+
+ getMessage: Ext.emptyFn,
+
+ getSuccess: Ext.emptyFn,
+
+ getId: Ext.emptyFn,
+
+ buildExtractors : Ext.emptyFn,
+
+ extractValues : Ext.emptyFn,
+
+
+ realize: function(rs, data){
+ if (Ext.isArray(rs)) {
+ for (var i = rs.length - 1; i >= 0; i--) {
+
+ if (Ext.isArray(data)) {
+ this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
+ }
+ else {
+
+
+ this.realize(rs.splice(i,1).shift(), data);
+ }
+ }
+ }
+ else {
+
+ if (Ext.isArray(data) && data.length == 1) {
+ data = data.shift();
+ }
+ if (!this.isData(data)) {
+
+
+ throw new Ext.data.DataReader.Error('realize', rs);
+ }
+ rs.phantom = false;
+ rs._phid = rs.id;
+ rs.id = this.getId(data);
+ rs.data = data;
+
+ rs.commit();
+ rs.store.reMap(rs);
+ }
+ },
+
+
+ update : function(rs, data) {
+ if (Ext.isArray(rs)) {
+ for (var i=rs.length-1; i >= 0; i--) {
+ if (Ext.isArray(data)) {
+ this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
+ }
+ else {
+
+
+ this.update(rs.splice(i,1).shift(), data);
+ }
+ }
+ }
+ else {
+
+ if (Ext.isArray(data) && data.length == 1) {
+ data = data.shift();
+ }
+ if (this.isData(data)) {
+ rs.data = Ext.apply(rs.data, data);
+ }
+ rs.commit();
+ }
+ },
+
+
+ extractData : function(root, returnRecords) {
+
+ var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
+
+ var rs = [];
+
+
+
+ if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
+ root = [root];
+ }
+ var f = this.recordType.prototype.fields,
+ fi = f.items,
+ fl = f.length,
+ rs = [];
+ if (returnRecords === true) {
+ var Record = this.recordType;
+ for (var i = 0; i < root.length; i++) {
+ var n = root[i];
+ var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
+ record[rawName] = n;
+ rs.push(record);
+ }
+ }
+ else {
+ for (var i = 0; i < root.length; i++) {
+ var data = this.extractValues(root[i], fi, fl);
+ data[this.meta.idProperty] = this.getId(root[i]);
+ rs.push(data);
+ }
+ }
+ return rs;
+ },
+
+
+ isData : function(data) {
+ return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
+ },
+
+
+ onMetaChange : function(meta){
+ delete this.ef;
+ this.meta = meta;
+ this.recordType = Ext.data.Record.create(meta.fields);
+ this.buildExtractors();
+ }
+};
+
+
+Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
+ constructor : function(message, arg) {
+ this.arg = arg;
+ Ext.Error.call(this, message);
+ },
+ name: 'Ext.data.DataReader'
+});
+Ext.apply(Ext.data.DataReader.Error.prototype, {
+ lang : {
+ 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
+ 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
+ 'invalid-response': "#readResponse received an invalid response from the server."
+ }
+});
+
+Ext.data.DataWriter = function(config){
+ Ext.apply(this, config);
+};
+Ext.data.DataWriter.prototype = {
+
+
+ writeAllFields : false,
+
+ listful : false,
+
+
+ apply : function(params, baseParams, action, rs) {
+ var data = [],
+ renderer = action + 'Record';
+
+ if (Ext.isArray(rs)) {
+ Ext.each(rs, function(rec){
+ data.push(this[renderer](rec));
+ }, this);
+ }
+ else if (rs instanceof Ext.data.Record) {
+ data = this[renderer](rs);
+ }
+ this.render(params, baseParams, data);
+ },
+
+
+ render : Ext.emptyFn,
+
+
+ updateRecord : Ext.emptyFn,
+
+
+ createRecord : Ext.emptyFn,
+
+
+ destroyRecord : Ext.emptyFn,
+
+
+ toHash : function(rec, config) {
+ var map = rec.fields.map,
+ data = {},
+ raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
+ m;
+ Ext.iterate(raw, function(prop, value){
+ if((m = map[prop])){
+ data[m.mapping ? m.mapping : m.name] = value;
+ }
+ });
+
+
+
+ if (rec.phantom) {
+ if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
+ delete data[this.meta.idProperty];
+ }
+ } else {
+ data[this.meta.idProperty] = rec.id;
+ }
+ return data;
+ },
+
+
+ toArray : function(data) {
+ var fields = [];
+ Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
+ return fields;
+ }
+};
+Ext.data.DataProxy = function(conn){
+
+
+ conn = conn || {};
+
+
+
+
+
+ this.api = conn.api;
+ this.url = conn.url;
+ this.restful = conn.restful;
+ this.listeners = conn.listeners;
+
+
+ this.prettyUrls = conn.prettyUrls;
+
+
+
+ this.addEvents(
+
+ 'exception',
+
+ 'beforeload',
+
+ 'load',
+
+ 'loadexception',
+
+ 'beforewrite',
+
+ 'write'
+ );
+ Ext.data.DataProxy.superclass.constructor.call(this);
+
+
+ try {
+ Ext.data.Api.prepare(this);
+ } catch (e) {
+ if (e instanceof Ext.data.Api.Error) {
+ e.toConsole();
+ }
+ }
+
+ Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
+};
+
+Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
+
+ restful: false,
+
+
+ setApi : function() {
+ if (arguments.length == 1) {
+ var valid = Ext.data.Api.isValid(arguments[0]);
+ if (valid === true) {
+ this.api = arguments[0];
+ }
+ else {
+ throw new Ext.data.Api.Error('invalid', valid);
+ }
+ }
+ else if (arguments.length == 2) {
+ if (!Ext.data.Api.isAction(arguments[0])) {
+ throw new Ext.data.Api.Error('invalid', arguments[0]);
+ }
+ this.api[arguments[0]] = arguments[1];
+ }
+ Ext.data.Api.prepare(this);
+ },
+
+
+ isApiAction : function(action) {
+ return (this.api[action]) ? true : false;
+ },
+
+
+ request : function(action, rs, params, reader, callback, scope, options) {
+ if (!this.api[action] && !this.load) {
+ throw new Ext.data.DataProxy.Error('action-undefined', action);
+ }
+ params = params || {};
+ if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
+ this.doRequest.apply(this, arguments);
+ }
+ else {
+ callback.call(scope || this, null, options, false);
+ }
+ },
+
+
+
+ load : null,
+
+
+ doRequest : function(action, rs, params, reader, callback, scope, options) {
+
+
+
+ this.load(params, reader, callback, scope, options);
+ },
+
+
+ onRead : Ext.emptyFn,
+
+ onWrite : Ext.emptyFn,
+
+ buildUrl : function(action, record) {
+ record = record || null;
+
+
+
+
+ var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
+ if (!url) {
+ throw new Ext.data.Api.Error('invalid-url', action);
+ }
+
+
+
+
+
+
+
+ var provides = null;
+ var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
+ if (m) {
+ provides = m[2];
+ url = m[1];
+ }
+
+ if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
+ url += '/' + record.id;
+ }
+ return (provides === null) ? url : url + provides;
+ },
+
+
+ destroy: function(){
+ this.purgeListeners();
+ }
+});
+
+
+
+Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
+Ext.util.Observable.call(Ext.data.DataProxy);
+
+
+Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
+ constructor : function(message, arg) {
+ this.arg = arg;
+ Ext.Error.call(this, message);
+ },
+ name: 'Ext.data.DataProxy'
+});
+Ext.apply(Ext.data.DataProxy.Error.prototype, {
+ lang: {
+ 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
+ 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
+ }
+});
+
+
+
+Ext.data.Request = function(params) {
+ Ext.apply(this, params);
+};
+Ext.data.Request.prototype = {
+
+ action : undefined,
+
+ rs : undefined,
+
+ params: undefined,
+
+ callback : Ext.emptyFn,
+
+ scope : undefined,
+
+ reader : undefined
+};
+
+Ext.data.Response = function(params) {
+ Ext.apply(this, params);
+};
+Ext.data.Response.prototype = {
+
+ action: undefined,
+
+ success : undefined,
+
+ message : undefined,
+
+ data: undefined,
+
+ raw: undefined,
+
+ records: undefined
+};
+
+Ext.data.ScriptTagProxy = function(config){
+ Ext.apply(this, config);
+
+ Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
+
+ 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,
+
+
+ doRequest : function(action, rs, params, reader, callback, scope, arg) {
+ var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
+
+ var url = this.buildUrl(action, rs);
+ if (!url) {
+ throw new Ext.data.Api.Error('invalid-url', url);
+ }
+ url = Ext.urlAppend(url, p);
+
+ if(this.nocache){
+ url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
+ }
+ var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
+ var trans = {
+ id : transId,
+ action: action,
+ cb : "stcCallback"+transId,
+ scriptId : "stcScript"+transId,
+ params : params,
+ arg : arg,
+ url : url,
+ callback : callback,
+ scope : scope,
+ reader : reader
+ };
+ window[trans.cb] = this.createCallback(action, rs, trans);
+ url += String.format("&{0}={1}", this.callbackParam, trans.cb);
+ if(this.autoAbort !== false){
+ this.abort();
+ }
+
+ trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
+
+ var script = document.createElement("script");
+ script.setAttribute("src", url);
+ script.setAttribute("type", "text/javascript");
+ script.setAttribute("id", trans.scriptId);
+ this.head.appendChild(script);
+
+ this.trans = trans;
+ },
+
+
+ createCallback : function(action, rs, trans) {
+ var self = this;
+ return function(res) {
+ self.trans = false;
+ self.destroyTrans(trans, true);
+ if (action === Ext.data.Api.actions.read) {
+ self.onRead.call(self, action, trans, res);
+ } else {
+ self.onWrite.call(self, action, trans, res, rs);
+ }
+ };
+ },
+
+ onRead : function(action, trans, res) {
+ var result;
+ try {
+ result = trans.reader.readRecords(res);
+ }catch(e){
+
+ this.fireEvent("loadexception", this, trans, res, e);
+
+ this.fireEvent('exception', this, 'response', action, trans, res, e);
+ trans.callback.call(trans.scope||window, null, trans.arg, false);
+ return;
+ }
+ if (result.success === false) {
+
+ this.fireEvent('loadexception', this, trans, res);
+
+ this.fireEvent('exception', this, 'remote', action, trans, res, null);
+ } else {
+ this.fireEvent("load", this, res, trans.arg);
+ }
+ trans.callback.call(trans.scope||window, result, trans.arg, result.success);
+ },
+
+ onWrite : function(action, trans, response, rs) {
+ var reader = trans.reader;
+ try {
+
+ var res = reader.readResponse(action, response);
+ } catch (e) {
+ this.fireEvent('exception', this, 'response', action, trans, res, e);
+ trans.callback.call(trans.scope||window, null, res, false);
+ return;
+ }
+ if(!res.success === true){
+ this.fireEvent('exception', this, 'remote', action, trans, res, rs);
+ trans.callback.call(trans.scope||window, null, res, false);
+ return;
+ }
+ this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
+ trans.callback.call(trans.scope||window, res.data, res, true);
+ },
+
+
+ isLoading : function(){
+ return this.trans ? true : false;
+ },
+
+
+ abort : function(){
+ if(this.isLoading()){
+ this.destroyTrans(this.trans);
+ }
+ },
+
+
+ destroyTrans : function(trans, isLoaded){
+ this.head.removeChild(document.getElementById(trans.scriptId));
+ clearTimeout(trans.timeoutId);
+ if(isLoaded){
+ window[trans.cb] = undefined;
+ try{
+ delete window[trans.cb];
+ }catch(e){}
+ }else{
+
+ window[trans.cb] = function(){
+ window[trans.cb] = undefined;
+ try{
+ delete window[trans.cb];
+ }catch(e){}
+ };
+ }
+ },
+
+
+ handleFailure : function(trans){
+ this.trans = false;
+ this.destroyTrans(trans, false);
+ if (trans.action === Ext.data.Api.actions.read) {
+
+ this.fireEvent("loadexception", this, null, trans.arg);
+ }
+
+ this.fireEvent('exception', this, 'response', trans.action, {
+ response: null,
+ options: trans.arg
+ });
+ trans.callback.call(trans.scope||window, null, trans.arg, false);
+ },
+
+
+ destroy: function(){
+ this.abort();
+ Ext.data.ScriptTagProxy.superclass.destroy.call(this);
+ }
+});
+Ext.data.HttpProxy = function(conn){
+ Ext.data.HttpProxy.superclass.constructor.call(this, conn);
+
+
+ this.conn = conn;
+
+
+
+
+
+ this.conn.url = null;
+
+ this.useAjax = !conn || !conn.events;
+
+
+ var actions = Ext.data.Api.actions;
+ this.activeRequest = {};
+ for (var verb in actions) {
+ this.activeRequest[actions[verb]] = undefined;
+ }
+};
+
+Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
+
+ getConnection : function() {
+ return this.useAjax ? Ext.Ajax : this.conn;
+ },
+
+
+ setUrl : function(url, makePermanent) {
+ this.conn.url = url;
+ if (makePermanent === true) {
+ this.url = url;
+ this.api = null;
+ Ext.data.Api.prepare(this);
+ }
+ },
+
+
+ doRequest : function(action, rs, params, reader, cb, scope, arg) {
+ var o = {
+ method: (this.api[action]) ? this.api[action]['method'] : undefined,
+ request: {
+ callback : cb,
+ scope : scope,
+ arg : arg
+ },
+ reader: reader,
+ callback : this.createCallback(action, rs),
+ scope: this
+ };
+
+
+
+ if (params.jsonData) {
+ o.jsonData = params.jsonData;
+ } else if (params.xmlData) {
+ o.xmlData = params.xmlData;
+ } else {
+ o.params = params || {};
+ }
+
+
+
+ this.conn.url = this.buildUrl(action, rs);
+
+ if(this.useAjax){
+
+ Ext.applyIf(o, this.conn);
+
+
+ if (action == Ext.data.Api.actions.read && this.activeRequest[action]) {
+ Ext.Ajax.abort(this.activeRequest[action]);
+ }
+ this.activeRequest[action] = Ext.Ajax.request(o);
+ }else{
+ this.conn.request(o);
+ }
+
+ this.conn.url = null;
+ },
+
+
+ createCallback : function(action, rs) {
+ return function(o, success, response) {
+ this.activeRequest[action] = undefined;
+ if (!success) {
+ if (action === Ext.data.Api.actions.read) {
+
+
+ this.fireEvent('loadexception', this, o, response);
+ }
+ this.fireEvent('exception', this, 'response', action, o, response);
+ o.request.callback.call(o.request.scope, null, o.request.arg, false);
+ return;
+ }
+ if (action === Ext.data.Api.actions.read) {
+ this.onRead(action, o, response);
+ } else {
+ this.onWrite(action, o, response, rs);
+ }
+ };
+ },
+
+
+ onRead : function(action, o, response) {
+ var result;
+ try {
+ result = o.reader.read(response);
+ }catch(e){
+
+
+ this.fireEvent('loadexception', this, o, response, e);
+
+ this.fireEvent('exception', this, 'response', action, o, response, e);
+ o.request.callback.call(o.request.scope, null, o.request.arg, false);
+ return;
+ }
+ if (result.success === false) {
+
+
+ this.fireEvent('loadexception', this, o, response);
+
+
+ var res = o.reader.readResponse(action, response);
+ this.fireEvent('exception', this, 'remote', action, o, res, null);
+ }
+ else {
+ this.fireEvent('load', this, o, o.request.arg);
+ }
+
+
+
+ o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
+ },
+
+ onWrite : function(action, o, response, rs) {
+ var reader = o.reader;
+ var res;
+ try {
+ res = reader.readResponse(action, response);
+ } catch (e) {
+ this.fireEvent('exception', this, 'response', action, o, response, e);
+ o.request.callback.call(o.request.scope, null, o.request.arg, false);
+ return;
+ }
+ if (res.success === true) {
+ this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
+ } else {
+ this.fireEvent('exception', this, 'remote', action, o, res, rs);
+ }
+
+
+
+ o.request.callback.call(o.request.scope, res.data, res, res.success);
+ },
+
+
+ destroy: function(){
+ if(!this.useAjax){
+ this.conn.abort();
+ }else if(this.activeRequest){
+ var actions = Ext.data.Api.actions;
+ for (var verb in actions) {
+ if(this.activeRequest[actions[verb]]){
+ Ext.Ajax.abort(this.activeRequest[actions[verb]]);
+ }
+ }
+ }
+ Ext.data.HttpProxy.superclass.destroy.call(this);
+ }
+});
+Ext.data.MemoryProxy = function(data){
+
+ var api = {};
+ api[Ext.data.Api.actions.read] = true;
+ Ext.data.MemoryProxy.superclass.constructor.call(this, {
+ api: api
+ });
+ this.data = data;
+};
+
+Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
+
+
+
+ doRequest : function(action, rs, params, reader, callback, scope, arg) {
+
+ params = params || {};
+ var result;
+ try {
+ result = reader.readRecords(this.data);
+ }catch(e){
+
+ this.fireEvent("loadexception", this, null, arg, e);
+
+ this.fireEvent('exception', this, 'response', action, arg, null, e);
+ callback.call(scope, null, arg, false);
+ return;
+ }
+ callback.call(scope, result, arg, true);
+ }
+});
+Ext.data.Types = new function(){
+ var st = Ext.data.SortTypes;
+ Ext.apply(this, {
+
+ stripRe: /[\$,%]/g,
+
+
+ AUTO: {
+ convert: function(v){ return v; },
+ sortType: st.none,
+ type: 'auto'
+ },
+
+
+ STRING: {
+ convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
+ sortType: st.asUCString,
+ type: 'string'
+ },
+
+
+ INT: {
+ convert: function(v){
+ return v !== undefined && v !== null && v !== '' ?
+ parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+ },
+ sortType: st.none,
+ type: 'int'
+ },
+
+
+ FLOAT: {
+ convert: function(v){
+ return v !== undefined && v !== null && v !== '' ?
+ parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+ },
+ sortType: st.none,
+ type: 'float'
+ },
+
+
+ BOOL: {
+ convert: function(v){ return v === true || v === 'true' || v == 1; },
+ sortType: st.none,
+ type: 'bool'
+ },
+
+
+ DATE: {
+ convert: function(v){
+ var df = this.dateFormat;
+ if(!v){
+ return null;
+ }
+ if(Ext.isDate(v)){
+ return v;
+ }
+ if(df){
+ if(df == 'timestamp'){
+ return new Date(v*1000);
+ }
+ if(df == 'time'){
+ return new Date(parseInt(v, 10));
+ }
+ return Date.parseDate(v, df);
+ }
+ var parsed = Date.parse(v);
+ return parsed ? new Date(parsed) : null;
+ },
+ sortType: st.asDate,
+ type: 'date'
+ }
+ });
+
+ Ext.apply(this, {
+
+ BOOLEAN: this.BOOL,
+
+ INTEGER: this.INT,
+
+ NUMBER: this.FLOAT
+ });
+};
+Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
+
+ encode : true,
+
+ encodeDelete: false,
+
+ constructor : function(config){
+ Ext.data.JsonWriter.superclass.constructor.call(this, config);
+ },
+
+
+ render : function(params, baseParams, data) {
+ if (this.encode === true) {
+
+ Ext.apply(params, baseParams);
+ params[this.meta.root] = Ext.encode(data);
+ } else {
+
+ var jdata = Ext.apply({}, baseParams);
+ jdata[this.meta.root] = data;
+ params.jsonData = jdata;
+ }
+ },
+
+ createRecord : function(rec) {
+ return this.toHash(rec);
+ },
+
+ updateRecord : function(rec) {
+ return this.toHash(rec);
+
+ },
+
+ destroyRecord : function(rec){
+ if(this.encodeDelete){
+ var data = {};
+ data[this.meta.idProperty] = rec.id;
+ return data;
+ }else{
+ return rec.id;
+ }
+ }
+});
+Ext.data.JsonReader = function(meta, recordType){
+ meta = meta || {};
+
+
+
+
+ Ext.applyIf(meta, {
+ idProperty: 'id',
+ successProperty: 'success',
+ totalProperty: 'total'
+ });
+
+ Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
+};
+Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
+
+
+ read : function(response){
+ var json = response.responseText;
+ var o = Ext.decode(json);
+ if(!o) {
+ throw {message: 'JsonReader.read: Json object not found'};
+ }
+ return this.readRecords(o);
+ },
+
+
+
+ readResponse : function(action, response) {
+ var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
+ if(!o) {
+ throw new Ext.data.JsonReader.Error('response');
+ }
+
+ var root = this.getRoot(o),
+ success = this.getSuccess(o);
+ if (success && action === Ext.data.Api.actions.create) {
+ var def = Ext.isDefined(root);
+ if (def && Ext.isEmpty(root)) {
+ throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
+ }
+ else if (!def) {
+ throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
+ }
+ }
+
+
+ var res = new Ext.data.Response({
+ action: action,
+ success: success,
+ data: (root) ? this.extractData(root, false) : [],
+ message: this.getMessage(o),
+ raw: o
+ });
+
+
+ if (Ext.isEmpty(res.success)) {
+ throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
+ }
+ return res;
+ },
+
+
+ readRecords : function(o){
+
+ this.jsonData = o;
+ if(o.metaData){
+ this.onMetaChange(o.metaData);
+ }
+ var s = this.meta, Record = this.recordType,
+ f = Record.prototype.fields, fi = f.items, fl = f.length, v;
+
+ var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
+ if(s.totalProperty){
+ v = parseInt(this.getTotal(o), 10);
+ if(!isNaN(v)){
+ totalRecords = v;
+ }
+ }
+ if(s.successProperty){
+ v = this.getSuccess(o);
+ if(v === false || v === 'false'){
+ success = false;
+ }
+ }
+
+
+ return {
+ success : success,
+ records : this.extractData(root, true),
+ totalRecords : totalRecords
+ };
+ },
+
+
+ buildExtractors : function() {
+ if(this.ef){
+ return;
+ }
+ var s = this.meta, Record = this.recordType,
+ f = Record.prototype.fields, fi = f.items, fl = f.length;
+
+ if(s.totalProperty) {
+ this.getTotal = this.createAccessor(s.totalProperty);
+ }
+ if(s.successProperty) {
+ this.getSuccess = this.createAccessor(s.successProperty);
+ }
+ if (s.messageProperty) {
+ this.getMessage = this.createAccessor(s.messageProperty);
+ }
+ this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
+ if (s.id || s.idProperty) {
+ var g = this.createAccessor(s.id || s.idProperty);
+ this.getId = function(rec) {
+ var r = g(rec);
+ return (r === undefined || r === '') ? null : r;
+ };
+ } else {
+ this.getId = function(){return null;};
+ }
+ var ef = [];
+ for(var i = 0; i < fl; i++){
+ f = fi[i];
+ var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
+ ef.push(this.createAccessor(map));
+ }
+ this.ef = ef;
+ },
+
+
+ simpleAccess : function(obj, subsc) {
+ return obj[subsc];
+ },
+
+
+ createAccessor : function(){
+ var re = /[\[\.]/;
+ return function(expr) {
+ if(Ext.isEmpty(expr)){
+ return Ext.emptyFn;
+ }
+ if(Ext.isFunction(expr)){
+ return expr;
+ }
+ var i = String(expr).search(re);
+ if(i >= 0){
+ return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
+ }
+ return function(obj){
+ return obj[expr];
+ };
+
+ };
+ }(),
+
+
+ extractValues : function(data, items, len) {
+ var f, values = {};
+ for(var j = 0; j < len; j++){
+ f = items[j];
+ var v = this.ef[j](data);
+ values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
+ }
+ return values;
+ }
+});
+
+
+Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
+ constructor : function(message, arg) {
+ this.arg = arg;
+ Ext.Error.call(this, message);
+ },
+ name : 'Ext.data.JsonReader'
+});
+Ext.apply(Ext.data.JsonReader.Error.prototype, {
+ lang: {
+ 'response': 'An error occurred while json-decoding your server response',
+ 'successProperty-response': 'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.',
+ 'root-undefined-config': 'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.',
+ 'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.',
+ 'root-empty': 'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.'
+ }
+});
+
+Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
+
+
+
+
+ readRecords : function(o){
+ this.arrayData = o;
+ var s = this.meta,
+ sid = s ? Ext.num(s.idIndex, s.id) : null,
+ recordType = this.recordType,
+ fields = recordType.prototype.fields,
+ records = [],
+ success = true,
+ v;
+
+ var root = this.getRoot(o);
+
+ for(var i = 0, len = root.length; i < len; i++) {
+ var n = root[i],
+ values = {},
+ id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
+ for(var j = 0, jlen = fields.length; j < jlen; j++) {
+ var f = fields.items[j],
+ k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
+ v = n[k] !== undefined ? n[k] : f.defaultValue;
+ v = f.convert(v, n);
+ values[f.name] = v;
+ }
+ var record = new recordType(values, id);
+ record.json = n;
+ records[records.length] = record;
+ }
+
+ var totalRecords = records.length;
+
+ if(s.totalProperty) {
+ v = parseInt(this.getTotal(o), 10);
+ if(!isNaN(v)) {
+ totalRecords = v;
+ }
+ }
+ if(s.successProperty){
+ v = this.getSuccess(o);
+ if(v === false || v === 'false'){
+ success = false;
+ }
+ }
+
+ return {
+ success : success,
+ records : records,
+ totalRecords : totalRecords
+ };
+ }
+});
+Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
+
+ constructor: function(config){
+ Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
+ reader: new Ext.data.ArrayReader(config)
+ }));
+ },
+
+ loadData : function(data, append){
+ if(this.expandData === true){
+ var r = [];
+ for(var i = 0, len = data.length; i < len; i++){
+ r[r.length] = [data[i]];
+ }
+ data = r;
+ }
+ Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
+ }
+});
+Ext.reg('arraystore', Ext.data.ArrayStore);
+
+
+Ext.data.SimpleStore = Ext.data.ArrayStore;
+Ext.reg('simplestore', Ext.data.SimpleStore);
+Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
+
+ constructor: function(config){
+ Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
+ reader: new Ext.data.JsonReader(config)
+ }));
+ }
+});
+Ext.reg('jsonstore', Ext.data.JsonStore);
+Ext.data.XmlWriter = function(params) {
+ Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
+
+ this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
+};
+Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
+
+ documentRoot: 'xrequest',
+
+ forceDocumentRoot: false,
+
+ root: 'records',
+
+ xmlVersion : '1.0',
+
+ xmlEncoding: 'ISO-8859-15',
+
+
+ tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
+
+
+
+ render : function(params, baseParams, data) {
+ baseParams = this.toArray(baseParams);
+ params.xmlData = this.tpl.applyTemplate({
+ version: this.xmlVersion,
+ encoding: this.xmlEncoding,
+ documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
+ record: this.meta.record,
+ root: this.root,
+ baseParams: baseParams,
+ records: (Ext.isArray(data[0])) ? data : [data]
+ });
+ },
+
+
+ createRecord : function(rec) {
+ return this.toArray(this.toHash(rec));
+ },
+
+
+ updateRecord : function(rec) {
+ return this.toArray(this.toHash(rec));
+
+ },
+
+ destroyRecord : function(rec) {
+ var data = {};
+ data[this.meta.idProperty] = rec.id;
+ return this.toArray(data);
+ }
+});
+
+Ext.data.XmlReader = function(meta, recordType){
+ meta = meta || {};
+
+
+ Ext.applyIf(meta, {
+ idProperty: meta.idProperty || meta.idPath || meta.id,
+ successProperty: meta.successProperty || meta.success
+ });
+
+ Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
+};
+Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
+
+ read : function(response){
+ var doc = response.responseXML;
+ if(!doc) {
+ throw {message: "XmlReader.read: XML Document not available"};
+ }
+ return this.readRecords(doc);
+ },
+
+
+ readRecords : function(doc){
+
+ this.xmlData = doc;
+
+ var root = doc.documentElement || doc,
+ q = Ext.DomQuery,
+ totalRecords = 0,
+ success = true;
+
+ if(this.meta.totalProperty){
+ totalRecords = this.getTotal(root, 0);
+ }
+ if(this.meta.successProperty){
+ success = this.getSuccess(root);
+ }
+
+ var records = this.extractData(q.select(this.meta.record, root), true);
+
+
+ return {
+ success : success,
+ records : records,
+ totalRecords : totalRecords || records.length
+ };
+ },
+
+
+ readResponse : function(action, response) {
+ var q = Ext.DomQuery,
+ doc = response.responseXML,
+ root = doc.documentElement || doc;
+
+
+ var res = new Ext.data.Response({
+ action: action,
+ success : this.getSuccess(root),
+ message: this.getMessage(root),
+ data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
+ raw: doc
+ });
+
+ if (Ext.isEmpty(res.success)) {
+ throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
+ }
+
+
+ if (action === Ext.data.Api.actions.create) {
+ var def = Ext.isDefined(res.data);
+ if (def && Ext.isEmpty(res.data)) {
+ throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
+ }
+ else if (!def) {
+ throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
+ }
+ }
+ return res;
+ },
+
+ getSuccess : function() {
+ return true;
+ },
+
+
+ buildExtractors : function() {
+ if(this.ef){
+ return;
+ }
+ var s = this.meta,
+ Record = this.recordType,
+ f = Record.prototype.fields,
+ fi = f.items,
+ fl = f.length;
+
+ if(s.totalProperty) {
+ this.getTotal = this.createAccessor(s.totalProperty);
+ }
+ if(s.successProperty) {
+ this.getSuccess = this.createAccessor(s.successProperty);
+ }
+ if (s.messageProperty) {
+ this.getMessage = this.createAccessor(s.messageProperty);
+ }
+ this.getRoot = function(res) {
+ return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
+ };
+ if (s.idPath || s.idProperty) {
+ var g = this.createAccessor(s.idPath || s.idProperty);
+ this.getId = function(rec) {
+ var id = g(rec) || rec.id;
+ return (id === undefined || id === '') ? null : id;
+ };
+ } else {
+ this.getId = function(){return null;};
+ }
+ var ef = [];
+ for(var i = 0; i < fl; i++){
+ f = fi[i];
+ var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
+ ef.push(this.createAccessor(map));
+ }
+ this.ef = ef;
+ },
+
+
+ createAccessor : function(){
+ var q = Ext.DomQuery;
+ return function(key) {
+ if (Ext.isFunction(key)) {
+ return key;
+ }
+ switch(key) {
+ case this.meta.totalProperty:
+ return function(root, def){
+ return q.selectNumber(key, root, def);
+ };
+ break;
+ case this.meta.successProperty:
+ return function(root, def) {
+ var sv = q.selectValue(key, root, true);
+ var success = sv !== false && sv !== 'false';
+ return success;
+ };
+ break;
+ default:
+ return function(root, def) {
+ return q.selectValue(key, root, def);
+ };
+ break;
+ }
+ };
+ }(),
+
+
+ extractValues : function(data, items, len) {
+ var f, values = {};
+ for(var j = 0; j < len; j++){
+ f = items[j];
+ var v = this.ef[j](data);
+ values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
+ }
+ return values;
+ }
+});
+Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
+
+ constructor: function(config){
+ Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
+ reader: new Ext.data.XmlReader(config)
+ }));
+ }
+});
+Ext.reg('xmlstore', Ext.data.XmlStore);
+Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
+
+
+ constructor: function(config) {
+ config = config || {};
+
+
+
+
+
+ this.hasMultiSort = true;
+ this.multiSortInfo = this.multiSortInfo || {sorters: []};
+
+ var sorters = this.multiSortInfo.sorters,
+ groupField = config.groupField || this.groupField,
+ sortInfo = config.sortInfo || this.sortInfo,
+ groupDir = config.groupDir || this.groupDir;
+
+
+ if(groupField){
+ sorters.push({
+ field : groupField,
+ direction: groupDir
+ });
+ }
+
+
+ if (sortInfo) {
+ sorters.push(sortInfo);
+ }
+
+ Ext.data.GroupingStore.superclass.constructor.call(this, config);
+
+ this.addEvents(
+
+ 'groupchange'
+ );
+
+ this.applyGroupField();
+ },
+
+
+
+ remoteGroup : false,
+
+ groupOnSort:false,
+
+
+ groupDir : 'ASC',
+
+
+ clearGrouping : function(){
+ this.groupField = false;
+
+ if(this.remoteGroup){
+ if(this.baseParams){
+ delete this.baseParams.groupBy;
+ delete this.baseParams.groupDir;
+ }
+ var lo = this.lastOptions;
+ if(lo && lo.params){
+ delete lo.params.groupBy;
+ delete lo.params.groupDir;
+ }
+
+ this.reload();
+ }else{
+ this.sort();
+ this.fireEvent('datachanged', this);
+ }
+ },
+
+
+ groupBy : function(field, forceRegroup, direction) {
+ direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
+
+ if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
+ return;
+ }
+
+
+
+ var sorters = this.multiSortInfo.sorters;
+ if (sorters.length > 0 && sorters[0].field == this.groupField) {
+ sorters.shift();
+ }
+
+ this.groupField = field;
+ this.groupDir = direction;
+ this.applyGroupField();
+
+ var fireGroupEvent = function() {
+ this.fireEvent('groupchange', this, this.getGroupState());
+ };
+
+ if (this.groupOnSort) {
+ this.sort(field, direction);
+ fireGroupEvent.call(this);
+ return;
+ }
+
+ if (this.remoteGroup) {
+ this.on('load', fireGroupEvent, this, {single: true});
+ this.reload();
+ } else {
+ this.sort(sorters);
+ fireGroupEvent.call(this);
+ }
+ },
+
+
+
+ sort : function(fieldName, dir) {
+ if (this.remoteSort) {
+ return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
+ }
+
+ var sorters = [];
+
+
+ if (Ext.isArray(arguments[0])) {
+ sorters = arguments[0];
+ } else if (fieldName == undefined) {
+
+
+ sorters = this.sortInfo ? [this.sortInfo] : [];
+ } else {
+
+
+ var field = this.fields.get(fieldName);
+ if (!field) return false;
+
+ var name = field.name,
+ sortInfo = this.sortInfo || null,
+ sortToggle = this.sortToggle ? this.sortToggle[name] : null;
+
+ if (!dir) {
+ if (sortInfo && sortInfo.field == name) {
+ dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
+ } else {
+ dir = field.sortDir;
+ }
+ }
+
+ this.sortToggle[name] = dir;
+ this.sortInfo = {field: name, direction: dir};
+
+ sorters = [this.sortInfo];
+ }
+
+
+ if (this.groupField) {
+ sorters.unshift({direction: this.groupDir, field: this.groupField});
+ }
+
+ return this.multiSort.call(this, sorters, dir);
+ },
+
+
+ applyGroupField: function(){
+ if (this.remoteGroup) {
+ if(!this.baseParams){
+ this.baseParams = {};
+ }
+
+ Ext.apply(this.baseParams, {
+ groupBy : this.groupField,
+ groupDir: this.groupDir
+ });
+
+ var lo = this.lastOptions;
+ if (lo && lo.params) {
+ lo.params.groupDir = this.groupDir;
+
+
+ delete lo.params.groupBy;
+ }
+ }
+ },
+
+
+ applyGrouping : function(alwaysFireChange){
+ if(this.groupField !== false){
+ this.groupBy(this.groupField, true, this.groupDir);
+ return true;
+ }else{
+ if(alwaysFireChange === true){
+ this.fireEvent('datachanged', this);
+ }
+ return false;
+ }
+ },
+
+
+ getGroupState : function(){
+ return this.groupOnSort && this.groupField !== false ?
+ (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
+ }
+});
+Ext.reg('groupingstore', Ext.data.GroupingStore);
+
+Ext.data.DirectProxy = function(config){
+ Ext.apply(this, config);
+ if(typeof this.paramOrder == 'string'){
+ this.paramOrder = this.paramOrder.split(/[\s,|]/);
+ }
+ Ext.data.DirectProxy.superclass.constructor.call(this, config);
+};
+
+Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
+
+ paramOrder: undefined,
+
+
+ paramsAsHash: true,
+
+
+ directFn : undefined,
+
+
+ doRequest : function(action, rs, params, reader, callback, scope, options) {
+ var args = [],
+ directFn = this.api[action] || this.directFn;
+
+ switch (action) {
+ case Ext.data.Api.actions.create:
+ args.push(params.jsonData);
+ break;
+ case Ext.data.Api.actions.read:
+
+ if(directFn.directCfg.method.len > 0){
+ if(this.paramOrder){
+ for(var i = 0, len = this.paramOrder.length; i < len; i++){
+ args.push(params[this.paramOrder[i]]);
+ }
+ }else if(this.paramsAsHash){
+ args.push(params);
+ }
+ }
+ break;
+ case Ext.data.Api.actions.update:
+ args.push(params.jsonData);
+ break;
+ case Ext.data.Api.actions.destroy:
+ args.push(params.jsonData);
+ break;
+ }
+
+ var trans = {
+ params : params || {},
+ request: {
+ callback : callback,
+ scope : scope,
+ arg : options
+ },
+ reader: reader
+ };
+
+ args.push(this.createCallback(action, rs, trans), this);
+ directFn.apply(window, args);
+ },
+
+
+ createCallback : function(action, rs, trans) {
+ var me = this;
+ return function(result, res) {
+ if (!res.status) {
+
+ if (action === Ext.data.Api.actions.read) {
+ me.fireEvent("loadexception", me, trans, res, null);
+ }
+ me.fireEvent('exception', me, 'remote', action, trans, res, null);
+ trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
+ return;
+ }
+ if (action === Ext.data.Api.actions.read) {
+ me.onRead(action, trans, result, res);
+ } else {
+ me.onWrite(action, trans, result, res, rs);
+ }
+ };
+ },
+
+
+ onRead : function(action, trans, result, res) {
+ var records;
+ try {
+ records = trans.reader.readRecords(result);
+ }
+ catch (ex) {
+
+ this.fireEvent("loadexception", this, trans, res, ex);
+
+ this.fireEvent('exception', this, 'response', action, trans, res, ex);
+ trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
+ return;
+ }
+ this.fireEvent("load", this, res, trans.request.arg);
+ trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
+ },
+
+ onWrite : function(action, trans, result, res, rs) {
+ var data = trans.reader.extractData(trans.reader.getRoot(result), false);
+ var success = trans.reader.getSuccess(result);
+ success = (success !== false);
+ if (success){
+ this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
+ }else{
+ this.fireEvent('exception', this, 'remote', action, trans, result, rs);
+ }
+ trans.request.callback.call(trans.request.scope, data, res, success);
+ }
+});
+
+Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
+ constructor : function(config){
+
+ var c = Ext.apply({}, {
+ batchTransactions: false
+ }, config);
+ Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
+ proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
+ reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
+ }));
+ }
+});
+Ext.reg('directstore', Ext.data.DirectStore);
+
+Ext.Direct = Ext.extend(Ext.util.Observable, {
+
+
+
+ exceptions: {
+ TRANSPORT: 'xhr',
+ PARSE: 'parse',
+ LOGIN: 'login',
+ SERVER: 'exception'
+ },
+
+
+ constructor: function(){
+ this.addEvents(
+
+ 'event',
+
+ 'exception'
+ );
+ this.transactions = {};
+ this.providers = {};
+ },
+
+
+ addProvider : function(provider){
+ var a = arguments;
+ if(a.length > 1){
+ for(var i = 0, len = a.length; i < len; i++){
+ this.addProvider(a[i]);
+ }
+ return;
+ }
+
+
+ if(!provider.events){
+ provider = new Ext.Direct.PROVIDERS[provider.type](provider);
+ }
+ provider.id = provider.id || Ext.id();
+ this.providers[provider.id] = provider;
+
+ provider.on('data', this.onProviderData, this);
+ provider.on('exception', this.onProviderException, this);
+
+
+ if(!provider.isConnected()){
+ provider.connect();
+ }
+
+ return provider;
+ },
+
+
+ getProvider : function(id){
+ return this.providers[id];
+ },
+
+ removeProvider : function(id){
+ var provider = id.id ? id : this.providers[id];
+ provider.un('data', this.onProviderData, this);
+ provider.un('exception', this.onProviderException, this);
+ delete this.providers[provider.id];
+ return provider;
+ },
+
+ addTransaction: function(t){
+ this.transactions[t.tid] = t;
+ return t;
+ },
+
+ removeTransaction: function(t){
+ delete this.transactions[t.tid || t];
+ return t;
+ },
+
+ getTransaction: function(tid){
+ return this.transactions[tid.tid || tid];
+ },
+
+ onProviderData : function(provider, e){
+ if(Ext.isArray(e)){
+ for(var i = 0, len = e.length; i < len; i++){
+ this.onProviderData(provider, e[i]);
+ }
+ return;
+ }
+ if(e.name && e.name != 'event' && e.name != 'exception'){
+ this.fireEvent(e.name, e);
+ }else if(e.type == 'exception'){
+ this.fireEvent('exception', e);
+ }
+ this.fireEvent('event', e, provider);
+ },
+
+ createEvent : function(response, extraProps){
+ return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
+ }
+});
+
+Ext.Direct = new Ext.Direct();
+
+Ext.Direct.TID = 1;
+Ext.Direct.PROVIDERS = {};
+Ext.Direct.Transaction = function(config){
+ Ext.apply(this, config);
+ this.tid = ++Ext.Direct.TID;
+ this.retryCount = 0;
+};
+Ext.Direct.Transaction.prototype = {
+ send: function(){
+ this.provider.queueTransaction(this);
+ },
+
+ retry: function(){
+ this.retryCount++;
+ this.send();
+ },
+
+ getProvider: function(){
+ return this.provider;
+ }
+};Ext.Direct.Event = function(config){
+ Ext.apply(this, config);
+};
+
+Ext.Direct.Event.prototype = {
+ status: true,
+ getData: function(){
+ return this.data;
+ }
+};
+
+Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
+ type: 'rpc',
+ getTransaction: function(){
+ return this.transaction || Ext.Direct.getTransaction(this.tid);
+ }
+});
+
+Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
+ status: false,
+ type: 'exception'
+});
+
+Ext.Direct.eventTypes = {
+ 'rpc': Ext.Direct.RemotingEvent,
+ 'event': Ext.Direct.Event,
+ 'exception': Ext.Direct.ExceptionEvent
+};
+
+Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
+
+
+
+ priority: 1,
+
+
+
+
+ constructor : function(config){
+ Ext.apply(this, config);
+ this.addEvents(
+
+ 'connect',
+
+ 'disconnect',
+
+ 'data',
+
+ 'exception'
+ );
+ Ext.direct.Provider.superclass.constructor.call(this, config);
+ },
+
+
+ isConnected: function(){
+ return false;
+ },
+
+
+ connect: Ext.emptyFn,
+
+
+ disconnect: Ext.emptyFn
+});
+
+Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
+ parseResponse: function(xhr){
+ if(!Ext.isEmpty(xhr.responseText)){
+ if(typeof xhr.responseText == 'object'){
+ return xhr.responseText;
+ }
+ return Ext.decode(xhr.responseText);
+ }
+ return null;
+ },
+
+ getEvents: function(xhr){
+ var data = null;
+ try{
+ data = this.parseResponse(xhr);
+ }catch(e){
+ var event = new Ext.Direct.ExceptionEvent({
+ data: e,
+ xhr: xhr,
+ code: Ext.Direct.exceptions.PARSE,
+ message: 'Error parsing json response: \n\n ' + data
+ });
+ return [event];
+ }
+ var events = [];
+ if(Ext.isArray(data)){
+ for(var i = 0, len = data.length; i < len; i++){
+ events.push(Ext.Direct.createEvent(data[i]));
+ }
+ }else{
+ events.push(Ext.Direct.createEvent(data));
+ }
+ return events;
+ }
+});
+Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
+
+
+ priority: 3,
+
+
+ interval: 3000,
+
+
+
+
+
+
+ constructor : function(config){
+ Ext.direct.PollingProvider.superclass.constructor.call(this, config);
+ this.addEvents(
+
+ 'beforepoll',
+
+ 'poll'
+ );
+ },
+
+
+ isConnected: function(){
+ return !!this.pollTask;
+ },
+
+
+ connect: function(){
+ if(this.url && !this.pollTask){
+ this.pollTask = Ext.TaskMgr.start({
+ run: function(){
+ if(this.fireEvent('beforepoll', this) !== false){
+ if(typeof this.url == 'function'){
+ this.url(this.baseParams);
+ }else{
+ Ext.Ajax.request({
+ url: this.url,
+ callback: this.onData,
+ scope: this,
+ params: this.baseParams
+ });
+ }
+ }
+ },
+ interval: this.interval,
+ scope: this
+ });
+ this.fireEvent('connect', this);
+ }else if(!this.url){
+ throw 'Error initializing PollingProvider, no url configured.';
+ }
+ },
+
+
+ disconnect: function(){
+ if(this.pollTask){
+ Ext.TaskMgr.stop(this.pollTask);
+ delete this.pollTask;
+ this.fireEvent('disconnect', this);
+ }
+ },
+
+
+ onData: function(opt, success, xhr){
+ if(success){
+ var events = this.getEvents(xhr);
+ for(var i = 0, len = events.length; i < len; i++){
+ var e = events[i];
+ this.fireEvent('data', this, e);
+ }
+ }else{
+ var e = new Ext.Direct.ExceptionEvent({
+ data: e,
+ code: Ext.Direct.exceptions.TRANSPORT,
+ message: 'Unable to connect to the server.',
+ xhr: xhr
+ });
+ this.fireEvent('data', this, e);
+ }
+ }
+});
+
+Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
+Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
+
+
+
+
+
+
+
+
+
+ enableBuffer: 10,
+
+
+ maxRetries: 1,
+
+
+ timeout: undefined,
+
+ constructor : function(config){
+ Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
+ this.addEvents(
+
+ 'beforecall',
+
+ 'call'
+ );
+ this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
+ this.transactions = {};
+ this.callBuffer = [];
+ },
+
+
+ initAPI : function(){
+ var o = this.actions;
+ for(var c in o){
+ var cls = this.namespace[c] || (this.namespace[c] = {}),
+ ms = o[c];
+ for(var i = 0, len = ms.length; i < len; i++){
+ var m = ms[i];
+ cls[m.name] = this.createMethod(c, m);
+ }
+ }
+ },
+
+
+ isConnected: function(){
+ return !!this.connected;
+ },
+
+ connect: function(){
+ if(this.url){
+ this.initAPI();
+ this.connected = true;
+ this.fireEvent('connect', this);
+ }else if(!this.url){
+ throw 'Error initializing RemotingProvider, no url configured.';
+ }
+ },
+
+ disconnect: function(){
+ if(this.connected){
+ this.connected = false;
+ this.fireEvent('disconnect', this);
+ }
+ },
+
+ onData: function(opt, success, xhr){
+ if(success){
+ var events = this.getEvents(xhr);
+ for(var i = 0, len = events.length; i < len; i++){
+ var e = events[i],
+ t = this.getTransaction(e);
+ this.fireEvent('data', this, e);
+ if(t){
+ this.doCallback(t, e, true);
+ Ext.Direct.removeTransaction(t);
+ }
+ }
+ }else{
+ var ts = [].concat(opt.ts);
+ for(var i = 0, len = ts.length; i < len; i++){
+ var t = this.getTransaction(ts[i]);
+ if(t && t.retryCount < this.maxRetries){
+ t.retry();
+ }else{
+ var e = new Ext.Direct.ExceptionEvent({
+ data: e,
+ transaction: t,
+ code: Ext.Direct.exceptions.TRANSPORT,
+ message: 'Unable to connect to the server.',
+ xhr: xhr
+ });
+ this.fireEvent('data', this, e);
+ if(t){
+ this.doCallback(t, e, false);
+ Ext.Direct.removeTransaction(t);
+ }
+ }
+ }
+ }
+ },
+
+ getCallData: function(t){
+ return {
+ action: t.action,
+ method: t.method,
+ data: t.data,
+ type: 'rpc',
+ tid: t.tid
+ };
+ },
+
+ doSend : function(data){
+ var o = {
+ url: this.url,
+ callback: this.onData,
+ scope: this,
+ ts: data,
+ timeout: this.timeout
+ }, callData;
+
+ if(Ext.isArray(data)){
+ callData = [];
+ for(var i = 0, len = data.length; i < len; i++){
+ callData.push(this.getCallData(data[i]));
+ }
+ }else{
+ callData = this.getCallData(data);
+ }
+
+ if(this.enableUrlEncode){
+ var params = {};
+ params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
+ o.params = params;
+ }else{
+ o.jsonData = callData;
+ }
+ Ext.Ajax.request(o);
+ },
+
+ combineAndSend : function(){
+ var len = this.callBuffer.length;
+ if(len > 0){
+ this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
+ this.callBuffer = [];
+ }
+ },
+
+ queueTransaction: function(t){
+ if(t.form){
+ this.processForm(t);
+ return;
+ }
+ this.callBuffer.push(t);
+ if(this.enableBuffer){
+ if(!this.callTask){
+ this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
+ }
+ this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
+ }else{
+ this.combineAndSend();
+ }
+ },
+
+ doCall : function(c, m, args){
+ var data = null, hs = args[m.len], scope = args[m.len+1];
+
+ if(m.len !== 0){
+ data = args.slice(0, m.len);
+ }
+
+ var t = new Ext.Direct.Transaction({
+ provider: this,
+ args: args,
+ action: c,
+ method: m.name,
+ data: data,
+ cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
+ });
+
+ if(this.fireEvent('beforecall', this, t, m) !== false){
+ Ext.Direct.addTransaction(t);
+ this.queueTransaction(t);
+ this.fireEvent('call', this, t, m);
+ }
+ },
+
+ doForm : function(c, m, form, callback, scope){
+ var t = new Ext.Direct.Transaction({
+ provider: this,
+ action: c,
+ method: m.name,
+ args:[form, callback, scope],
+ cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
+ isForm: true
+ });
+
+ if(this.fireEvent('beforecall', this, t, m) !== false){
+ Ext.Direct.addTransaction(t);
+ var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
+ params = {
+ extTID: t.tid,
+ extAction: c,
+ extMethod: m.name,
+ extType: 'rpc',
+ extUpload: String(isUpload)
+ };
+
+
+
+ Ext.apply(t, {
+ form: Ext.getDom(form),
+ isUpload: isUpload,
+ params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
+ });
+ this.fireEvent('call', this, t, m);
+ this.processForm(t);
+ }
+ },
+
+ processForm: function(t){
+ Ext.Ajax.request({
+ url: this.url,
+ params: t.params,
+ callback: this.onData,
+ scope: this,
+ form: t.form,
+ isUpload: t.isUpload,
+ ts: t
+ });
+ },
+
+ createMethod : function(c, m){
+ var f;
+ if(!m.formHandler){
+ f = function(){
+ this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
+ }.createDelegate(this);
+ }else{
+ f = function(form, callback, scope){
+ this.doForm(c, m, form, callback, scope);
+ }.createDelegate(this);
+ }
+ f.directCfg = {
+ action: c,
+ method: m
+ };
+ return f;
+ },
+
+ getTransaction: function(opt){
+ return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
+ },
+
+ doCallback: function(t, e){
+ var fn = e.status ? 'success' : 'failure';
+ if(t && t.cb){
+ var hs = t.cb,
+ result = Ext.isDefined(e.result) ? e.result : e.data;
+ if(Ext.isFunction(hs)){
+ hs(result, e);
+ } else{
+ Ext.callback(hs[fn], hs.scope, [result, e]);
+ Ext.callback(hs.callback, hs.scope, [result, e]);
+ }
+ }
+ }
+});
+Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
+Ext.Resizable = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(el, config){
+ this.el = Ext.get(el);
+ if(config && config.wrap){
+ config.resizeChild = this.el;
+ this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
+ this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
+ this.el.setStyle('overflow', 'hidden');
+ this.el.setPositioning(config.resizeChild.getPositioning());
+ config.resizeChild.clearPositioning();
+ if(!config.width || !config.height){
+ var csize = config.resizeChild.getSize();
+ this.el.setSize(csize.width, csize.height);
+ }
+ if(config.pinned && !config.adjustments){
+ config.adjustments = 'auto';
+ }
+ }
+
+
+ this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
+ this.proxy.unselectable();
+ this.proxy.enableDisplayMode('block');
+
+ Ext.apply(this, config);
+
+ if(this.pinned){
+ this.disableTrackOver = true;
+ this.el.addClass('x-resizable-pinned');
+ }
+
+ var position = this.el.getStyle('position');
+ if(position != 'absolute' && position != '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, len = hs.length; i < len; i++){
+ if(hs[i] && ps[hs[i]]){
+ var pos = ps[hs[i]];
+ this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
+ }
+ }
+
+ 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);
+ if(this.constrainTo){
+ this.dd.constrainTo(this.constrainTo);
+ }
+ }
+
+ this.addEvents(
+
+ 'beforeresize',
+
+ 'resize'
+ );
+
+ if(this.width !== null && this.height !== null){
+ this.resizeTo(this.width, this.height);
+ }else{
+ this.updateChildSize();
+ }
+ if(Ext.isIE){
+ this.el.dom.style.zoom = 1;
+ }
+ Ext.Resizable.superclass.constructor.call(this);
+ },
+
+
+ adjustments : [0, 0],
+
+ animate : false,
+
+
+ disableTrackOver : false,
+
+ draggable: false,
+
+ duration : 0.35,
+
+ dynamic : false,
+
+ easing : 'easeOutStrong',
+
+ enabled : true,
+
+
+ handles : false,
+
+ multiDirectional : false,
+
+ height : null,
+
+ width : null,
+
+ heightIncrement : 0,
+
+ widthIncrement : 0,
+
+ minHeight : 5,
+
+ minWidth : 5,
+
+ maxHeight : 10000,
+
+ maxWidth : 10000,
+
+ minX: 0,
+
+ minY: 0,
+
+ pinned : false,
+
+ preserveRatio : false,
+
+ resizeChild : false,
+
+ transparent: false,
+
+
+
+
+
+
+ resizeTo : function(width, height){
+ this.el.setSize(width, height);
+ this.updateChildSize();
+ this.fireEvent('resize', this, width, height, null);
+ },
+
+
+ startSizing : function(e, handle){
+ this.fireEvent('beforeresize', this, e);
+ if(this.enabled){
+
+ if(!this.overlay){
+ this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: '&#160;'}, Ext.getBody());
+ this.overlay.unselectable();
+ this.overlay.enableDisplayMode('block');
+ this.overlay.on({
+ scope: this,
+ mousemove: this.onMouseMove,
+ mouseup: this.onMouseUp
+ });
+ }
+ this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
+
+ 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.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
+ this.overlay.show();
+
+ if(this.constrainTo) {
+ var ct = Ext.get(this.constrainTo);
+ this.resizeRegion = ct.getRegion().adjust(
+ ct.getFrameWidth('t'),
+ ct.getFrameWidth('l'),
+ -ct.getFrameWidth('b'),
+ -ct.getFrameWidth('r')
+ );
+ }
+
+ this.proxy.setStyle('visibility', 'hidden');
+ this.proxy.show();
+ this.proxy.setBox(this.startBox);
+ if(!this.dynamic){
+ this.proxy.setStyle('visibility', 'visible');
+ }
+ }
+ },
+
+
+ onMouseDown : function(handle, e){
+ if(this.enabled){
+ e.stopEvent();
+ this.activeHandle = handle;
+ this.startSizing(e, handle);
+ }
+ },
+
+
+ onMouseUp : function(e){
+ this.activeHandle = null;
+ var size = this.resizeElement();
+ this.resizing = false;
+ this.handleOut();
+ this.overlay.hide();
+ this.proxy.hide();
+ this.fireEvent('resize', this, size.width, size.height, e);
+ },
+
+
+ updateChildSize : function(){
+ if(this.resizeChild){
+ var el = this.el;
+ var child = this.resizeChild;
+ var adj = this.adjustments;
+ if(el.dom.offsetWidth){
+ var b = el.getSize(true);
+ child.setSize(b.width+adj[0], b.height+adj[1]);
+ }
+
+
+
+
+ if(Ext.isIE9m){
+ setTimeout(function(){
+ if(el.dom.offsetWidth){
+ var b = el.getSize(true);
+ child.setSize(b.width+adj[0], b.height+adj[1]);
+ }
+ }, 10);
+ }
+ }
+ },
+
+
+ snap : function(value, inc, min){
+ if(!inc || !value){
+ return value;
+ }
+ var newValue = value;
+ var m = value % inc;
+ if(m > 0){
+ if(m > (inc/2)){
+ newValue = value + (inc-m);
+ }else{
+ newValue = value - m;
+ }
+ }
+ return Math.max(min, newValue);
+ },
+
+
+ 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();
+ if(!this.dynamic){
+ this.proxy.hide();
+ }
+ if(this.draggable && this.constrainTo){
+ this.dd.resetConstraints();
+ this.dd.constrainTo(this.constrainTo);
+ }
+ return box;
+ },
+
+
+ constrain : function(v, diff, m, mx){
+ if(v - diff < m){
+ diff = v - m;
+ }else if(v - diff > mx){
+ diff = v - mx;
+ }
+ return diff;
+ },
+
+
+ onMouseMove : function(e){
+ if(this.enabled && this.activeHandle){
+ try{
+
+ if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
+ return;
+ }
+
+
+ var curSize = this.curSize || this.startBox,
+ x = this.startBox.x, y = this.startBox.y,
+ ox = x,
+ oy = y,
+ w = curSize.width,
+ h = curSize.height,
+ ow = w,
+ oh = h,
+ mw = this.minWidth,
+ mh = this.minHeight,
+ mxw = this.maxWidth,
+ mxh = this.maxHeight,
+ wi = this.widthIncrement,
+ hi = this.heightIncrement,
+ eventXY = e.getXY(),
+ diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
+ diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
+ pos = this.activeHandle.position,
+ tw,
+ th;
+
+ switch(pos){
+ case 'east':
+ w += diffX;
+ w = Math.min(Math.max(mw, w), mxw);
+ break;
+ case 'south':
+ h += diffY;
+ h = Math.min(Math.max(mh, h), mxh);
+ break;
+ case 'southeast':
+ w += diffX;
+ h += diffY;
+ w = Math.min(Math.max(mw, w), mxw);
+ h = Math.min(Math.max(mh, h), mxh);
+ break;
+ case 'north':
+ diffY = this.constrain(h, diffY, mh, mxh);
+ y += diffY;
+ h -= diffY;
+ break;
+ case 'west':
+ diffX = this.constrain(w, diffX, mw, mxw);
+ x += diffX;
+ w -= diffX;
+ break;
+ case 'northeast':
+ w += diffX;
+ w = Math.min(Math.max(mw, w), mxw);
+ diffY = this.constrain(h, diffY, mh, mxh);
+ y += diffY;
+ h -= diffY;
+ break;
+ case 'northwest':
+ diffX = this.constrain(w, diffX, mw, mxw);
+ diffY = this.constrain(h, diffY, mh, mxh);
+ y += diffY;
+ h -= diffY;
+ x += diffX;
+ w -= diffX;
+ break;
+ case 'southwest':
+ diffX = this.constrain(w, diffX, mw, mxw);
+ h += diffY;
+ h = Math.min(Math.max(mh, h), mxh);
+ x += diffX;
+ w -= diffX;
+ 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':
+ 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);
+ tw = w;
+ w = ow * (h/oh);
+ x += tw - w;
+ break;
+ case 'west':
+ th = h;
+ h = oh * (w/ow);
+ h = Math.min(Math.max(mh, h), mxh);
+ y += (th - h) / 2;
+ tw = w;
+ w = ow * (h/oh);
+ x += tw - w;
+ break;
+ case 'northwest':
+ tw = w;
+ 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(ex){}
+ }
+ },
+
+
+ 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(removeEl){
+ Ext.destroy(this.dd, this.overlay, this.proxy);
+ this.overlay = null;
+ this.proxy = null;
+
+ var ps = Ext.Resizable.positions;
+ for(var k in ps){
+ if(typeof ps[k] != 'function' && this[ps[k]]){
+ this[ps[k]].destroy();
+ }
+ }
+ if(removeEl){
+ this.el.update('');
+ Ext.destroy(this.el);
+ this.el = null;
+ }
+ this.purgeListeners();
+ },
+
+ syncHandleHeight : function(){
+ var h = this.el.getHeight(true);
+ if(this.west){
+ this.west.el.setHeight(h);
+ }
+ if(this.east){
+ this.east.el.setHeight(h);
+ }
+ }
+});
+
+
+
+Ext.Resizable.positions = {
+ n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
+};
+
+Ext.Resizable.Handle = Ext.extend(Object, {
+ constructor : function(rz, pos, disableTrackOver, transparent, cls){
+ 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(transparent){
+ this.el.setOpacity(0);
+ }
+ if(!Ext.isEmpty(cls)){
+ this.el.addClass(cls);
+ }
+ this.el.on('mousedown', this.onMouseDown, this);
+ if(!disableTrackOver){
+ this.el.on({
+ scope: this,
+ mouseover: this.onMouseOver,
+ mouseout: this.onMouseOut
+ });
+ }
+ },
+
+
+ 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);
+ },
+
+ destroy : function(){
+ Ext.destroy(this.el);
+ this.el = null;
+ }
+});
+
+Ext.Window = Ext.extend(Ext.Panel, {
+
+
+
+
+
+
+
+
+
+
+
+
+ baseCls : 'x-window',
+
+ resizable : true,
+
+ draggable : true,
+
+ closable : true,
+
+ closeAction : 'close',
+
+ constrain : false,
+
+ constrainHeader : false,
+
+ plain : false,
+
+ minimizable : false,
+
+ maximizable : false,
+
+ minHeight : 100,
+
+ minWidth : 200,
+
+ expandOnShow : true,
+
+
+ showAnimDuration: 0.25,
+
+
+ hideAnimDuration: 0.25,
+
+
+ collapsible : false,
+
+
+ initHidden : undefined,
+
+
+ hidden : true,
+
+
+
+
+
+
+ elements : 'header,body',
+
+ frame : true,
+
+ floating : true,
+
+
+ initComponent : function(){
+ this.initTools();
+ Ext.Window.superclass.initComponent.call(this);
+ this.addEvents(
+
+
+
+ 'resize',
+
+ 'maximize',
+
+ 'minimize',
+
+ 'restore'
+ );
+
+ if(Ext.isDefined(this.initHidden)){
+ this.hidden = this.initHidden;
+ }
+ if(this.hidden === false){
+ this.hidden = true;
+ this.show();
+ }
+ },
+
+
+ getState : function(){
+ return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
+ },
+
+
+ onRender : function(ct, position){
+ Ext.Window.superclass.onRender.call(this, ct, position);
+
+ if(this.plain){
+ this.el.addClass('x-window-plain');
+ }
+
+
+ this.focusEl = this.el.createChild({
+ tag: 'a', href:'#', cls:'x-dlg-focus',
+ tabIndex:'-1', html: '&#160;'});
+ this.focusEl.swallowEvent('click', true);
+
+ this.proxy = this.el.createProxy('x-window-proxy');
+ this.proxy.enableDisplayMode('block');
+
+ if(this.modal){
+ this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
+ this.mask.enableDisplayMode('block');
+ this.mask.hide();
+ this.mon(this.mask, 'click', this.focus, this);
+ }
+ if(this.maximizable){
+ this.mon(this.header, 'dblclick', this.toggleMaximize, this);
+ }
+ },
+
+
+ initEvents : function(){
+ Ext.Window.superclass.initEvents.call(this);
+ if(this.animateTarget){
+ this.setAnimateTarget(this.animateTarget);
+ }
+
+ if(this.resizable){
+ this.resizer = new Ext.Resizable(this.el, {
+ minWidth: this.minWidth,
+ minHeight:this.minHeight,
+ handles: this.resizeHandles || 'all',
+ pinned: true,
+ resizeElement : this.resizerAction,
+ handleCls: 'x-window-handle'
+ });
+ this.resizer.window = this;
+ this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
+ }
+
+ if(this.draggable){
+ this.header.addClass('x-window-draggable');
+ }
+ this.mon(this.el, 'mousedown', this.toFront, this);
+ this.manager = this.manager || Ext.WindowMgr;
+ this.manager.register(this);
+ if(this.maximized){
+ this.maximized = false;
+ this.maximize();
+ }
+ if(this.closable){
+ var km = this.getKeyMap();
+ km.on(27, this.onEsc, this);
+ km.disable();
+ }
+ },
+
+ initDraggable : function(){
+
+ this.dd = new Ext.Window.DD(this);
+ },
+
+
+ onEsc : function(k, e){
+ if (this.activeGhost) {
+ this.unghost();
+ }
+ e.stopEvent();
+ this[this.closeAction]();
+ },
+
+
+ beforeDestroy : function(){
+ if(this.rendered){
+ this.hide();
+ this.clearAnchor();
+ Ext.destroy(
+ this.focusEl,
+ this.resizer,
+ this.dd,
+ this.proxy,
+ this.mask
+ );
+ }
+ Ext.Window.superclass.beforeDestroy.call(this);
+ },
+
+
+ onDestroy : function(){
+ if(this.manager){
+ this.manager.unregister(this);
+ }
+ Ext.Window.superclass.onDestroy.call(this);
+ },
+
+
+ initTools : function(){
+ if(this.minimizable){
+ this.addTool({
+ id: 'minimize',
+ handler: this.minimize.createDelegate(this, [])
+ });
+ }
+ if(this.maximizable){
+ this.addTool({
+ id: 'maximize',
+ handler: this.maximize.createDelegate(this, [])
+ });
+ this.addTool({
+ id: 'restore',
+ handler: this.restore.createDelegate(this, []),
+ hidden:true
+ });
+ }
+ if(this.closable){
+ this.addTool({
+ id: 'close',
+ handler: this[this.closeAction].createDelegate(this, [])
+ });
+ }
+ },
+
+
+ resizerAction : function(){
+ var box = this.proxy.getBox();
+ this.proxy.hide();
+ this.window.handleResize(box);
+ return box;
+ },
+
+
+ beforeResize : function(){
+ this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
+ this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
+ this.resizeBox = this.el.getBox();
+ },
+
+
+ updateHandles : function(){
+ if(Ext.isIE9m && this.resizer){
+ this.resizer.syncHandleHeight();
+ this.el.repaint();
+ }
+ },
+
+
+ handleResize : function(box){
+ var rz = this.resizeBox;
+ if(rz.x != box.x || rz.y != box.y){
+ this.updateBox(box);
+ }else{
+ this.setSize(box);
+ if (Ext.isIE6 && Ext.isStrict) {
+ this.doLayout();
+ }
+ }
+ this.focus();
+ this.updateHandles();
+ this.saveState();
+ },
+
+
+ focus : function(){
+ var f = this.focusEl,
+ db = this.defaultButton,
+ t = typeof db,
+ el,
+ ct;
+ if(Ext.isDefined(db)){
+ if(Ext.isNumber(db) && this.fbar){
+ f = this.fbar.items.get(db);
+ }else if(Ext.isString(db)){
+ f = Ext.getCmp(db);
+ }else{
+ f = db;
+ }
+ el = f.getEl();
+ ct = Ext.getDom(this.container);
+ if (el && ct) {
+ if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
+ return;
+ }
+ }
+ }
+ f = f || this.focusEl;
+ f.focus.defer(10, f);
+ },
+
+
+ setAnimateTarget : function(el){
+ el = Ext.get(el);
+ this.animateTarget = el;
+ },
+
+
+ beforeShow : function(){
+ delete this.el.lastXY;
+ delete this.el.lastLT;
+ if(this.x === undefined || this.y === undefined){
+ var xy = this.el.getAlignToXY(this.container, 'c-c');
+ var pos = this.el.translatePoints(xy[0], xy[1]);
+ this.x = this.x === undefined? pos.left : this.x;
+ this.y = this.y === undefined? pos.top : this.y;
+ }
+ this.el.setLeftTop(this.x, this.y);
+
+ if(this.expandOnShow){
+ this.expand(false);
+ }
+
+ if(this.modal){
+ Ext.getBody().addClass('x-body-masked');
+ this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
+ this.mask.show();
+ }
+ },
+
+
+ show : function(animateTarget, cb, scope){
+ if(!this.rendered){
+ this.render(Ext.getBody());
+ }
+ if(this.hidden === false){
+ this.toFront();
+ return this;
+ }
+ if(this.fireEvent('beforeshow', this) === false){
+ return this;
+ }
+ if(cb){
+ this.on('show', cb, scope, {single:true});
+ }
+ this.hidden = false;
+ if(Ext.isDefined(animateTarget)){
+ this.setAnimateTarget(animateTarget);
+ }
+ this.beforeShow();
+ if(this.animateTarget){
+ this.animShow();
+ }else{
+ this.afterShow();
+ }
+ return this;
+ },
+
+
+ afterShow : function(isAnim){
+ if (this.isDestroyed){
+ return false;
+ }
+ this.proxy.hide();
+ this.el.setStyle('display', 'block');
+ this.el.show();
+ if(this.maximized){
+ this.fitContainer();
+ }
+ if(Ext.isMac && Ext.isGecko2){
+ this.cascade(this.setAutoScroll);
+ }
+
+ if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
+ Ext.EventManager.onWindowResize(this.onWindowResize, this);
+ }
+ this.doConstrain();
+ this.doLayout();
+ if(this.keyMap){
+ this.keyMap.enable();
+ }
+ this.toFront();
+ this.updateHandles();
+ if(isAnim && (Ext.isIE || Ext.isWebKit)){
+ var sz = this.getSize();
+ this.onResize(sz.width, sz.height);
+ }
+ this.onShow();
+ this.fireEvent('show', this);
+ },
+
+
+ animShow : function(){
+ this.proxy.show();
+ this.proxy.setBox(this.animateTarget.getBox());
+ this.proxy.setOpacity(0);
+ var b = this.getBox();
+ this.el.setStyle('display', 'none');
+ this.proxy.shift(Ext.apply(b, {
+ callback: this.afterShow.createDelegate(this, [true], false),
+ scope: this,
+ easing: 'easeNone',
+ duration: this.showAnimDuration,
+ opacity: 0.5
+ }));
+ },
+
+
+ hide : function(animateTarget, cb, scope){
+ if(this.hidden || this.fireEvent('beforehide', this) === false){
+ return this;
+ }
+ if(cb){
+ this.on('hide', cb, scope, {single:true});
+ }
+ this.hidden = true;
+ if(animateTarget !== undefined){
+ this.setAnimateTarget(animateTarget);
+ }
+ if(this.modal){
+ this.mask.hide();
+ Ext.getBody().removeClass('x-body-masked');
+ }
+ if(this.animateTarget){
+ this.animHide();
+ }else{
+ this.el.hide();
+ this.afterHide();
+ }
+ return this;
+ },
+
+
+ afterHide : function(){
+ this.proxy.hide();
+ if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
+ Ext.EventManager.removeResizeListener(this.onWindowResize, this);
+ }
+ if(this.keyMap){
+ this.keyMap.disable();
+ }
+ this.onHide();
+ this.fireEvent('hide', this);
+ },
+
+
+ animHide : function(){
+ this.proxy.setOpacity(0.5);
+ this.proxy.show();
+ var tb = this.getBox(false);
+ this.proxy.setBox(tb);
+ this.el.hide();
+ this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
+ callback: this.afterHide,
+ scope: this,
+ duration: this.hideAnimDuration,
+ easing: 'easeNone',
+ opacity: 0
+ }));
+ },
+
+
+ onShow : Ext.emptyFn,
+
+
+ onHide : Ext.emptyFn,
+
+
+ onWindowResize : function(){
+ if(this.maximized){
+ this.fitContainer();
+ }
+ if(this.modal){
+ this.mask.setSize('100%', '100%');
+ var force = this.mask.dom.offsetHeight;
+ this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
+ }
+ this.doConstrain();
+ },
+
+
+ doConstrain : function(){
+ if(this.constrain || this.constrainHeader){
+ var offsets;
+ if(this.constrain){
+ offsets = {
+ right:this.el.shadowOffset,
+ left:this.el.shadowOffset,
+ bottom:this.el.shadowOffset
+ };
+ }else {
+ var s = this.getSize();
+ offsets = {
+ right:-(s.width - 100),
+ bottom:-(s.height - 25 + this.el.getConstrainOffset())
+ };
+ }
+
+ var xy = this.el.getConstrainToXY(this.container, true, offsets);
+ if(xy){
+ this.setPosition(xy[0], xy[1]);
+ }
+ }
+ },
+
+
+ ghost : function(cls){
+ var ghost = this.createGhost(cls);
+ var box = this.getBox(true);
+ ghost.setLeftTop(box.x, box.y);
+ ghost.setWidth(box.width);
+ this.el.hide();
+ this.activeGhost = ghost;
+ return ghost;
+ },
+
+
+ unghost : function(show, matchPosition){
+ if(!this.activeGhost) {
+ return;
+ }
+ if(show !== false){
+ this.el.show();
+ this.focus.defer(10, this);
+ if(Ext.isMac && Ext.isGecko2){
+ this.cascade(this.setAutoScroll);
+ }
+ }
+ if(matchPosition !== false){
+ this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
+ }
+ this.activeGhost.hide();
+ this.activeGhost.remove();
+ delete this.activeGhost;
+ },
+
+
+ minimize : function(){
+ this.fireEvent('minimize', this);
+ return this;
+ },
+
+
+ close : function(){
+ if(this.fireEvent('beforeclose', this) !== false){
+ if(this.hidden){
+ this.doClose();
+ }else{
+ this.hide(null, this.doClose, this);
+ }
+ }
+ },
+
+
+ doClose : function(){
+ this.fireEvent('close', this);
+ this.destroy();
+ },
+
+
+ maximize : function(){
+ if(!this.maximized){
+ this.expand(false);
+ this.restoreSize = this.getSize();
+ this.restorePos = this.getPosition(true);
+ if (this.maximizable){
+ this.tools.maximize.hide();
+ this.tools.restore.show();
+ }
+ this.maximized = true;
+ this.el.disableShadow();
+
+ if(this.dd){
+ this.dd.lock();
+ }
+ if(this.collapsible){
+ this.tools.toggle.hide();
+ }
+ this.el.addClass('x-window-maximized');
+ this.container.addClass('x-window-maximized-ct');
+
+ this.setPosition(0, 0);
+ this.fitContainer();
+ this.fireEvent('maximize', this);
+ }
+ return this;
+ },
+
+
+ restore : function(){
+ if(this.maximized){
+ var t = this.tools;
+ this.el.removeClass('x-window-maximized');
+ if(t.restore){
+ t.restore.hide();
+ }
+ if(t.maximize){
+ t.maximize.show();
+ }
+ this.setPosition(this.restorePos[0], this.restorePos[1]);
+ this.setSize(this.restoreSize.width, this.restoreSize.height);
+ delete this.restorePos;
+ delete this.restoreSize;
+ this.maximized = false;
+ this.el.enableShadow(true);
+
+ if(this.dd){
+ this.dd.unlock();
+ }
+ if(this.collapsible && t.toggle){
+ t.toggle.show();
+ }
+ this.container.removeClass('x-window-maximized-ct');
+
+ this.doConstrain();
+ this.fireEvent('restore', this);
+ }
+ return this;
+ },
+
+
+ toggleMaximize : function(){
+ return this[this.maximized ? 'restore' : 'maximize']();
+ },
+
+
+ fitContainer : function(){
+ var vs = this.container.getViewSize(false);
+ this.setSize(vs.width, vs.height);
+ },
+
+
+
+ setZIndex : function(index){
+ if(this.modal){
+ this.mask.setStyle('z-index', index);
+ }
+ this.el.setZIndex(++index);
+ index += 5;
+
+ if(this.resizer){
+ this.resizer.proxy.setStyle('z-index', ++index);
+ }
+
+ this.lastZIndex = index;
+ },
+
+
+ alignTo : function(element, position, offsets){
+ var xy = this.el.getAlignToXY(element, position, offsets);
+ this.setPagePosition(xy[0], xy[1]);
+ return this;
+ },
+
+
+ anchorTo : function(el, alignment, offsets, monitorScroll){
+ this.clearAnchor();
+ this.anchorTarget = {
+ el: el,
+ alignment: alignment,
+ offsets: offsets
+ };
+
+ Ext.EventManager.onWindowResize(this.doAnchor, this);
+ var tm = typeof monitorScroll;
+ if(tm != 'undefined'){
+ Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
+ {buffer: tm == 'number' ? monitorScroll : 50});
+ }
+ return this.doAnchor();
+ },
+
+
+ doAnchor : function(){
+ var o = this.anchorTarget;
+ this.alignTo(o.el, o.alignment, o.offsets);
+ return this;
+ },
+
+
+ clearAnchor : function(){
+ if(this.anchorTarget){
+ Ext.EventManager.removeResizeListener(this.doAnchor, this);
+ Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
+ delete this.anchorTarget;
+ }
+ return this;
+ },
+
+
+ toFront : function(e){
+ if(this.manager.bringToFront(this)){
+ if(!e || !e.getTarget().focus){
+ this.focus();
+ }
+ }
+ return this;
+ },
+
+
+ setActive : function(active){
+ if(active){
+ if(!this.maximized){
+ this.el.enableShadow(true);
+ }
+ this.fireEvent('activate', this);
+ }else{
+ this.el.disableShadow();
+ this.fireEvent('deactivate', this);
+ }
+ },
+
+
+ toBack : function(){
+ this.manager.sendToBack(this);
+ return this;
+ },
+
+
+ center : function(){
+ var xy = this.el.getAlignToXY(this.container, 'c-c');
+ this.setPagePosition(xy[0], xy[1]);
+ return this;
+ }
+
+
+});
+Ext.reg('window', Ext.Window);
+
+
+Ext.Window.DD = Ext.extend(Ext.dd.DD, {
+
+ constructor : function(win){
+ this.win = win;
+ Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
+ this.setHandleElId(win.header.id);
+ this.scroll = false;
+ },
+
+ moveOnly:true,
+ headerOffsets:[100, 25],
+ startDrag : function(){
+ var w = this.win;
+ this.proxy = w.ghost(w.initialConfig.cls);
+ if(w.constrain !== false){
+ var so = w.el.shadowOffset;
+ this.constrainTo(w.container, {right: so, left: so, bottom: so});
+ }else if(w.constrainHeader !== false){
+ var s = this.proxy.getSize();
+ this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
+ }
+ },
+ b4Drag : Ext.emptyFn,
+
+ onDrag : function(e){
+ this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
+ },
+
+ endDrag : function(e){
+ this.win.unghost();
+ this.win.saveState();
+ }
+});
+
+Ext.WindowGroup = function(){
+ var list = {};
+ var accessList = [];
+ var front = null;
+
+
+ var sortWindows = function(d1, d2){
+ return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
+ };
+
+
+ var orderWindows = function(){
+ var a = accessList, len = a.length;
+ if(len > 0){
+ a.sort(sortWindows);
+ var seed = a[0].manager.zseed;
+ for(var i = 0; i < len; i++){
+ var win = a[i];
+ if(win && !win.hidden){
+ win.setZIndex(seed + (i*10));
+ }
+ }
+ }
+ activateLast();
+ };
+
+
+ var setActiveWin = function(win){
+ if(win != front){
+ if(front){
+ front.setActive(false);
+ }
+ front = win;
+ if(win){
+ win.setActive(true);
+ }
+ }
+ };
+
+
+ var activateLast = function(){
+ for(var i = accessList.length-1; i >=0; --i) {
+ if(!accessList[i].hidden){
+ setActiveWin(accessList[i]);
+ return;
+ }
+ }
+
+ setActiveWin(null);
+ };
+
+ return {
+
+ zseed : 9000,
+
+
+ register : function(win){
+ if(win.manager){
+ win.manager.unregister(win);
+ }
+ win.manager = this;
+
+ list[win.id] = win;
+ accessList.push(win);
+ win.on('hide', activateLast);
+ },
+
+
+ unregister : function(win){
+ delete win.manager;
+ delete list[win.id];
+ win.un('hide', activateLast);
+ accessList.remove(win);
+ },
+
+
+ get : function(id){
+ return typeof id == "object" ? id : list[id];
+ },
+
+
+ bringToFront : function(win){
+ win = this.get(win);
+ if(win != front){
+ win._lastAccess = new Date().getTime();
+ orderWindows();
+ return true;
+ }
+ return false;
+ },
+
+
+ sendToBack : function(win){
+ win = this.get(win);
+ win._lastAccess = -(new Date().getTime());
+ orderWindows();
+ return win;
+ },
+
+
+ hideAll : function(){
+ for(var id in list){
+ if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
+ list[id].hide();
+ }
+ }
+ },
+
+
+ getActive : function(){
+ return front;
+ },
+
+
+ getBy : function(fn, scope){
+ var r = [];
+ for(var i = accessList.length-1; i >=0; --i) {
+ var win = accessList[i];
+ if(fn.call(scope||win, win) !== false){
+ r.push(win);
+ }
+ }
+ return r;
+ },
+
+
+ each : function(fn, scope){
+ for(var id in list){
+ if(list[id] && typeof list[id] != "function"){
+ if(fn.call(scope || list[id], list[id]) === false){
+ return;
+ }
+ }
+ }
+ }
+ };
+};
+
+
+
+Ext.WindowMgr = new Ext.WindowGroup();
+Ext.MessageBox = function(){
+ var dlg, opt, mask, waitTimer,
+ bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
+ buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
+ buttonNames = ['ok', 'yes', 'no', 'cancel'];
+
+
+ var handleButton = function(button){
+ buttons[button].blur();
+ if(dlg.isVisible()){
+ dlg.hide();
+ handleHide();
+ Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
+ }
+ };
+
+
+ var handleHide = function(){
+ if(opt && opt.cls){
+ dlg.el.removeClass(opt.cls);
+ }
+ progressBar.reset();
+ };
+
+
+ var handleEsc = function(d, k, e){
+ if(opt && opt.closable !== false){
+ dlg.hide();
+ handleHide();
+ }
+ if(e){
+ e.stopEvent();
+ }
+ };
+
+
+ var updateButtons = function(b){
+ var width = 0,
+ cfg;
+ if(!b){
+ Ext.each(buttonNames, function(name){
+ buttons[name].hide();
+ });
+ return width;
+ }
+ dlg.footer.dom.style.display = '';
+ Ext.iterate(buttons, function(name, btn){
+ cfg = b[name];
+ if(cfg){
+ btn.show();
+ btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
+ width += btn.getEl().getWidth() + 15;
+ }else{
+ btn.hide();
+ }
+ });
+ return width;
+ };
+
+ return {
+
+ getDialog : function(titleText){
+ if(!dlg){
+ var btns = [];
+
+ buttons = {};
+ Ext.each(buttonNames, function(name){
+ btns.push(buttons[name] = new Ext.Button({
+ text: this.buttonText[name],
+ handler: handleButton.createCallback(name),
+ hideMode: 'offsets'
+ }));
+ }, this);
+ dlg = new Ext.Window({
+ autoCreate : true,
+ title:titleText,
+ resizable:false,
+ constrain:true,
+ constrainHeader:true,
+ minimizable : false,
+ maximizable : false,
+ stateful: false,
+ modal: true,
+ shim:true,
+ buttonAlign:"center",
+ width:400,
+ height:100,
+ minHeight: 80,
+ plain:true,
+ footer:true,
+ closable:true,
+ close : function(){
+ if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
+ handleButton("no");
+ }else{
+ handleButton("cancel");
+ }
+ },
+ fbar: new Ext.Toolbar({
+ items: btns,
+ enableOverflow: false
+ })
+ });
+ dlg.render(document.body);
+ dlg.getEl().addClass('x-window-dlg');
+ mask = dlg.mask;
+ bodyEl = dlg.body.createChild({
+ html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
+ });
+ iconEl = Ext.get(bodyEl.dom.firstChild);
+ var contentEl = bodyEl.dom.childNodes[1];
+ msgEl = Ext.get(contentEl.firstChild);
+ textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
+ textboxEl.enableDisplayMode();
+ textboxEl.addKeyListener([10,13], function(){
+ if(dlg.isVisible() && opt && opt.buttons){
+ if(opt.buttons.ok){
+ handleButton("ok");
+ }else if(opt.buttons.yes){
+ handleButton("yes");
+ }
+ }
+ });
+ textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
+ textareaEl.enableDisplayMode();
+ progressBar = new Ext.ProgressBar({
+ renderTo:bodyEl
+ });
+ bodyEl.createChild({cls:'x-clear'});
+ }
+ return dlg;
+ },
+
+
+ updateText : function(text){
+ if(!dlg.isVisible() && !opt.width){
+ dlg.setSize(this.maxWidth, 100);
+ }
+
+ msgEl.update(text ? text + ' ' : '&#160;');
+
+ var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
+ mw = msgEl.getWidth() + msgEl.getMargins('lr'),
+ fw = dlg.getFrameWidth('lr'),
+ bw = dlg.body.getFrameWidth('lr'),
+ w;
+
+ w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
+ Math.max(opt.minWidth || this.minWidth, bwidth || 0));
+
+ if(opt.prompt === true){
+ activeTextEl.setWidth(w-iw-fw-bw);
+ }
+ if(opt.progress === true || opt.wait === true){
+ progressBar.setSize(w-iw-fw-bw);
+ }
+ if(Ext.isIE9m && w == bwidth){
+ w += 4;
+ }
+ msgEl.update(text || '&#160;');
+ dlg.setSize(w, 'auto').center();
+ return this;
+ },
+
+
+ updateProgress : function(value, progressText, msg){
+ progressBar.updateProgress(value, progressText);
+ if(msg){
+ this.updateText(msg);
+ }
+ return this;
+ },
+
+
+ isVisible : function(){
+ return dlg && dlg.isVisible();
+ },
+
+
+ hide : function(){
+ var proxy = dlg ? dlg.activeGhost : null;
+ if(this.isVisible() || proxy){
+ dlg.hide();
+ handleHide();
+ if (proxy){
+
+
+ dlg.unghost(false, false);
+ }
+ }
+ return this;
+ },
+
+
+ show : function(options){
+ if(this.isVisible()){
+ this.hide();
+ }
+ opt = options;
+ var d = this.getDialog(opt.title || "&#160;");
+
+ d.setTitle(opt.title || "&#160;");
+ var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
+ d.tools.close.setDisplayed(allowClose);
+ activeTextEl = textboxEl;
+ opt.prompt = opt.prompt || (opt.multiline ? true : false);
+ if(opt.prompt){
+ if(opt.multiline){
+ textboxEl.hide();
+ textareaEl.show();
+ textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
+ activeTextEl = textareaEl;
+ }else{
+ textboxEl.show();
+ textareaEl.hide();
+ }
+ }else{
+ textboxEl.hide();
+ textareaEl.hide();
+ }
+ activeTextEl.dom.value = opt.value || "";
+ if(opt.prompt){
+ d.focusEl = activeTextEl;
+ }else{
+ var bs = opt.buttons;
+ var db = null;
+ if(bs && bs.ok){
+ db = buttons["ok"];
+ }else if(bs && bs.yes){
+ db = buttons["yes"];
+ }
+ if (db){
+ d.focusEl = db;
+ }
+ }
+ if(Ext.isDefined(opt.iconCls)){
+ d.setIconClass(opt.iconCls);
+ }
+ this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
+ bwidth = updateButtons(opt.buttons);
+ progressBar.setVisible(opt.progress === true || opt.wait === true);
+ this.updateProgress(0, opt.progressText);
+ this.updateText(opt.msg);
+ if(opt.cls){
+ d.el.addClass(opt.cls);
+ }
+ d.proxyDrag = opt.proxyDrag === true;
+ d.modal = opt.modal !== false;
+ d.mask = opt.modal !== false ? mask : false;
+ if(!d.isVisible()){
+
+ document.body.appendChild(dlg.el.dom);
+ d.setAnimateTarget(opt.animEl);
+
+ d.on('show', function(){
+ if(allowClose === true){
+ d.keyMap.enable();
+ }else{
+ d.keyMap.disable();
+ }
+ }, this, {single:true});
+ d.show(opt.animEl);
+ }
+ if(opt.wait === true){
+ progressBar.wait(opt.waitConfig);
+ }
+ return this;
+ },
+
+
+ setIcon : function(icon){
+ if(!dlg){
+ bufferIcon = icon;
+ return;
+ }
+ bufferIcon = undefined;
+ if(icon && icon != ''){
+ iconEl.removeClass('x-hidden');
+ iconEl.replaceClass(iconCls, icon);
+ bodyEl.addClass('x-dlg-icon');
+ iconCls = icon;
+ }else{
+ iconEl.replaceClass(iconCls, 'x-hidden');
+ bodyEl.removeClass('x-dlg-icon');
+ iconCls = '';
+ }
+ return this;
+ },
+
+
+ progress : function(title, msg, progressText){
+ this.show({
+ title : title,
+ msg : msg,
+ buttons: false,
+ progress:true,
+ closable:false,
+ minWidth: this.minProgressWidth,
+ progressText: progressText
+ });
+ return this;
+ },
+
+
+ wait : function(msg, title, config){
+ this.show({
+ title : title,
+ msg : msg,
+ buttons: false,
+ closable:false,
+ wait:true,
+ modal:true,
+ minWidth: this.minProgressWidth,
+ waitConfig: config
+ });
+ return this;
+ },
+
+
+ alert : function(title, msg, fn, scope){
+ this.show({
+ title : title,
+ msg : msg,
+ buttons: this.OK,
+ fn: fn,
+ scope : scope,
+ minWidth: this.minWidth
+ });
+ return this;
+ },
+
+
+ confirm : function(title, msg, fn, scope){
+ this.show({
+ title : title,
+ msg : msg,
+ buttons: this.YESNO,
+ fn: fn,
+ scope : scope,
+ icon: this.QUESTION,
+ minWidth: this.minWidth
+ });
+ return this;
+ },
+
+
+ prompt : function(title, msg, fn, scope, multiline, value){
+ this.show({
+ title : title,
+ msg : msg,
+ buttons: this.OKCANCEL,
+ fn: fn,
+ minWidth: this.minPromptWidth,
+ scope : scope,
+ prompt:true,
+ multiline: multiline,
+ value: value
+ });
+ return this;
+ },
+
+
+ OK : {ok:true},
+
+ CANCEL : {cancel:true},
+
+ OKCANCEL : {ok:true, cancel:true},
+
+ YESNO : {yes:true, no:true},
+
+ YESNOCANCEL : {yes:true, no:true, cancel:true},
+
+ INFO : 'ext-mb-info',
+
+ WARNING : 'ext-mb-warning',
+
+ QUESTION : 'ext-mb-question',
+
+ ERROR : 'ext-mb-error',
+
+
+ defaultTextHeight : 75,
+
+ maxWidth : 600,
+
+ minWidth : 100,
+
+ minProgressWidth : 250,
+
+ minPromptWidth: 250,
+
+ buttonText : {
+ ok : "OK",
+ cancel : "Cancel",
+ yes : "Yes",
+ no : "No"
+ }
+ };
+}();
+
+
+Ext.Msg = Ext.MessageBox;
+Ext.dd.PanelProxy = Ext.extend(Object, {
+
+ constructor : function(panel, config){
+ this.panel = panel;
+ this.id = this.panel.id +'-ddproxy';
+ Ext.apply(this, config);
+ },
+
+
+ insertProxy : true,
+
+
+ setStatus : Ext.emptyFn,
+ reset : Ext.emptyFn,
+ update : Ext.emptyFn,
+ stop : Ext.emptyFn,
+ sync: Ext.emptyFn,
+
+
+ getEl : function(){
+ return this.ghost;
+ },
+
+
+ getGhost : function(){
+ return this.ghost;
+ },
+
+
+ getProxy : function(){
+ return this.proxy;
+ },
+
+
+ hide : function(){
+ if(this.ghost){
+ if(this.proxy){
+ this.proxy.remove();
+ delete this.proxy;
+ }
+ this.panel.el.dom.style.display = '';
+ this.ghost.remove();
+ delete this.ghost;
+ }
+ },
+
+
+ show : function(){
+ if(!this.ghost){
+ this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
+ this.ghost.setXY(this.panel.el.getXY());
+ if(this.insertProxy){
+ this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
+ this.proxy.setSize(this.panel.getSize());
+ }
+ this.panel.el.dom.style.display = 'none';
+ }
+ },
+
+
+ repair : function(xy, callback, scope){
+ this.hide();
+ if(typeof callback == "function"){
+ callback.call(scope || this);
+ }
+ },
+
+
+ moveProxy : function(parentNode, before){
+ if(this.proxy){
+ parentNode.insertBefore(this.proxy.dom, before);
+ }
+ }
+});
+
+
+Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
+
+ constructor : function(panel, cfg){
+ this.panel = panel;
+ this.dragData = {panel: panel};
+ this.proxy = new Ext.dd.PanelProxy(panel, cfg);
+ Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
+ var h = panel.header,
+ el = panel.body;
+ if(h){
+ this.setHandleElId(h.id);
+ el = panel.header;
+ }
+ el.setStyle('cursor', 'move');
+ this.scroll = false;
+ },
+
+ showFrame: Ext.emptyFn,
+ startDrag: Ext.emptyFn,
+ b4StartDrag: function(x, y) {
+ this.proxy.show();
+ },
+ b4MouseDown: function(e) {
+ var x = e.getPageX(),
+ y = e.getPageY();
+ this.autoOffset(x, y);
+ },
+ onInitDrag : function(x, y){
+ this.onStartDrag(x, y);
+ return true;
+ },
+ createFrame : Ext.emptyFn,
+ getDragEl : function(e){
+ return this.proxy.ghost.dom;
+ },
+ endDrag : function(e){
+ this.proxy.hide();
+ this.panel.saveState();
+ },
+
+ autoOffset : function(x, y) {
+ x -= this.startPageX;
+ y -= this.startPageY;
+ this.setDelta(x, y);
+ }
+});
+Ext.state.Provider = Ext.extend(Ext.util.Observable, {
+
+ constructor : function(){
+
+ this.addEvents("statechange");
+ this.state = {};
+ Ext.state.Provider.superclass.constructor.call(this);
+ },
+
+
+ get : function(name, defaultValue){
+ return typeof this.state[name] == "undefined" ?
+ defaultValue : this.state[name];
+ },
+
+
+ clear : function(name){
+ delete this.state[name];
+ this.fireEvent("statechange", this, name, null);
+ },
+
+
+ set : function(name, value){
+ this.state[name] = value;
+ this.fireEvent("statechange", this, name, value);
+ },
+
+
+ decodeValue : function(cookie){
+
+ var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
+ matches = re.exec(unescape(cookie)),
+ all,
+ type,
+ v,
+ kv;
+ if(!matches || !matches[1]){
+ return;
+ }
+ type = matches[1];
+ v = matches[2];
+ switch(type){
+ case 'e':
+ return null;
+ case 'n':
+ return parseFloat(v);
+ case 'd':
+ return new Date(Date.parse(v));
+ case 'b':
+ return (v == '1');
+ case 'a':
+ all = [];
+ if(v != ''){
+ Ext.each(v.split('^'), function(val){
+ all.push(this.decodeValue(val));
+ }, this);
+ }
+ return all;
+ case 'o':
+ all = {};
+ if(v != ''){
+ Ext.each(v.split('^'), function(val){
+ kv = val.split('=');
+ all[kv[0]] = this.decodeValue(kv[1]);
+ }, this);
+ }
+ return all;
+ default:
+ return v;
+ }
+ },
+
+
+ encodeValue : function(v){
+ var enc,
+ flat = '',
+ i = 0,
+ len,
+ key;
+ if(v == null){
+ return 'e:1';
+ }else if(typeof v == 'number'){
+ enc = 'n:' + v;
+ }else if(typeof v == 'boolean'){
+ enc = 'b:' + (v ? '1' : '0');
+ }else if(Ext.isDate(v)){
+ enc = 'd:' + v.toGMTString();
+ }else if(Ext.isArray(v)){
+ for(len = v.length; i < len; i++){
+ flat += this.encodeValue(v[i]);
+ if(i != len - 1){
+ flat += '^';
+ }
+ }
+ enc = 'a:' + flat;
+ }else if(typeof v == 'object'){
+ for(key in v){
+ if(typeof v[key] != 'function' && v[key] !== undefined){
+ flat += key + '=' + this.encodeValue(v[key]) + '^';
+ }
+ }
+ enc = 'o:' + flat.substring(0, flat.length-1);
+ }else{
+ enc = 's:' + v;
+ }
+ return escape(enc);
+ }
+});
+
+Ext.state.Manager = function(){
+ var provider = new Ext.state.Provider();
+
+ return {
+
+ setProvider : function(stateProvider){
+ provider = stateProvider;
+ },
+
+
+ get : function(key, defaultValue){
+ return provider.get(key, defaultValue);
+ },
+
+
+ set : function(key, value){
+ provider.set(key, value);
+ },
+
+
+ clear : function(key){
+ provider.clear(key);
+ },
+
+
+ getProvider : function(){
+ return provider;
+ }
+ };
+}();
+
+Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
+
+ constructor : function(config){
+ 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, config);
+ this.state = this.readCookies();
+ },
+
+
+ set : function(name, value){
+ if(typeof value == "undefined" || value === null){
+ this.clear(name);
+ return;
+ }
+ this.setCookie(name, value);
+ Ext.state.CookieProvider.superclass.set.call(this, name, value);
+ },
+
+
+ clear : function(name){
+ this.clearCookie(name);
+ Ext.state.CookieProvider.superclass.clear.call(this, name);
+ },
+
+
+ readCookies : function(){
+ var cookies = {},
+ c = document.cookie + ";",
+ re = /\s?(.*?)=(.*?);/g,
+ matches,
+ name,
+ value;
+ while((matches = re.exec(c)) != null){
+ name = matches[1];
+ value = matches[2];
+ if(name && name.substring(0,3) == "ys-"){
+ cookies[name.substr(3)] = this.decodeValue(value);
+ }
+ }
+ return cookies;
+ },
+
+
+ setCookie : function(name, value){
+ document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
+ ((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(name){
+ document.cookie = "ys-" + name + "=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" : "");
+ }
+});
+Ext.DataView = Ext.extend(Ext.BoxComponent, {
+
+
+
+
+
+
+
+
+
+ selectedClass : "x-view-selected",
+
+ emptyText : "",
+
+
+ deferEmptyText: true,
+
+ trackOver: false,
+
+
+ blockRefresh: false,
+
+
+ last: false,
+
+
+ initComponent : function(){
+ Ext.DataView.superclass.initComponent.call(this);
+ if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
+ this.tpl = new Ext.XTemplate(this.tpl);
+ }
+
+ this.addEvents(
+
+ "beforeclick",
+
+ "click",
+
+ "mouseenter",
+
+ "mouseleave",
+
+ "containerclick",
+
+ "dblclick",
+
+ "contextmenu",
+
+ "containercontextmenu",
+
+ "selectionchange",
+
+
+ "beforeselect"
+ );
+
+ this.store = Ext.StoreMgr.lookup(this.store);
+ this.all = new Ext.CompositeElementLite();
+ this.selected = new Ext.CompositeElementLite();
+ },
+
+
+ afterRender : function(){
+ Ext.DataView.superclass.afterRender.call(this);
+
+ this.mon(this.getTemplateTarget(), {
+ "click": this.onClick,
+ "dblclick": this.onDblClick,
+ "contextmenu": this.onContextMenu,
+ scope:this
+ });
+
+ if(this.overClass || this.trackOver){
+ this.mon(this.getTemplateTarget(), {
+ "mouseover": this.onMouseOver,
+ "mouseout": this.onMouseOut,
+ scope:this
+ });
+ }
+
+ if(this.store){
+ this.bindStore(this.store, true);
+ }
+ },
+
+
+ refresh : function() {
+ this.clearSelections(false, true);
+ var el = this.getTemplateTarget(),
+ records = this.store.getRange();
+
+ el.update('');
+ if(records.length < 1){
+ if(!this.deferEmptyText || this.hasSkippedEmptyText){
+ el.update(this.emptyText);
+ }
+ this.all.clear();
+ }else{
+ this.tpl.overwrite(el, this.collectData(records, 0));
+ this.all.fill(Ext.query(this.itemSelector, el.dom));
+ this.updateIndexes(0);
+ }
+ this.hasSkippedEmptyText = true;
+ },
+
+ getTemplateTarget: function(){
+ return this.el;
+ },
+
+
+ prepareData : function(data){
+ return data;
+ },
+
+
+ collectData : function(records, startIndex){
+ var r = [],
+ i = 0,
+ len = records.length;
+ for(; i < len; i++){
+ r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
+ }
+ return r;
+ },
+
+
+ bufferRender : function(records, index){
+ var div = document.createElement('div');
+ this.tpl.overwrite(div, this.collectData(records, index));
+ return Ext.query(this.itemSelector, div);
+ },
+
+
+ onUpdate : function(ds, record){
+ var index = this.store.indexOf(record);
+ if(index > -1){
+ var sel = this.isSelected(index),
+ original = this.all.elements[index],
+ node = this.bufferRender([record], index)[0];
+
+ this.all.replaceElement(index, node, true);
+ if(sel){
+ this.selected.replaceElement(original, node);
+ this.all.item(index).addClass(this.selectedClass);
+ }
+ this.updateIndexes(index, index);
+ }
+ },
+
+
+ onAdd : function(ds, records, index){
+ if(this.all.getCount() === 0){
+ this.refresh();
+ return;
+ }
+ var nodes = this.bufferRender(records, index), n, a = this.all.elements;
+ if(index < this.all.getCount()){
+ n = this.all.item(index).insertSibling(nodes, 'before', true);
+ a.splice.apply(a, [index, 0].concat(nodes));
+ }else{
+ n = this.all.last().insertSibling(nodes, 'after', true);
+ a.push.apply(a, nodes);
+ }
+ this.updateIndexes(index);
+ },
+
+
+ onRemove : function(ds, record, index){
+ this.deselect(index);
+ this.all.removeElement(index, true);
+ this.updateIndexes(index);
+ if (this.store.getCount() === 0){
+ this.refresh();
+ }
+ },
+
+
+ refreshNode : function(index){
+ this.onUpdate(this.store, this.store.getAt(index));
+ },
+
+
+ updateIndexes : function(startIndex, endIndex){
+ var ns = this.all.elements;
+ startIndex = startIndex || 0;
+ endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
+ for(var i = startIndex; i <= endIndex; i++){
+ ns[i].viewIndex = i;
+ }
+ },
+
+
+ getStore : function(){
+ return this.store;
+ },
+
+
+ bindStore : function(store, initial){
+ if(!initial && this.store){
+ if(store !== this.store && this.store.autoDestroy){
+ this.store.destroy();
+ }else{
+ this.store.un("beforeload", this.onBeforeLoad, this);
+ this.store.un("datachanged", this.onDataChanged, this);
+ this.store.un("add", this.onAdd, this);
+ this.store.un("remove", this.onRemove, this);
+ this.store.un("update", this.onUpdate, this);
+ this.store.un("clear", this.refresh, this);
+ }
+ if(!store){
+ this.store = null;
+ }
+ }
+ if(store){
+ store = Ext.StoreMgr.lookup(store);
+ store.on({
+ scope: this,
+ beforeload: this.onBeforeLoad,
+ datachanged: this.onDataChanged,
+ add: this.onAdd,
+ remove: this.onRemove,
+ update: this.onUpdate,
+ clear: this.refresh
+ });
+ }
+ this.store = store;
+ if(store){
+ this.refresh();
+ }
+ },
+
+
+ onDataChanged: function() {
+ if (this.blockRefresh !== true) {
+ this.refresh.apply(this, arguments);
+ }
+ },
+
+
+ findItemFromChild : function(node){
+ return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
+ },
+
+
+ onClick : function(e){
+ var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
+ index;
+ if(item){
+ index = this.indexOf(item);
+ if(this.onItemClick(item, index, e) !== false){
+ this.fireEvent("click", this, index, item, e);
+ }
+ }else{
+ if(this.fireEvent("containerclick", this, e) !== false){
+ this.onContainerClick(e);
+ }
+ }
+ },
+
+ onContainerClick : function(e){
+ this.clearSelections();
+ },
+
+
+ onContextMenu : function(e){
+ var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
+ if(item){
+ this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
+ }else{
+ this.fireEvent("containercontextmenu", this, e);
+ }
+ },
+
+
+ onDblClick : function(e){
+ var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
+ if(item){
+ this.fireEvent("dblclick", this, this.indexOf(item), item, e);
+ }
+ },
+
+
+ onMouseOver : function(e){
+ var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
+ if(item && item !== this.lastItem){
+ this.lastItem = item;
+ Ext.fly(item).addClass(this.overClass);
+ this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
+ }
+ },
+
+
+ onMouseOut : function(e){
+ if(this.lastItem){
+ if(!e.within(this.lastItem, true, true)){
+ Ext.fly(this.lastItem).removeClass(this.overClass);
+ this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
+ delete this.lastItem;
+ }
+ }
+ },
+
+
+ onItemClick : function(item, index, e){
+ if(this.fireEvent("beforeclick", this, index, item, e) === false){
+ return false;
+ }
+ if(this.multiSelect){
+ this.doMultiSelection(item, index, e);
+ e.preventDefault();
+ }else if(this.singleSelect){
+ this.doSingleSelection(item, index, e);
+ e.preventDefault();
+ }
+ return true;
+ },
+
+
+ doSingleSelection : function(item, index, e){
+ if(e.ctrlKey && this.isSelected(index)){
+ this.deselect(index);
+ }else{
+ this.select(index, false);
+ }
+ },
+
+
+ doMultiSelection : function(item, index, e){
+ if(e.shiftKey && this.last !== false){
+ var last = this.last;
+ this.selectRange(last, index, e.ctrlKey);
+ this.last = last;
+ }else{
+ if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
+ this.deselect(index);
+ }else{
+ this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
+ }
+ }
+ },
+
+
+ getSelectionCount : function(){
+ return this.selected.getCount();
+ },
+
+
+ getSelectedNodes : function(){
+ return this.selected.elements;
+ },
+
+
+ getSelectedIndexes : function(){
+ var indexes = [],
+ selected = this.selected.elements,
+ i = 0,
+ len = selected.length;
+
+ for(; i < len; i++){
+ indexes.push(selected[i].viewIndex);
+ }
+ return indexes;
+ },
+
+
+ getSelectedRecords : function(){
+ return this.getRecords(this.selected.elements);
+ },
+
+
+ getRecords : function(nodes){
+ var records = [],
+ i = 0,
+ len = nodes.length;
+
+ for(; i < len; i++){
+ records[records.length] = this.store.getAt(nodes[i].viewIndex);
+ }
+ return records;
+ },
+
+
+ getRecord : function(node){
+ return this.store.getAt(node.viewIndex);
+ },
+
+
+ clearSelections : function(suppressEvent, skipUpdate){
+ if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
+ if(!skipUpdate){
+ this.selected.removeClass(this.selectedClass);
+ }
+ this.selected.clear();
+ this.last = false;
+ if(!suppressEvent){
+ this.fireEvent("selectionchange", this, this.selected.elements);
+ }
+ }
+ },
+
+
+ isSelected : function(node){
+ return this.selected.contains(this.getNode(node));
+ },
+
+
+ deselect : function(node){
+ if(this.isSelected(node)){
+ node = this.getNode(node);
+ this.selected.removeElement(node);
+ if(this.last == node.viewIndex){
+ this.last = false;
+ }
+ Ext.fly(node).removeClass(this.selectedClass);
+ this.fireEvent("selectionchange", this, this.selected.elements);
+ }
+ },
+
+
+ select : function(nodeInfo, keepExisting, suppressEvent){
+ if(Ext.isArray(nodeInfo)){
+ if(!keepExisting){
+ this.clearSelections(true);
+ }
+ for(var i = 0, len = nodeInfo.length; i < len; i++){
+ this.select(nodeInfo[i], true, true);
+ }
+ if(!suppressEvent){
+ this.fireEvent("selectionchange", this, this.selected.elements);
+ }
+ } else{
+ var node = this.getNode(nodeInfo);
+ if(!keepExisting){
+ this.clearSelections(true);
+ }
+ if(node && !this.isSelected(node)){
+ if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
+ Ext.fly(node).addClass(this.selectedClass);
+ this.selected.add(node);
+ this.last = node.viewIndex;
+ if(!suppressEvent){
+ this.fireEvent("selectionchange", this, this.selected.elements);
+ }
+ }
+ }
+ }
+ },
+
+
+ selectRange : function(start, end, keepExisting){
+ if(!keepExisting){
+ this.clearSelections(true);
+ }
+ this.select(this.getNodes(start, end), true);
+ },
+
+
+ getNode : function(nodeInfo){
+ if(Ext.isString(nodeInfo)){
+ return document.getElementById(nodeInfo);
+ }else if(Ext.isNumber(nodeInfo)){
+ return this.all.elements[nodeInfo];
+ }else if(nodeInfo instanceof Ext.data.Record){
+ var idx = this.store.indexOf(nodeInfo);
+ return this.all.elements[idx];
+ }
+ return nodeInfo;
+ },
+
+
+ getNodes : function(start, end){
+ var ns = this.all.elements,
+ nodes = [],
+ i;
+
+ start = start || 0;
+ end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
+ if(start <= end){
+ for(i = start; i <= end && ns[i]; i++){
+ nodes.push(ns[i]);
+ }
+ } else{
+ for(i = start; i >= end && ns[i]; i--){
+ nodes.push(ns[i]);
+ }
+ }
+ return nodes;
+ },
+
+
+ indexOf : function(node){
+ node = this.getNode(node);
+ if(Ext.isNumber(node.viewIndex)){
+ return node.viewIndex;
+ }
+ return this.all.indexOf(node);
+ },
+
+
+ onBeforeLoad : function(){
+ if(this.loadingText){
+ this.clearSelections(false, true);
+ this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
+ this.all.clear();
+ }
+ },
+
+ onDestroy : function(){
+ this.all.clear();
+ this.selected.clear();
+ Ext.DataView.superclass.onDestroy.call(this);
+ this.bindStore(null);
+ }
+});
+
+
+Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
+
+Ext.reg('dataview', Ext.DataView);
+
+Ext.list.ListView = Ext.extend(Ext.DataView, {
+
+
+
+ itemSelector: 'dl',
+
+ selectedClass:'x-list-selected',
+
+ overClass:'x-list-over',
+
+
+ scrollOffset : undefined,
+
+ columnResize: true,
+
+
+ columnSort: true,
+
+
+
+ maxColumnWidth: Ext.isIE9m ? 99 : 100,
+
+ initComponent : function(){
+ if(this.columnResize){
+ this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
+ this.colResizer.init(this);
+ }
+ if(this.columnSort){
+ this.colSorter = new Ext.list.Sorter(this.columnSort);
+ this.colSorter.init(this);
+ }
+ if(!this.internalTpl){
+ this.internalTpl = new Ext.XTemplate(
+ '<div class="x-list-header"><div class="x-list-header-inner">',
+ '<tpl for="columns">',
+ '<div style="width:{[values.width*100]}%;text-align:{align};"><em class="x-unselectable" unselectable="on" id="',this.id, '-xlhd-{#}">',
+ '{header}',
+ '</em></div>',
+ '</tpl>',
+ '<div class="x-clear"></div>',
+ '</div></div>',
+ '<div class="x-list-body"><div class="x-list-body-inner">',
+ '</div></div>'
+ );
+ }
+ if(!this.tpl){
+ this.tpl = new Ext.XTemplate(
+ '<tpl for="rows">',
+ '<dl>',
+ '<tpl for="parent.columns">',
+ '<dt style="width:{[values.width*100]}%;text-align:{align};">',
+ '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
+ '{[values.tpl.apply(parent)]}',
+ '</em></dt>',
+ '</tpl>',
+ '<div class="x-clear"></div>',
+ '</dl>',
+ '</tpl>'
+ );
+ };
+
+ var cs = this.columns,
+ allocatedWidth = 0,
+ colsWithWidth = 0,
+ len = cs.length,
+ columns = [];
+
+ for(var i = 0; i < len; i++){
+ var c = cs[i];
+ if(!c.isColumn) {
+ c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
+ c = Ext.create(c);
+ }
+ if(c.width) {
+ allocatedWidth += c.width*100;
+ if(allocatedWidth > this.maxColumnWidth){
+ c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
+ }
+ colsWithWidth++;
+ }
+ columns.push(c);
+ }
+
+ cs = this.columns = columns;
+
+
+ if(colsWithWidth < len){
+ var remaining = len - colsWithWidth;
+ if(allocatedWidth < this.maxColumnWidth){
+ var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
+ for(var j = 0; j < len; j++){
+ var c = cs[j];
+ if(!c.width){
+ c.width = perCol;
+ }
+ }
+ }
+ }
+ Ext.list.ListView.superclass.initComponent.call(this);
+ },
+
+ onRender : function(){
+ this.autoEl = {
+ cls: 'x-list-wrap'
+ };
+ Ext.list.ListView.superclass.onRender.apply(this, arguments);
+
+ this.internalTpl.overwrite(this.el, {columns: this.columns});
+
+ this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
+ this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
+
+ if(this.hideHeaders){
+ this.el.dom.firstChild.style.display = 'none';
+ }
+ },
+
+ getTemplateTarget : function(){
+ return this.innerBody;
+ },
+
+
+ collectData : function(){
+ var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
+ return {
+ columns: this.columns,
+ rows: rs
+ };
+ },
+
+ verifyInternalSize : function(){
+ if(this.lastSize){
+ this.onResize(this.lastSize.width, this.lastSize.height);
+ }
+ },
+
+
+ onResize : function(w, h){
+ var body = this.innerBody.dom,
+ header = this.innerHd.dom,
+ scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
+ parentNode;
+
+ if(!body){
+ return;
+ }
+ parentNode = body.parentNode;
+ if(Ext.isNumber(w)){
+ if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
+ body.style.width = scrollWidth;
+ header.style.width = scrollWidth;
+ }else{
+ body.style.width = w + 'px';
+ header.style.width = w + 'px';
+ setTimeout(function(){
+ if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
+ body.style.width = scrollWidth;
+ header.style.width = scrollWidth;
+ }
+ }, 10);
+ }
+ }
+ if(Ext.isNumber(h)){
+ parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
+ }
+ },
+
+ updateIndexes : function(){
+ Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
+ this.verifyInternalSize();
+ },
+
+ findHeaderIndex : function(header){
+ header = header.dom || header;
+ var parentNode = header.parentNode,
+ children = parentNode.parentNode.childNodes,
+ i = 0,
+ c;
+ for(; c = children[i]; i++){
+ if(c == parentNode){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ setHdWidths : function(){
+ var els = this.innerHd.dom.getElementsByTagName('div'),
+ i = 0,
+ columns = this.columns,
+ len = columns.length;
+
+ for(; i < len; i++){
+ els[i].style.width = (columns[i].width*100) + '%';
+ }
+ }
+});
+
+Ext.reg('listview', Ext.list.ListView);
+
+
+Ext.ListView = Ext.list.ListView;
+Ext.list.Column = Ext.extend(Object, {
+
+ isColumn: true,
+
+
+ align: 'left',
+
+ header: '',
+
+
+ width: null,
+
+
+ cls: '',
+
+
+
+
+
+ constructor : function(c){
+ if(!c.tpl){
+ c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
+ }
+ else if(Ext.isString(c.tpl)){
+ c.tpl = new Ext.XTemplate(c.tpl);
+ }
+
+ Ext.apply(this, c);
+ }
+});
+
+Ext.reg('lvcolumn', Ext.list.Column);
+
+
+Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
+
+ format: '0,000.00',
+
+ constructor : function(c) {
+ c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
+ Ext.list.NumberColumn.superclass.constructor.call(this, c);
+ }
+});
+
+Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
+
+
+Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
+ format: 'm/d/Y',
+ constructor : function(c) {
+ c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
+ Ext.list.DateColumn.superclass.constructor.call(this, c);
+ }
+});
+Ext.reg('lvdatecolumn', Ext.list.DateColumn);
+
+
+Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
+
+ trueText: 'true',
+
+ falseText: 'false',
+
+ undefinedText: '&#160;',
+
+ constructor : function(c) {
+ c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
+
+ var t = this.trueText, f = this.falseText, u = this.undefinedText;
+ c.tpl.format = function(v){
+ if(v === undefined){
+ return u;
+ }
+ if(!v || v === 'false'){
+ return f;
+ }
+ return t;
+ };
+
+ Ext.list.DateColumn.superclass.constructor.call(this, c);
+ }
+});
+
+Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
+Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
+
+ minPct: .05,
+
+ constructor: function(config){
+ Ext.apply(this, config);
+ Ext.list.ColumnResizer.superclass.constructor.call(this);
+ },
+ init : function(listView){
+ this.view = listView;
+ listView.on('render', this.initEvents, this);
+ },
+
+ initEvents : function(view){
+ view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
+ this.tracker = new Ext.dd.DragTracker({
+ onBeforeStart: this.onBeforeStart.createDelegate(this),
+ onStart: this.onStart.createDelegate(this),
+ onDrag: this.onDrag.createDelegate(this),
+ onEnd: this.onEnd.createDelegate(this),
+ tolerance: 3,
+ autoStart: 300
+ });
+ this.tracker.initEl(view.innerHd);
+ view.on('beforedestroy', this.tracker.destroy, this.tracker);
+ },
+
+ handleHdMove : function(e, t){
+ var handleWidth = 5,
+ x = e.getPageX(),
+ header = e.getTarget('em', 3, true);
+ if(header){
+ var region = header.getRegion(),
+ style = header.dom.style,
+ parentNode = header.dom.parentNode;
+
+ if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
+ this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
+ style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
+ } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
+ this.activeHd = header;
+ style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
+ } else{
+ delete this.activeHd;
+ style.cursor = '';
+ }
+ }
+ },
+
+ onBeforeStart : function(e){
+ this.dragHd = this.activeHd;
+ return !!this.dragHd;
+ },
+
+ onStart: function(e){
+
+ var me = this,
+ view = me.view,
+ dragHeader = me.dragHd,
+ x = me.tracker.getXY()[0];
+
+ me.proxy = view.el.createChild({cls:'x-list-resizer'});
+ me.dragX = dragHeader.getX();
+ me.headerIndex = view.findHeaderIndex(dragHeader);
+
+ me.headersDisabled = view.disableHeaders;
+ view.disableHeaders = true;
+
+ me.proxy.setHeight(view.el.getHeight());
+ me.proxy.setX(me.dragX);
+ me.proxy.setWidth(x - me.dragX);
+
+ this.setBoundaries();
+
+ },
+
+
+ setBoundaries: function(relativeX){
+ var view = this.view,
+ headerIndex = this.headerIndex,
+ width = view.innerHd.getWidth(),
+ relativeX = view.innerHd.getX(),
+ minWidth = Math.ceil(width * this.minPct),
+ maxWidth = width - minWidth,
+ numColumns = view.columns.length,
+ headers = view.innerHd.select('em', true),
+ minX = minWidth + relativeX,
+ maxX = maxWidth + relativeX,
+ header;
+
+ if (numColumns == 2) {
+ this.minX = minX;
+ this.maxX = maxX;
+ }else{
+ header = headers.item(headerIndex + 2);
+ this.minX = headers.item(headerIndex).getX() + minWidth;
+ this.maxX = header ? header.getX() - minWidth : maxX;
+ if (headerIndex == 0) {
+
+ this.minX = minX;
+ } else if (headerIndex == numColumns - 2) {
+
+ this.maxX = maxX;
+ }
+ }
+ },
+
+ onDrag: function(e){
+ var me = this,
+ cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);
+
+ me.proxy.setWidth(cursorX - this.dragX);
+ },
+
+ onEnd: function(e){
+
+ var newWidth = this.proxy.getWidth(),
+ index = this.headerIndex,
+ view = this.view,
+ columns = view.columns,
+ width = view.innerHd.getWidth(),
+ newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
+ disabled = this.headersDisabled,
+ headerCol = columns[index],
+ otherCol = columns[index + 1],
+ totalPercent = headerCol.width + otherCol.width;
+
+ this.proxy.remove();
+
+ headerCol.width = newPercent;
+ otherCol.width = totalPercent - newPercent;
+
+ delete this.dragHd;
+ view.setHdWidths();
+ view.refresh();
+
+ setTimeout(function(){
+ view.disableHeaders = disabled;
+ }, 100);
+ }
+});
+
+
+Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
+Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
+
+ sortClasses : ["sort-asc", "sort-desc"],
+
+ constructor: function(config){
+ Ext.apply(this, config);
+ Ext.list.Sorter.superclass.constructor.call(this);
+ },
+
+ init : function(listView){
+ this.view = listView;
+ listView.on('render', this.initEvents, this);
+ },
+
+ initEvents : function(view){
+ view.mon(view.innerHd, 'click', this.onHdClick, this);
+ view.innerHd.setStyle('cursor', 'pointer');
+ view.mon(view.store, 'datachanged', this.updateSortState, this);
+ this.updateSortState.defer(10, this, [view.store]);
+ },
+
+ updateSortState : function(store){
+ var state = store.getSortState();
+ if(!state){
+ return;
+ }
+ this.sortState = state;
+ var cs = this.view.columns, sortColumn = -1;
+ for(var i = 0, len = cs.length; i < len; i++){
+ if(cs[i].dataIndex == state.field){
+ sortColumn = i;
+ break;
+ }
+ }
+ if(sortColumn != -1){
+ var sortDir = state.direction;
+ this.updateSortIcon(sortColumn, sortDir);
+ }
+ },
+
+ updateSortIcon : function(col, dir){
+ var sc = this.sortClasses;
+ var hds = this.view.innerHd.select('em').removeClass(sc);
+ hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
+ },
+
+ onHdClick : function(e){
+ var hd = e.getTarget('em', 3);
+ if(hd && !this.view.disableHeaders){
+ var index = this.view.findHeaderIndex(hd);
+ this.view.store.sort(this.view.columns[index].dataIndex);
+ }
+ }
+});
+
+
+Ext.ListView.Sorter = Ext.list.Sorter;
+Ext.TabPanel = Ext.extend(Ext.Panel, {
+
+
+
+ deferredRender : true,
+
+ tabWidth : 120,
+
+ minTabWidth : 30,
+
+ resizeTabs : false,
+
+ enableTabScroll : false,
+
+ scrollIncrement : 0,
+
+ scrollRepeatInterval : 400,
+
+ scrollDuration : 0.35,
+
+ animScroll : true,
+
+ tabPosition : 'top',
+
+ baseCls : 'x-tab-panel',
+
+ autoTabs : false,
+
+ autoTabSelector : 'div.x-tab',
+
+ activeTab : undefined,
+
+ tabMargin : 2,
+
+ plain : false,
+
+ wheelIncrement : 20,
+
+
+ idDelimiter : '__',
+
+
+ itemCls : 'x-tab-item',
+
+
+ elements : 'body',
+ headerAsText : false,
+ frame : false,
+ hideBorders :true,
+
+
+ initComponent : function(){
+ this.frame = false;
+ Ext.TabPanel.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'beforetabchange',
+
+ 'tabchange',
+
+ 'contextmenu'
+ );
+
+ this.setLayout(new Ext.layout.CardLayout(Ext.apply({
+ layoutOnCardChange: this.layoutOnTabChange,
+ deferredRender: this.deferredRender
+ }, this.layoutConfig)));
+
+ if(this.tabPosition == 'top'){
+ this.elements += ',header';
+ this.stripTarget = 'header';
+ }else {
+ this.elements += ',footer';
+ this.stripTarget = 'footer';
+ }
+ if(!this.stack){
+ this.stack = Ext.TabPanel.AccessStack();
+ }
+ this.initItems();
+ },
+
+
+ onRender : function(ct, position){
+ Ext.TabPanel.superclass.onRender.call(this, ct, position);
+
+ if(this.plain){
+ var pos = this.tabPosition == 'top' ? 'header' : 'footer';
+ this[pos].addClass('x-tab-panel-'+pos+'-plain');
+ }
+
+ var st = this[this.stripTarget];
+
+ this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
+ tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
+
+ var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
+ st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
+ this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
+
+
+ this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: '&#160;'}]});
+ this.strip.createChild({cls:'x-clear'});
+
+ this.body.addClass('x-tab-panel-body-'+this.tabPosition);
+
+
+ if(!this.itemTpl){
+ var tt = new Ext.Template(
+ '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
+ '<a class="x-tab-right" href="#"><em class="x-tab-left">',
+ '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
+ '</em></a></li>'
+ );
+ tt.disableFormats = true;
+ tt.compile();
+ Ext.TabPanel.prototype.itemTpl = tt;
+ }
+
+ this.items.each(this.initTab, this);
+ },
+
+
+ afterRender : function(){
+ Ext.TabPanel.superclass.afterRender.call(this);
+ if(this.autoTabs){
+ this.readTabs(false);
+ }
+ if(this.activeTab !== undefined){
+ var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
+ delete this.activeTab;
+ this.setActiveTab(item);
+ }
+ },
+
+
+ initEvents : function(){
+ Ext.TabPanel.superclass.initEvents.call(this);
+ this.mon(this.strip, {
+ scope: this,
+ mousedown: this.onStripMouseDown,
+ contextmenu: this.onStripContextMenu
+ });
+ if(this.enableTabScroll){
+ this.mon(this.strip, 'mousewheel', this.onWheel, this);
+ }
+ },
+
+
+ findTargets : function(e){
+ var item = null,
+ itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
+
+ if(itemEl){
+ item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
+ if(item.disabled){
+ return {
+ close : null,
+ item : null,
+ el : null
+ };
+ }
+ }
+ return {
+ close : e.getTarget('.x-tab-strip-close', this.strip),
+ item : item,
+ el : itemEl
+ };
+ },
+
+
+ onStripMouseDown : function(e){
+ if(e.button !== 0){
+ return;
+ }
+ e.preventDefault();
+ var t = this.findTargets(e);
+ if(t.close){
+ if (t.item.fireEvent('beforeclose', t.item) !== false) {
+ t.item.fireEvent('close', t.item);
+ this.remove(t.item);
+ }
+ return;
+ }
+ if(t.item && t.item != this.activeTab){
+ this.setActiveTab(t.item);
+ }
+ },
+
+
+ onStripContextMenu : function(e){
+ e.preventDefault();
+ var t = this.findTargets(e);
+ if(t.item){
+ this.fireEvent('contextmenu', this, t.item, e);
+ }
+ },
+
+
+ readTabs : function(removeExisting){
+ if(removeExisting === true){
+ this.items.each(function(item){
+ this.remove(item);
+ }, this);
+ }
+ var tabs = this.el.query(this.autoTabSelector);
+ for(var i = 0, len = tabs.length; i < len; i++){
+ var tab = tabs[i],
+ title = tab.getAttribute('title');
+ tab.removeAttribute('title');
+ this.add({
+ title: title,
+ contentEl: tab
+ });
+ }
+ },
+
+
+ initTab : function(item, index){
+ var before = this.strip.dom.childNodes[index],
+ p = this.getTemplateArgs(item),
+ el = before ?
+ this.itemTpl.insertBefore(before, p) :
+ this.itemTpl.append(this.strip, p),
+ cls = 'x-tab-strip-over',
+ tabEl = Ext.get(el);
+
+ tabEl.hover(function(){
+ if(!item.disabled){
+ tabEl.addClass(cls);
+ }
+ }, function(){
+ tabEl.removeClass(cls);
+ });
+
+ if(item.tabTip){
+ tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
+ }
+ item.tabEl = el;
+
+
+ tabEl.select('a').on('click', function(e){
+ if(!e.getPageX()){
+ this.onStripMouseDown(e);
+ }
+ }, this, {preventDefault: true});
+
+ item.on({
+ scope: this,
+ disable: this.onItemDisabled,
+ enable: this.onItemEnabled,
+ titlechange: this.onItemTitleChanged,
+ iconchange: this.onItemIconChanged,
+ beforeshow: this.onBeforeShowItem
+ });
+ },
+
+
+
+
+ getTemplateArgs : function(item) {
+ var cls = item.closable ? 'x-tab-strip-closable' : '';
+ if(item.disabled){
+ cls += ' x-item-disabled';
+ }
+ if(item.iconCls){
+ cls += ' x-tab-with-icon';
+ }
+ if(item.tabCls){
+ cls += ' ' + item.tabCls;
+ }
+
+ return {
+ id: this.id + this.idDelimiter + item.getItemId(),
+ text: item.title,
+ cls: cls,
+ iconCls: item.iconCls || ''
+ };
+ },
+
+
+ onAdd : function(c){
+ Ext.TabPanel.superclass.onAdd.call(this, c);
+ if(this.rendered){
+ var items = this.items;
+ this.initTab(c, items.indexOf(c));
+ this.delegateUpdates();
+ }
+ },
+
+
+ onBeforeAdd : function(item){
+ var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
+ if(existing){
+ this.setActiveTab(item);
+ return false;
+ }
+ Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
+ var es = item.elements;
+ item.elements = es ? es.replace(',header', '') : es;
+ item.border = (item.border === true);
+ },
+
+
+ onRemove : function(c){
+ var te = Ext.get(c.tabEl);
+
+ if(te){
+ te.select('a').removeAllListeners();
+ Ext.destroy(te);
+ }
+ Ext.TabPanel.superclass.onRemove.call(this, c);
+ this.stack.remove(c);
+ delete c.tabEl;
+ c.un('disable', this.onItemDisabled, this);
+ c.un('enable', this.onItemEnabled, this);
+ c.un('titlechange', this.onItemTitleChanged, this);
+ c.un('iconchange', this.onItemIconChanged, this);
+ c.un('beforeshow', this.onBeforeShowItem, this);
+ if(c == this.activeTab){
+ var next = this.stack.next();
+ if(next){
+ this.setActiveTab(next);
+ }else if(this.items.getCount() > 0){
+ this.setActiveTab(0);
+ }else{
+ this.setActiveTab(null);
+ }
+ }
+ if(!this.destroying){
+ this.delegateUpdates();
+ }
+ },
+
+
+ onBeforeShowItem : function(item){
+ if(item != this.activeTab){
+ this.setActiveTab(item);
+ return false;
+ }
+ },
+
+
+ onItemDisabled : function(item){
+ var el = this.getTabEl(item);
+ if(el){
+ Ext.fly(el).addClass('x-item-disabled');
+ }
+ this.stack.remove(item);
+ },
+
+
+ onItemEnabled : function(item){
+ var el = this.getTabEl(item);
+ if(el){
+ Ext.fly(el).removeClass('x-item-disabled');
+ }
+ },
+
+
+ onItemTitleChanged : function(item){
+ var el = this.getTabEl(item);
+ if(el){
+ Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
+ this.delegateUpdates();
+ }
+ },
+
+
+ onItemIconChanged : function(item, iconCls, oldCls){
+ var el = this.getTabEl(item);
+ if(el){
+ el = Ext.get(el);
+ el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
+ el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
+ this.delegateUpdates();
+ }
+ },
+
+
+ getTabEl : function(item){
+ var c = this.getComponent(item);
+ return c ? c.tabEl : null;
+ },
+
+
+ onResize : function(){
+ Ext.TabPanel.superclass.onResize.apply(this, arguments);
+ this.delegateUpdates();
+ },
+
+
+ beginUpdate : function(){
+ this.suspendUpdates = true;
+ },
+
+
+ endUpdate : function(){
+ this.suspendUpdates = false;
+ this.delegateUpdates();
+ },
+
+
+ hideTabStripItem : function(item){
+ item = this.getComponent(item);
+ var el = this.getTabEl(item);
+ if(el){
+ el.style.display = 'none';
+ this.delegateUpdates();
+ }
+ this.stack.remove(item);
+ },
+
+
+ unhideTabStripItem : function(item){
+ item = this.getComponent(item);
+ var el = this.getTabEl(item);
+ if(el){
+ el.style.display = '';
+ this.delegateUpdates();
+ }
+ },
+
+
+ delegateUpdates : function(){
+ var rendered = this.rendered;
+ if(this.suspendUpdates){
+ return;
+ }
+ if(this.resizeTabs && rendered){
+ this.autoSizeTabs();
+ }
+ if(this.enableTabScroll && rendered){
+ this.autoScrollTabs();
+ }
+ },
+
+
+ autoSizeTabs : function(){
+ var count = this.items.length,
+ ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
+ ow = this[ce].dom.offsetWidth,
+ aw = this[ce].dom.clientWidth;
+
+ if(!this.resizeTabs || count < 1 || !aw){
+ return;
+ }
+
+ var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
+ this.lastTabWidth = each;
+ var lis = this.strip.query('li:not(.x-tab-edge)');
+ for(var i = 0, len = lis.length; i < len; i++) {
+ var li = lis[i],
+ inner = Ext.fly(li).child('.x-tab-strip-inner', true),
+ tw = li.offsetWidth,
+ iw = inner.offsetWidth;
+ inner.style.width = (each - (tw-iw)) + 'px';
+ }
+ },
+
+
+ adjustBodyWidth : function(w){
+ if(this.header){
+ this.header.setWidth(w);
+ }
+ if(this.footer){
+ this.footer.setWidth(w);
+ }
+ return w;
+ },
+
+
+ setActiveTab : function(item){
+ item = this.getComponent(item);
+ if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
+ return;
+ }
+ if(!this.rendered){
+ this.activeTab = item;
+ return;
+ }
+ if(this.activeTab != item){
+ if(this.activeTab){
+ var oldEl = this.getTabEl(this.activeTab);
+ if(oldEl){
+ Ext.fly(oldEl).removeClass('x-tab-strip-active');
+ }
+ }
+ this.activeTab = item;
+ if(item){
+ var el = this.getTabEl(item);
+ Ext.fly(el).addClass('x-tab-strip-active');
+ this.stack.add(item);
+
+ this.layout.setActiveItem(item);
+
+ this.delegateUpdates();
+ if(this.scrolling){
+ this.scrollToTab(item, this.animScroll);
+ }
+ }
+ this.fireEvent('tabchange', this, item);
+ }
+ },
+
+
+ getActiveTab : function(){
+ return this.activeTab || null;
+ },
+
+
+ getItem : function(item){
+ return this.getComponent(item);
+ },
+
+
+ autoScrollTabs : function(){
+ this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
+ var count = this.items.length,
+ ow = this.pos.dom.offsetWidth,
+ tw = this.pos.dom.clientWidth,
+ wrap = this.stripWrap,
+ wd = wrap.dom,
+ cw = wd.offsetWidth,
+ pos = this.getScrollPos(),
+ l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
+
+ if(!this.enableTabScroll || cw < 20){
+ return;
+ }
+ if(count == 0 || l <= tw){
+
+ wd.scrollLeft = 0;
+ wrap.setWidth(tw);
+ if(this.scrolling){
+ this.scrolling = false;
+ this.pos.removeClass('x-tab-scrolling');
+ this.scrollLeft.hide();
+ this.scrollRight.hide();
+
+ if(Ext.isAir || Ext.isWebKit){
+ wd.style.marginLeft = '';
+ wd.style.marginRight = '';
+ }
+ }
+ }else{
+ if(!this.scrolling){
+ this.pos.addClass('x-tab-scrolling');
+
+ if(Ext.isAir || Ext.isWebKit){
+ wd.style.marginLeft = '18px';
+ wd.style.marginRight = '18px';
+ }
+ }
+ tw -= wrap.getMargins('lr');
+ wrap.setWidth(tw > 20 ? tw : 20);
+ if(!this.scrolling){
+ if(!this.scrollLeft){
+ this.createScrollers();
+ }else{
+ this.scrollLeft.show();
+ this.scrollRight.show();
+ }
+ }
+ this.scrolling = true;
+ if(pos > (l-tw)){
+ wd.scrollLeft = l-tw;
+ }else{
+ this.scrollToTab(this.activeTab, false);
+ }
+ this.updateScrollButtons();
+ }
+ },
+
+
+ createScrollers : function(){
+ this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
+ var h = this.stripWrap.dom.offsetHeight;
+
+
+ var sl = this.pos.insertFirst({
+ cls:'x-tab-scroller-left'
+ });
+ sl.setHeight(h);
+ sl.addClassOnOver('x-tab-scroller-left-over');
+ this.leftRepeater = new Ext.util.ClickRepeater(sl, {
+ interval : this.scrollRepeatInterval,
+ handler: this.onScrollLeft,
+ scope: this
+ });
+ this.scrollLeft = sl;
+
+
+ var sr = this.pos.insertFirst({
+ cls:'x-tab-scroller-right'
+ });
+ sr.setHeight(h);
+ sr.addClassOnOver('x-tab-scroller-right-over');
+ this.rightRepeater = new Ext.util.ClickRepeater(sr, {
+ interval : this.scrollRepeatInterval,
+ handler: this.onScrollRight,
+ scope: this
+ });
+ this.scrollRight = sr;
+ },
+
+
+ getScrollWidth : function(){
+ return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
+ },
+
+
+ getScrollPos : function(){
+ return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
+ },
+
+
+ getScrollArea : function(){
+ return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
+ },
+
+
+ getScrollAnim : function(){
+ return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
+ },
+
+
+ getScrollIncrement : function(){
+ return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
+ },
+
+
+
+ scrollToTab : function(item, animate){
+ if(!item){
+ return;
+ }
+ var el = this.getTabEl(item),
+ pos = this.getScrollPos(),
+ area = this.getScrollArea(),
+ left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
+ right = left + el.offsetWidth;
+ if(left < pos){
+ this.scrollTo(left, animate);
+ }else if(right > (pos + area)){
+ this.scrollTo(right - area, animate);
+ }
+ },
+
+
+ scrollTo : function(pos, animate){
+ this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
+ if(!animate){
+ this.updateScrollButtons();
+ }
+ },
+
+ onWheel : function(e){
+ var d = e.getWheelDelta()*this.wheelIncrement*-1;
+ e.stopEvent();
+
+ var pos = this.getScrollPos(),
+ newpos = pos + d,
+ sw = this.getScrollWidth()-this.getScrollArea();
+
+ var s = Math.max(0, Math.min(sw, newpos));
+ if(s != pos){
+ this.scrollTo(s, false);
+ }
+ },
+
+
+ onScrollRight : function(){
+ var sw = this.getScrollWidth()-this.getScrollArea(),
+ pos = this.getScrollPos(),
+ s = Math.min(sw, pos + this.getScrollIncrement());
+ if(s != pos){
+ this.scrollTo(s, this.animScroll);
+ }
+ },
+
+
+ onScrollLeft : function(){
+ var pos = this.getScrollPos(),
+ s = Math.max(0, pos - this.getScrollIncrement());
+ if(s != pos){
+ this.scrollTo(s, this.animScroll);
+ }
+ },
+
+
+ updateScrollButtons : function(){
+ var pos = this.getScrollPos();
+ this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
+ this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
+ },
+
+
+ beforeDestroy : function() {
+ Ext.destroy(this.leftRepeater, this.rightRepeater);
+ this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
+ this.activeTab = null;
+ Ext.TabPanel.superclass.beforeDestroy.apply(this);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+});
+Ext.reg('tabpanel', Ext.TabPanel);
+
+
+Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
+
+
+Ext.TabPanel.AccessStack = function(){
+ var items = [];
+ return {
+ add : function(item){
+ items.push(item);
+ if(items.length > 10){
+ items.shift();
+ }
+ },
+
+ remove : function(item){
+ var s = [];
+ for(var i = 0, len = items.length; i < len; i++) {
+ if(items[i] != item){
+ s.push(items[i]);
+ }
+ }
+ items = s;
+ },
+
+ next : function(){
+ return items.pop();
+ }
+ };
+};
+
+Ext.Button = Ext.extend(Ext.BoxComponent, {
+
+ hidden : false,
+
+ disabled : false,
+
+ pressed : false,
+
+
+
+
+
+
+ enableToggle : false,
+
+
+
+ menuAlign : 'tl-bl?',
+
+
+
+
+ type : 'button',
+
+
+ menuClassTarget : 'tr:nth(2)',
+
+
+ clickEvent : 'click',
+
+
+ handleMouseEvents : true,
+
+
+ tooltipType : 'qtip',
+
+
+ buttonSelector : 'button:first-child',
+
+
+ scale : 'small',
+
+
+
+
+ iconAlign : 'left',
+
+
+ arrowAlign : 'right',
+
+
+
+
+
+
+ initComponent : function(){
+ if(this.menu){
+
+
+ if (Ext.isArray(this.menu)){
+ this.menu = { items: this.menu };
+ }
+
+
+
+ if (Ext.isObject(this.menu)){
+ this.menu.ownerCt = this;
+ }
+
+ this.menu = Ext.menu.MenuMgr.get(this.menu);
+ this.menu.ownerCt = undefined;
+ }
+
+ Ext.Button.superclass.initComponent.call(this);
+
+ this.addEvents(
+
+ 'click',
+
+ 'toggle',
+
+ 'mouseover',
+
+ 'mouseout',
+
+ 'menushow',
+
+ 'menuhide',
+
+ 'menutriggerover',
+
+ 'menutriggerout'
+ );
+
+ if(Ext.isString(this.toggleGroup)){
+ this.enableToggle = true;
+ }
+ },
+
+
+ getTemplateArgs : function(){
+ return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
+ },
+
+
+ setButtonClass : function(){
+ if(this.useSetClass){
+ if(!Ext.isEmpty(this.oldCls)){
+ this.el.removeClass([this.oldCls, 'x-btn-pressed']);
+ }
+ this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
+ this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
+ }
+ },
+
+
+ getMenuClass : function(){
+ return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
+ },
+
+
+ onRender : function(ct, position){
+ if(!this.template){
+ if(!Ext.Button.buttonTemplate){
+
+ Ext.Button.buttonTemplate = new Ext.Template(
+ '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
+ '<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>',
+ '<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{2} x-unselectable" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
+ '<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',
+ '</tbody></table>');
+ Ext.Button.buttonTemplate.compile();
+ }
+ this.template = Ext.Button.buttonTemplate;
+ }
+
+ var btn, targs = this.getTemplateArgs();
+
+ if(position){
+ btn = this.template.insertBefore(position, targs, true);
+ }else{
+ btn = this.template.append(ct, targs, true);
+ }
+
+ this.btnEl = btn.child(this.buttonSelector);
+ this.mon(this.btnEl, {
+ scope: this,
+ focus: this.onFocus,
+ blur: this.onBlur
+ });
+
+ this.initButtonEl(btn, this.btnEl);
+
+ Ext.ButtonToggleMgr.register(this);
+ },
+
+
+ initButtonEl : function(btn, btnEl){
+ this.el = btn;
+ this.setIcon(this.icon);
+ this.setText(this.text);
+ this.setIconClass(this.iconCls);
+ if(Ext.isDefined(this.tabIndex)){
+ btnEl.dom.tabIndex = this.tabIndex;
+ }
+ if(this.tooltip){
+ this.setTooltip(this.tooltip, true);
+ }
+
+ if(this.handleMouseEvents){
+ this.mon(btn, {
+ scope: this,
+ mouseover: this.onMouseOver,
+ mousedown: this.onMouseDown
+ });
+
+
+
+ }
+
+ if(this.menu){
+ this.mon(this.menu, {
+ scope: this,
+ show: this.onMenuShow,
+ hide: this.onMenuHide
+ });
+ }
+
+ if(this.repeat){
+ var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
+ this.mon(repeater, 'click', this.onRepeatClick, this);
+ }else{
+ this.mon(btn, this.clickEvent, this.onClick, this);
+ }
+ },
+
+
+ afterRender : function(){
+ Ext.Button.superclass.afterRender.call(this);
+ this.useSetClass = true;
+ this.setButtonClass();
+ this.doc = Ext.getDoc();
+ this.doAutoWidth();
+ },
+
+
+ setIconClass : function(cls){
+ this.iconCls = cls;
+ if(this.el){
+ this.btnEl.dom.className = '';
+ this.btnEl.addClass(['x-btn-text', cls || '']);
+ this.setButtonClass();
+ }
+ return this;
+ },
+
+
+ setTooltip : function(tooltip, initial){
+ if(this.rendered){
+ if(!initial){
+ this.clearTip();
+ }
+ if(Ext.isObject(tooltip)){
+ Ext.QuickTips.register(Ext.apply({
+ target: this.btnEl.id
+ }, tooltip));
+ this.tooltip = tooltip;
+ }else{
+ this.btnEl.dom[this.tooltipType] = tooltip;
+ }
+ }else{
+ this.tooltip = tooltip;
+ }
+ return this;
+ },
+
+
+ clearTip : function(){
+ if(Ext.isObject(this.tooltip)){
+ Ext.QuickTips.unregister(this.btnEl);
+ }
+ },
+
+
+ beforeDestroy : function(){
+ if(this.rendered){
+ this.clearTip();
+ }
+ if(this.menu && this.destroyMenu !== false) {
+ Ext.destroy(this.btnEl, this.menu);
+ }
+ Ext.destroy(this.repeater);
+ },
+
+
+ onDestroy : function(){
+ if(this.rendered){
+ this.doc.un('mouseover', this.monitorMouseOver, this);
+ this.doc.un('mouseup', this.onMouseUp, this);
+ delete this.doc;
+ delete this.btnEl;
+ Ext.ButtonToggleMgr.unregister(this);
+ }
+ Ext.Button.superclass.onDestroy.call(this);
+ },
+
+
+ doAutoWidth : function(){
+ if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
+ this.el.setWidth('auto');
+ if(Ext.isIE7 && Ext.isStrict){
+ var ib = this.btnEl;
+ 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.el.getWidth() < this.minWidth){
+ this.el.setWidth(this.minWidth);
+ }
+ }
+ }
+ },
+
+
+ setHandler : function(handler, scope){
+ this.handler = handler;
+ this.scope = scope;
+ return this;
+ },
+
+
+ setText : function(text){
+ this.text = text;
+ if(this.el){
+ this.btnEl.update(text || '&#160;');
+ this.setButtonClass();
+ }
+ this.doAutoWidth();
+ return this;
+ },
+
+
+ setIcon : function(icon){
+ this.icon = icon;
+ if(this.el){
+ this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
+ this.setButtonClass();
+ }
+ return this;
+ },
+
+
+ getText : function(){
+ return this.text;
+ },
+
+
+ toggle : function(state, suppressEvent){
+ state = state === undefined ? !this.pressed : !!state;
+ if(state != this.pressed){
+ if(this.rendered){
+ this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
+ }
+ this.pressed = state;
+ if(!suppressEvent){
+ this.fireEvent('toggle', this, state);
+ if(this.toggleHandler){
+ this.toggleHandler.call(this.scope || this, this, state);
+ }
+ }
+ }
+ return this;
+ },
+
+
+ onDisable : function(){
+ this.onDisableChange(true);
+ },
+
+
+ onEnable : function(){
+ this.onDisableChange(false);
+ },
+
+ onDisableChange : function(disabled){
+ if(this.el){
+ if(!Ext.isIE6 || !this.text){
+ this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
+ }
+ this.el.dom.disabled = disabled;
+ }
+ this.disabled = disabled;
+ },
+
+
+ showMenu : function(){
+ if(this.rendered && this.menu){
+ if(this.tooltip){
+ Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
+ }
+ if(this.menu.isVisible()){
+ this.menu.hide();
+ }
+ this.menu.ownerCt = this;
+ this.menu.show(this.el, this.menuAlign);
+ }
+ return this;
+ },
+
+
+ hideMenu : function(){
+ if(this.hasVisibleMenu()){
+ this.menu.hide();
+ }
+ return this;
+ },
+
+
+ hasVisibleMenu : function(){
+ return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
+ },
+
+
+ onRepeatClick : function(repeat, e){
+ this.onClick(e);
+ },
+
+
+ onClick : function(e){
+ if(e){
+ e.preventDefault();
+ }
+ if(e.button !== 0){
+ return;
+ }
+ if(!this.disabled){
+ this.doToggle();
+ if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
+ this.showMenu();
+ }
+ this.fireEvent('click', this, e);
+ if(this.handler){
+
+ this.handler.call(this.scope || this, this, e);
+ }
+ }
+ },
+
+
+ doToggle: function(){
+ if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
+ this.toggle();
+ }
+ },
+
+
+ isMenuTriggerOver : function(e, internal){
+ return this.menu && !internal;
+ },
+
+
+ isMenuTriggerOut : function(e, internal){
+ return this.menu && !internal;
+ },
+
+
+ onMouseOver : function(e){
+ if(!this.disabled){
+ var internal = e.within(this.el, true);
+ if(!internal){
+ this.el.addClass('x-btn-over');
+ if(!this.monitoringMouseOver){
+ this.doc.on('mouseover', this.monitorMouseOver, this);
+ this.monitoringMouseOver = true;
+ }
+ this.fireEvent('mouseover', this, e);
+ }
+ if(this.isMenuTriggerOver(e, internal)){
+ this.fireEvent('menutriggerover', this, this.menu, e);
+ }
+ }
+ },
+
+
+ monitorMouseOver : function(e){
+ if(e.target != this.el.dom && !e.within(this.el)){
+ if(this.monitoringMouseOver){
+ this.doc.un('mouseover', this.monitorMouseOver, this);
+ this.monitoringMouseOver = false;
+ }
+ this.onMouseOut(e);
+ }
+ },
+
+
+ onMouseOut : function(e){
+ var internal = e.within(this.el) && e.target != this.el.dom;
+ this.el.removeClass('x-btn-over');
+ this.fireEvent('mouseout', this, e);
+ if(this.isMenuTriggerOut(e, internal)){
+ this.fireEvent('menutriggerout', this, this.menu, e);
+ }
+ },
+
+ focus : function() {
+ this.btnEl.focus();
+ },
+
+ blur : function() {
+ this.btnEl.blur();
+ },
+
+
+ onFocus : function(e){
+ if(!this.disabled){
+ this.el.addClass('x-btn-focus');
+ }
+ },
+
+ onBlur : function(e){
+ this.el.removeClass('x-btn-focus');
+ },
+
+
+ getClickEl : function(e, isUp){
+ return this.el;
+ },
+
+
+ onMouseDown : function(e){
+ if(!this.disabled && e.button === 0){
+ this.getClickEl(e).addClass('x-btn-click');
+ this.doc.on('mouseup', this.onMouseUp, this);
+ }
+ },
+
+ onMouseUp : function(e){
+ if(e.button === 0){
+ this.getClickEl(e, true).removeClass('x-btn-click');
+ this.doc.un('mouseup', this.onMouseUp, this);
+ }
+ },
+
+ onMenuShow : function(e){
+ if(this.menu.ownerCt == this){
+ this.menu.ownerCt = this;
+ this.ignoreNextClick = 0;
+ this.el.addClass('x-btn-menu-active');
+ this.fireEvent('menushow', this, this.menu);
+ }
+ },
+
+ onMenuHide : function(e){
+ if(this.menu.ownerCt == this){
+ this.el.removeClass('x-btn-menu-active');
+ this.ignoreNextClick = this.restoreClick.defer(250, this);
+ this.fireEvent('menuhide', this, this.menu);
+ delete this.menu.ownerCt;
+ }
+ },
+
+
+ restoreClick : function(){
+ this.ignoreNextClick = 0;
+ }
+
+
+
+
+
+
+
+});
+Ext.reg('button', Ext.Button);
+
+
+Ext.ButtonToggleMgr = function(){
+ var groups = {};
+
+ function toggleGroup(btn, state){
+ if(state){
+ var g = groups[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 = groups[btn.toggleGroup];
+ if(!g){
+ g = groups[btn.toggleGroup] = [];
+ }
+ g.push(btn);
+ btn.on('toggle', toggleGroup);
+ },
+
+ unregister : function(btn){
+ if(!btn.toggleGroup){
+ return;
+ }
+ var g = groups[btn.toggleGroup];
+ if(g){
+ g.remove(btn);
+ btn.un('toggle', toggleGroup);
+ }
+ },
+
+
+ getPressed : function(group){
+ var g = groups[group];
+ if(g){
+ for(var i = 0, len = g.length; i < len; i++){
+ if(g[i].pressed === true){
+ return g[i];
+ }
+ }
+ }
+ return null;
+ }
+ };
+}();
+
+Ext.SplitButton = Ext.extend(Ext.Button, {
+
+ arrowSelector : 'em',
+ split: true,
+
+
+ initComponent : function(){
+ Ext.SplitButton.superclass.initComponent.call(this);
+
+ this.addEvents("arrowclick");
+ },
+
+
+ onRender : function(){
+ Ext.SplitButton.superclass.onRender.apply(this, arguments);
+ if(this.arrowTooltip){
+ this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
+ }
+ },
+
+
+ setArrowHandler : function(handler, scope){
+ this.arrowHandler = handler;
+ this.scope = scope;
+ },
+
+ getMenuClass : function(){
+ return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
+ },
+
+ isClickOnArrow : function(e){
+ if (this.arrowAlign != 'bottom') {
+ var visBtn = this.el.child('em.x-btn-split');
+ var right = visBtn.getRegion().right - visBtn.getPadding('r');
+ return e.getPageX() > right;
+ } else {
+ return e.getPageY() > this.btnEl.getRegion().bottom;
+ }
+ },
+
+
+ onClick : function(e, t){
+ e.preventDefault();
+ if(!this.disabled){
+ if(this.isClickOnArrow(e)){
+ if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
+ this.showMenu();
+ }
+ this.fireEvent("arrowclick", this, e);
+ if(this.arrowHandler){
+ this.arrowHandler.call(this.scope || this, this, e);
+ }
+ }else{
+ this.doToggle();
+ this.fireEvent("click", this, e);
+ if(this.handler){
+ this.handler.call(this.scope || this, this, e);
+ }
+ }
+ }
+ },
+
+
+ isMenuTriggerOver : function(e){
+ return this.menu && e.target.tagName == this.arrowSelector;
+ },
+
+
+ isMenuTriggerOut : function(e, internal){
+ return this.menu && e.target.tagName != this.arrowSelector;
+ }
+});
+
+Ext.reg('splitbutton', Ext.SplitButton);
+Ext.CycleButton = Ext.extend(Ext.SplitButton, {
+
+
+
+
+
+
+
+
+ getItemText : function(item){
+ if(item && this.showText === true){
+ var text = '';
+ if(this.prependText){
+ text += this.prependText;
+ }
+ text += item.text;
+ return text;
+ }
+ return undefined;
+ },
+
+
+ setActiveItem : function(item, suppressEvent){
+ if(!Ext.isObject(item)){
+ item = this.menu.getComponent(item);
+ }
+ if(item){
+ if(!this.rendered){
+ this.text = this.getItemText(item);
+ this.iconCls = item.iconCls;
+ }else{
+ var t = this.getItemText(item);
+ if(t){
+ this.setText(t);
+ }
+ this.setIconClass(item.iconCls);
+ }
+ this.activeItem = item;
+ if(!item.checked){
+ item.setChecked(true, suppressEvent);
+ }
+ if(this.forceIcon){
+ this.setIconClass(this.forceIcon);
+ }
+ if(!suppressEvent){
+ this.fireEvent('change', this, item);
+ }
+ }
+ },
+
+
+ getActiveItem : function(){
+ return this.activeItem;
+ },
+
+
+ initComponent : function(){
+ this.addEvents(
+
+ "change"
+ );
+
+ if(this.changeHandler){
+ this.on('change', this.changeHandler, this.scope||this);
+ delete this.changeHandler;
+ }
+
+ this.itemCount = this.items.length;
+
+ this.menu = {cls:'x-cycle-menu', items:[]};
+ var checked = 0;
+ Ext.each(this.items, function(item, i){
+ Ext.apply(item, {
+ group: item.group || this.id,
+ itemIndex: i,
+ checkHandler: this.checkHandler,
+ scope: this,
+ checked: item.checked || false
+ });
+ this.menu.items.push(item);
+ if(item.checked){
+ checked = i;
+ }
+ }, this);
+ Ext.CycleButton.superclass.initComponent.call(this);
+ this.on('click', this.toggleSelected, this);
+ this.setActiveItem(checked, true);
+ },
+
+
+ checkHandler : function(item, pressed){
+ if(pressed){
+ this.setActiveItem(item);
+ }
+ },
+
+
+ toggleSelected : function(){
+ var m = this.menu;
+ m.render();
+
+ if(!m.hasLayout){
+ m.doLayout();
+ }
+
+ var nextIdx, checkItem;
+ for (var i = 1; i < this.itemCount; i++) {
+ nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
+
+ checkItem = m.items.itemAt(nextIdx);
+
+ if (!checkItem.disabled) {
+ checkItem.setChecked(true);
+ break;
+ }
+ }
+ }
+});
+Ext.reg('cycle', Ext.CycleButton);
+Ext.Toolbar = function(config){
+ if(Ext.isArray(config)){
+ config = {items: config, layout: 'toolbar'};
+ } else {
+ config = Ext.apply({
+ layout: 'toolbar'
+ }, config);
+ if(config.buttons) {
+ config.items = config.buttons;
+ }
+ }
+ Ext.Toolbar.superclass.constructor.call(this, config);
+};
+
+(function(){
+
+var T = Ext.Toolbar;
+
+Ext.extend(T, Ext.Container, {
+
+ defaultType: 'button',
+
+
+
+ enableOverflow : false,
+
+
+
+
+ trackMenus : true,
+ internalDefaults: {removeMode: 'container', hideParent: true},
+ toolbarCls: 'x-toolbar',
+
+ initComponent : function(){
+ T.superclass.initComponent.call(this);
+
+
+ this.addEvents('overflowchange');
+ },
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ if(!this.autoCreate){
+ this.autoCreate = {
+ cls: this.toolbarCls + ' x-small-editor'
+ };
+ }
+ this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
+ Ext.Toolbar.superclass.onRender.apply(this, arguments);
+ }
+ },
+
+
+
+
+ lookupComponent : function(c){
+ if(Ext.isString(c)){
+ if(c == '-'){
+ c = new T.Separator();
+ }else if(c == ' '){
+ c = new T.Spacer();
+ }else if(c == '->'){
+ c = new T.Fill();
+ }else{
+ c = new T.TextItem(c);
+ }
+ this.applyDefaults(c);
+ }else{
+ if(c.isFormField || c.render){
+ c = this.createComponent(c);
+ }else if(c.tag){
+ c = new T.Item({autoEl: c});
+ }else if(c.tagName){
+ c = new T.Item({el:c});
+ }else if(Ext.isObject(c)){
+ c = c.xtype ? this.createComponent(c) : this.constructButton(c);
+ }
+ }
+ return c;
+ },
+
+
+ applyDefaults : function(c){
+ if(!Ext.isString(c)){
+ c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
+ var d = this.internalDefaults;
+ if(c.events){
+ Ext.applyIf(c.initialConfig, d);
+ Ext.apply(c, d);
+ }else{
+ Ext.applyIf(c, d);
+ }
+ }
+ return c;
+ },
+
+
+ addSeparator : function(){
+ return this.add(new T.Separator());
+ },
+
+
+ addSpacer : function(){
+ return this.add(new T.Spacer());
+ },
+
+
+ addFill : function(){
+ this.add(new T.Fill());
+ },
+
+
+ addElement : function(el){
+ return this.addItem(new T.Item({el:el}));
+ },
+
+
+ addItem : function(item){
+ return this.add.apply(this, arguments);
+ },
+
+
+ addButton : function(config){
+ if(Ext.isArray(config)){
+ var buttons = [];
+ for(var i = 0, len = config.length; i < len; i++) {
+ buttons.push(this.addButton(config[i]));
+ }
+ return buttons;
+ }
+ return this.add(this.constructButton(config));
+ },
+
+
+ addText : function(text){
+ return this.addItem(new T.TextItem(text));
+ },
+
+
+ addDom : function(config){
+ return this.add(new T.Item({autoEl: config}));
+ },
+
+
+ addField : function(field){
+ return this.add(field);
+ },
+
+
+ insertButton : function(index, item){
+ if(Ext.isArray(item)){
+ var buttons = [];
+ for(var i = 0, len = item.length; i < len; i++) {
+ buttons.push(this.insertButton(index + i, item[i]));
+ }
+ return buttons;
+ }
+ return Ext.Toolbar.superclass.insert.call(this, index, item);
+ },
+
+
+ trackMenu : function(item, remove){
+ if(this.trackMenus && item.menu){
+ var method = remove ? 'mun' : 'mon';
+ this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
+ this[method](item, 'menushow', this.onButtonMenuShow, this);
+ this[method](item, 'menuhide', this.onButtonMenuHide, this);
+ }
+ },
+
+
+ constructButton : function(item){
+ var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
+ return b;
+ },
+
+
+ onAdd : function(c){
+ Ext.Toolbar.superclass.onAdd.call(this);
+ this.trackMenu(c);
+ if(this.disabled){
+ c.disable();
+ }
+ },
+
+
+ onRemove : function(c){
+ Ext.Toolbar.superclass.onRemove.call(this);
+ if (c == this.activeMenuBtn) {
+ delete this.activeMenuBtn;
+ }
+ this.trackMenu(c, true);
+ },
+
+
+ onDisable : function(){
+ this.items.each(function(item){
+ if(item.disable){
+ item.disable();
+ }
+ });
+ },
+
+
+ onEnable : function(){
+ this.items.each(function(item){
+ if(item.enable){
+ item.enable();
+ }
+ });
+ },
+
+
+ onButtonTriggerOver : function(btn){
+ if(this.activeMenuBtn && this.activeMenuBtn != btn){
+ this.activeMenuBtn.hideMenu();
+ btn.showMenu();
+ this.activeMenuBtn = btn;
+ }
+ },
+
+
+ onButtonMenuShow : function(btn){
+ this.activeMenuBtn = btn;
+ },
+
+
+ onButtonMenuHide : function(btn){
+ delete this.activeMenuBtn;
+ }
+});
+Ext.reg('toolbar', Ext.Toolbar);
+
+
+T.Item = Ext.extend(Ext.BoxComponent, {
+ hideParent: true,
+ enable:Ext.emptyFn,
+ disable:Ext.emptyFn,
+ focus:Ext.emptyFn
+
+});
+Ext.reg('tbitem', T.Item);
+
+
+T.Separator = Ext.extend(T.Item, {
+ onRender : function(ct, position){
+ this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
+ }
+});
+Ext.reg('tbseparator', T.Separator);
+
+
+T.Spacer = Ext.extend(T.Item, {
+
+
+ onRender : function(ct, position){
+ this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
+ }
+});
+Ext.reg('tbspacer', T.Spacer);
+
+
+T.Fill = Ext.extend(T.Item, {
+
+ render : Ext.emptyFn,
+ isFill : true
+});
+Ext.reg('tbfill', T.Fill);
+
+
+T.TextItem = Ext.extend(T.Item, {
+
+
+ constructor: function(config){
+ T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
+ },
+
+
+ onRender : function(ct, position) {
+ this.autoEl = {cls: 'xtb-text', html: this.text || ''};
+ T.TextItem.superclass.onRender.call(this, ct, position);
+ },
+
+
+ setText : function(t) {
+ if(this.rendered){
+ this.el.update(t);
+ }else{
+ this.text = t;
+ }
+ }
+});
+Ext.reg('tbtext', T.TextItem);
+
+
+T.Button = Ext.extend(Ext.Button, {});
+T.SplitButton = Ext.extend(Ext.SplitButton, {});
+Ext.reg('tbbutton', T.Button);
+Ext.reg('tbsplit', T.SplitButton);
+
+})();
+
+Ext.ButtonGroup = Ext.extend(Ext.Panel, {
+
+
+ baseCls: 'x-btn-group',
+
+ layout:'table',
+ defaultType: 'button',
+
+ frame: true,
+ internalDefaults: {removeMode: 'container', hideParent: true},
+
+ initComponent : function(){
+ this.layoutConfig = this.layoutConfig || {};
+ Ext.applyIf(this.layoutConfig, {
+ columns : this.columns
+ });
+ if(!this.title){
+ this.addClass('x-btn-group-notitle');
+ }
+ this.on('afterlayout', this.onAfterLayout, this);
+ Ext.ButtonGroup.superclass.initComponent.call(this);
+ },
+
+ applyDefaults : function(c){
+ c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
+ var d = this.internalDefaults;
+ if(c.events){
+ Ext.applyIf(c.initialConfig, d);
+ Ext.apply(c, d);
+ }else{
+ Ext.applyIf(c, d);
+ }
+ return c;
+ },
+
+ onAfterLayout : function(){
+ var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
+ this.body.setWidth(bodyWidth);
+ this.el.setWidth(bodyWidth + this.getFrameWidth());
+ }
+
+});
+
+Ext.reg('buttongroup', Ext.ButtonGroup);
+
+(function() {
+
+var T = Ext.Toolbar;
+
+Ext.PagingToolbar = Ext.extend(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',
+
+
+
+
+
+
+
+ initComponent : function(){
+ var pagingItems = [this.first = new T.Button({
+ tooltip: this.firstText,
+ overflowText: this.firstText,
+ iconCls: 'x-tbar-page-first',
+ disabled: true,
+ handler: this.moveFirst,
+ scope: this
+ }), this.prev = new T.Button({
+ tooltip: this.prevText,
+ overflowText: this.prevText,
+ iconCls: 'x-tbar-page-prev',
+ disabled: true,
+ handler: this.movePrevious,
+ scope: this
+ }), '-', this.beforePageText,
+ this.inputItem = new Ext.form.NumberField({
+ cls: 'x-tbar-page-number',
+ allowDecimals: false,
+ allowNegative: false,
+ enableKeyEvents: true,
+ selectOnFocus: true,
+ submitValue: false,
+ listeners: {
+ scope: this,
+ keydown: this.onPagingKeyDown,
+ blur: this.onPagingBlur
+ }
+ }), this.afterTextItem = new T.TextItem({
+ text: String.format(this.afterPageText, 1)
+ }), '-', this.next = new T.Button({
+ tooltip: this.nextText,
+ overflowText: this.nextText,
+ iconCls: 'x-tbar-page-next',
+ disabled: true,
+ handler: this.moveNext,
+ scope: this
+ }), this.last = new T.Button({
+ tooltip: this.lastText,
+ overflowText: this.lastText,
+ iconCls: 'x-tbar-page-last',
+ disabled: true,
+ handler: this.moveLast,
+ scope: this
+ }), '-', this.refresh = new T.Button({
+ tooltip: this.refreshText,
+ overflowText: this.refreshText,
+ iconCls: 'x-tbar-loading',
+ handler: this.doRefresh,
+ scope: this
+ })];
+
+
+ var userItems = this.items || this.buttons || [];
+ if (this.prependButtons) {
+ this.items = userItems.concat(pagingItems);
+ }else{
+ this.items = pagingItems.concat(userItems);
+ }
+ delete this.buttons;
+ if(this.displayInfo){
+ this.items.push('->');
+ this.items.push(this.displayItem = new T.TextItem({}));
+ }
+ Ext.PagingToolbar.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'change',
+
+ 'beforechange'
+ );
+ this.on('afterlayout', this.onFirstLayout, this, {single: true});
+ this.cursor = 0;
+ this.bindStore(this.store, true);
+ },
+
+
+ onFirstLayout : function(){
+ if(this.dsLoaded){
+ this.onLoad.apply(this, this.dsLoaded);
+ }
+ },
+
+
+ updateInfo : function(){
+ if(this.displayItem){
+ var count = this.store.getCount();
+ var msg = count == 0 ?
+ this.emptyMsg :
+ String.format(
+ this.displayMsg,
+ this.cursor+1, this.cursor+count, this.store.getTotalCount()
+ );
+ this.displayItem.setText(msg);
+ }
+ },
+
+
+ onLoad : function(store, r, o){
+ if(!this.rendered){
+ this.dsLoaded = [store, r, o];
+ return;
+ }
+ var p = this.getParams();
+ this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
+ var d = this.getPageData(), ap = d.activePage, ps = d.pages;
+
+ this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
+ this.inputItem.setValue(ap);
+ this.first.setDisabled(ap == 1);
+ this.prev.setDisabled(ap == 1);
+ this.next.setDisabled(ap == ps);
+ this.last.setDisabled(ap == ps);
+ this.refresh.enable();
+ this.updateInfo();
+ this.fireEvent('change', this, d);
+ },
+
+
+ getPageData : function(){
+ var total = this.store.getTotalCount();
+ return {
+ total : total,
+ activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
+ pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
+ };
+ },
+
+
+ changePage : function(page){
+ this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
+ },
+
+
+ onLoadError : function(){
+ if(!this.rendered){
+ return;
+ }
+ this.refresh.enable();
+ },
+
+
+ readPage : function(d){
+ var v = this.inputItem.getValue(), pageNum;
+ if (!v || isNaN(pageNum = parseInt(v, 10))) {
+ this.inputItem.setValue(d.activePage);
+ return false;
+ }
+ return pageNum;
+ },
+
+ onPagingFocus : function(){
+ this.inputItem.select();
+ },
+
+
+ onPagingBlur : function(e){
+ this.inputItem.setValue(this.getPageData().activePage);
+ },
+
+
+ onPagingKeyDown : function(field, e){
+ var k = e.getKey(), d = this.getPageData(), pageNum;
+ if (k == e.RETURN) {
+ e.stopEvent();
+ pageNum = this.readPage(d);
+ if(pageNum !== false){
+ pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
+ this.doLoad(pageNum * this.pageSize);
+ }
+ }else if (k == e.HOME || k == e.END){
+ e.stopEvent();
+ pageNum = k == e.HOME ? 1 : d.pages;
+ field.setValue(pageNum);
+ }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
+ e.stopEvent();
+ if((pageNum = this.readPage(d))){
+ var increment = e.shiftKey ? 10 : 1;
+ if(k == e.DOWN || k == e.PAGEDOWN){
+ increment *= -1;
+ }
+ pageNum += increment;
+ if(pageNum >= 1 & pageNum <= d.pages){
+ field.setValue(pageNum);
+ }
+ }
+ }
+ },
+
+
+ getParams : function(){
+
+ return this.paramNames || this.store.paramNames;
+ },
+
+
+ beforeLoad : function(){
+ if(this.rendered && this.refresh){
+ this.refresh.disable();
+ }
+ },
+
+
+ doLoad : function(start){
+ var o = {}, pn = this.getParams();
+ o[pn.start] = start;
+ o[pn.limit] = this.pageSize;
+ if(this.fireEvent('beforechange', this, o) !== false){
+ this.store.load({params:o});
+ }
+ },
+
+
+ moveFirst : function(){
+ this.doLoad(0);
+ },
+
+
+ movePrevious : function(){
+ this.doLoad(Math.max(0, this.cursor-this.pageSize));
+ },
+
+
+ moveNext : function(){
+ this.doLoad(this.cursor+this.pageSize);
+ },
+
+
+ moveLast : function(){
+ var total = this.store.getTotalCount(),
+ extra = total % this.pageSize;
+
+ this.doLoad(extra ? (total - extra) : total - this.pageSize);
+ },
+
+
+ doRefresh : function(){
+ this.doLoad(this.cursor);
+ },
+
+
+ bindStore : function(store, initial){
+ var doLoad;
+ if(!initial && this.store){
+ if(store !== this.store && this.store.autoDestroy){
+ this.store.destroy();
+ }else{
+ this.store.un('beforeload', this.beforeLoad, this);
+ this.store.un('load', this.onLoad, this);
+ this.store.un('exception', this.onLoadError, this);
+ }
+ if(!store){
+ this.store = null;
+ }
+ }
+ if(store){
+ store = Ext.StoreMgr.lookup(store);
+ store.on({
+ scope: this,
+ beforeload: this.beforeLoad,
+ load: this.onLoad,
+ exception: this.onLoadError
+ });
+ doLoad = true;
+ }
+ this.store = store;
+ if(doLoad){
+ this.onLoad(store, null, {});
+ }
+ },
+
+
+ unbind : function(store){
+ this.bindStore(null);
+ },
+
+
+ bind : function(store){
+ this.bindStore(store);
+ },
+
+
+ onDestroy : function(){
+ this.bindStore(null);
+ Ext.PagingToolbar.superclass.onDestroy.call(this);
+ }
+});
+
+})();
+Ext.reg('paging', Ext.PagingToolbar);
+Ext.History = (function () {
+ var iframe, hiddenField;
+ var ready = false;
+ var currentToken;
+
+ function getHash() {
+ var href = location.href, i = href.indexOf("#"),
+ hash = i >= 0 ? href.substr(i + 1) : null;
+
+ if (Ext.isGecko) {
+ hash = decodeURIComponent(hash);
+ }
+ return hash;
+ }
+
+ function doSave() {
+ hiddenField.value = currentToken;
+ }
+
+ function handleStateChange(token) {
+ currentToken = token;
+ Ext.History.fireEvent('change', token);
+ }
+
+ function updateIFrame (token) {
+ var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
+ try {
+ var doc = iframe.contentWindow.document;
+ doc.open();
+ doc.write(html);
+ doc.close();
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function checkIFrame() {
+ if (!iframe.contentWindow || !iframe.contentWindow.document) {
+ setTimeout(checkIFrame, 10);
+ return;
+ }
+
+ var doc = iframe.contentWindow.document;
+ var elem = doc.getElementById("state");
+ var token = elem ? elem.innerText : null;
+
+ var hash = getHash();
+
+ setInterval(function () {
+
+ doc = iframe.contentWindow.document;
+ elem = doc.getElementById("state");
+
+ var newtoken = elem ? elem.innerText : null;
+
+ var newHash = getHash();
+
+ if (newtoken !== token) {
+ token = newtoken;
+ handleStateChange(token);
+ location.hash = token;
+ hash = token;
+ doSave();
+ } else if (newHash !== hash) {
+ hash = newHash;
+ updateIFrame(newHash);
+ }
+
+ }, 50);
+
+ ready = true;
+
+ Ext.History.fireEvent('ready', Ext.History);
+ }
+
+ function startUp() {
+ currentToken = hiddenField.value ? hiddenField.value : getHash();
+
+ if (Ext.isIE) {
+ checkIFrame();
+ } else {
+ var hash = getHash();
+ setInterval(function () {
+ var newHash = getHash();
+ if (newHash !== hash) {
+ hash = newHash;
+ handleStateChange(hash);
+ doSave();
+ }
+ }, 50);
+ ready = true;
+ Ext.History.fireEvent('ready', Ext.History);
+ }
+ }
+
+ return {
+
+ fieldId: 'x-history-field',
+
+ iframeId: 'x-history-frame',
+
+ events:{},
+
+
+ init: function (onReady, scope) {
+ if(ready) {
+ Ext.callback(onReady, scope, [this]);
+ return;
+ }
+ if(!Ext.isReady){
+ Ext.onReady(function(){
+ Ext.History.init(onReady, scope);
+ });
+ return;
+ }
+ hiddenField = Ext.getDom(Ext.History.fieldId);
+ if (Ext.isIE) {
+ iframe = Ext.getDom(Ext.History.iframeId);
+ }
+ this.addEvents(
+
+ 'ready',
+
+ 'change'
+ );
+ if(onReady){
+ this.on('ready', onReady, scope, {single:true});
+ }
+ startUp();
+ },
+
+
+ add: function (token, preventDup) {
+ if(preventDup !== false){
+ if(this.getToken() == token){
+ return true;
+ }
+ }
+ if (Ext.isIE) {
+ return updateIFrame(token);
+ } else {
+ location.hash = token;
+ return true;
+ }
+ },
+
+
+ back: function(){
+ history.go(-1);
+ },
+
+
+ forward: function(){
+ history.go(1);
+ },
+
+
+ getToken: function() {
+ return ready ? currentToken : getHash();
+ }
+ };
+})();
+Ext.apply(Ext.History, new Ext.util.Observable());
+Ext.Tip = Ext.extend(Ext.Panel, {
+
+
+
+ minWidth : 40,
+
+ maxWidth : 300,
+
+ shadow : "sides",
+
+ defaultAlign : "tl-bl?",
+ autoRender: true,
+ quickShowInterval : 250,
+
+
+ frame:true,
+ hidden:true,
+ baseCls: 'x-tip',
+ floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
+ autoHeight:true,
+
+ closeAction: 'hide',
+
+
+ initComponent : function(){
+ Ext.Tip.superclass.initComponent.call(this);
+ if(this.closable && !this.title){
+ this.elements += ',header';
+ }
+ },
+
+
+ afterRender : function(){
+ Ext.Tip.superclass.afterRender.call(this);
+ if(this.closable){
+ this.addTool({
+ id: 'close',
+ handler: this[this.closeAction],
+ scope: this
+ });
+ }
+ },
+
+
+ showAt : function(xy){
+ Ext.Tip.superclass.show.call(this);
+ if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
+ this.doAutoWidth();
+ }
+ if(this.constrainPosition){
+ xy = this.el.adjustForConstraints(xy);
+ }
+ this.setPagePosition(xy[0], xy[1]);
+ },
+
+
+ doAutoWidth : function(adjust){
+ adjust = adjust || 0;
+ var bw = this.body.getTextWidth();
+ if(this.title){
+ bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
+ }
+ bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
+ this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
+
+
+ if(Ext.isIE7 && !this.repainted){
+ this.el.repaint();
+ this.repainted = true;
+ }
+ },
+
+
+ showBy : function(el, pos){
+ if(!this.rendered){
+ this.render(Ext.getBody());
+ }
+ this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
+ },
+
+ initDraggable : function(){
+ this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
+ this.header.addClass('x-tip-draggable');
+ }
+});
+
+Ext.reg('tip', Ext.Tip);
+
+
+Ext.Tip.DD = function(tip, config){
+ Ext.apply(this, config);
+ this.tip = tip;
+ Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
+ this.setHandleElId(tip.header.id);
+ this.scroll = false;
+};
+
+Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
+ moveOnly:true,
+ scroll:false,
+ headerOffsets:[100, 25],
+ startDrag : function(){
+ this.tip.el.disableShadow();
+ },
+ endDrag : function(e){
+ this.tip.el.enableShadow(true);
+ }
+});
+Ext.ToolTip = Ext.extend(Ext.Tip, {
+
+
+
+
+ showDelay : 500,
+
+ hideDelay : 200,
+
+ dismissDelay : 5000,
+
+
+ trackMouse : false,
+
+ anchorToTarget : true,
+
+ anchorOffset : 0,
+
+
+
+ targetCounter : 0,
+
+ constrainPosition : false,
+
+
+ initComponent : function(){
+ Ext.ToolTip.superclass.initComponent.call(this);
+ this.lastActive = new Date();
+ this.initTarget(this.target);
+ this.origAnchor = this.anchor;
+ },
+
+
+ onRender : function(ct, position){
+ Ext.ToolTip.superclass.onRender.call(this, ct, position);
+ this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
+ this.anchorEl = this.el.createChild({
+ cls: 'x-tip-anchor ' + this.anchorCls
+ });
+ },
+
+
+ afterRender : function(){
+ Ext.ToolTip.superclass.afterRender.call(this);
+ this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
+ },
+
+
+ initTarget : function(target){
+ var t;
+ if((t = Ext.get(target))){
+ if(this.target){
+ var tg = Ext.get(this.target);
+ this.mun(tg, 'mouseover', this.onTargetOver, this);
+ this.mun(tg, 'mouseout', this.onTargetOut, this);
+ this.mun(tg, 'mousemove', this.onMouseMove, this);
+ }
+ this.mon(t, {
+ mouseover: this.onTargetOver,
+ mouseout: this.onTargetOut,
+ mousemove: this.onMouseMove,
+ scope: this
+ });
+ this.target = t;
+ }
+ if(this.anchor){
+ this.anchorTarget = this.target;
+ }
+ },
+
+
+ onMouseMove : function(e){
+ var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
+ if (t) {
+ this.targetXY = e.getXY();
+ if (t === this.triggerElement) {
+ if(!this.hidden && this.trackMouse){
+ this.setPagePosition(this.getTargetXY());
+ }
+ } else {
+ this.hide();
+ this.lastActive = new Date(0);
+ this.onTargetOver(e);
+ }
+ } else if (!this.closable && this.isVisible()) {
+ this.hide();
+ }
+ },
+
+
+ getTargetXY : function(){
+ if(this.delegate){
+ this.anchorTarget = this.triggerElement;
+ }
+ if(this.anchor){
+ this.targetCounter++;
+ var offsets = this.getOffsets(),
+ xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
+ dw = Ext.lib.Dom.getViewWidth() - 5,
+ dh = Ext.lib.Dom.getViewHeight() - 5,
+ de = document.documentElement,
+ bd = document.body,
+ scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
+ scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
+ axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
+ sz = this.getSize();
+
+ this.anchorEl.removeClass(this.anchorCls);
+
+ if(this.targetCounter < 2){
+ if(axy[0] < scrollX){
+ if(this.anchorToTarget){
+ this.defaultAlign = 'l-r';
+ if(this.mouseOffset){this.mouseOffset[0] *= -1;}
+ }
+ this.anchor = 'left';
+ return this.getTargetXY();
+ }
+ if(axy[0]+sz.width > dw){
+ if(this.anchorToTarget){
+ this.defaultAlign = 'r-l';
+ if(this.mouseOffset){this.mouseOffset[0] *= -1;}
+ }
+ this.anchor = 'right';
+ return this.getTargetXY();
+ }
+ if(axy[1] < scrollY){
+ if(this.anchorToTarget){
+ this.defaultAlign = 't-b';
+ if(this.mouseOffset){this.mouseOffset[1] *= -1;}
+ }
+ this.anchor = 'top';
+ return this.getTargetXY();
+ }
+ if(axy[1]+sz.height > dh){
+ if(this.anchorToTarget){
+ this.defaultAlign = 'b-t';
+ if(this.mouseOffset){this.mouseOffset[1] *= -1;}
+ }
+ this.anchor = 'bottom';
+ return this.getTargetXY();
+ }
+ }
+
+ this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
+ this.anchorEl.addClass(this.anchorCls);
+ this.targetCounter = 0;
+ return axy;
+ }else{
+ var mouseOffset = this.getMouseOffset();
+ return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
+ }
+ },
+
+ getMouseOffset : function(){
+ var offset = this.anchor ? [0,0] : [15,18];
+ if(this.mouseOffset){
+ offset[0] += this.mouseOffset[0];
+ offset[1] += this.mouseOffset[1];
+ }
+ return offset;
+ },
+
+
+ getAnchorPosition : function(){
+ if(this.anchor){
+ this.tipAnchor = this.anchor.charAt(0);
+ }else{
+ var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
+ if(!m){
+ throw 'AnchorTip.defaultAlign is invalid';
+ }
+ this.tipAnchor = m[1].charAt(0);
+ }
+
+ switch(this.tipAnchor){
+ case 't': return 'top';
+ case 'b': return 'bottom';
+ case 'r': return 'right';
+ }
+ return 'left';
+ },
+
+
+ getAnchorAlign : function(){
+ switch(this.anchor){
+ case 'top' : return 'tl-bl';
+ case 'left' : return 'tl-tr';
+ case 'right': return 'tr-tl';
+ default : return 'bl-tl';
+ }
+ },
+
+
+ getOffsets : function(){
+ var offsets,
+ ap = this.getAnchorPosition().charAt(0);
+ if(this.anchorToTarget && !this.trackMouse){
+ switch(ap){
+ case 't':
+ offsets = [0, 9];
+ break;
+ case 'b':
+ offsets = [0, -13];
+ break;
+ case 'r':
+ offsets = [-13, 0];
+ break;
+ default:
+ offsets = [9, 0];
+ break;
+ }
+ }else{
+ switch(ap){
+ case 't':
+ offsets = [-15-this.anchorOffset, 30];
+ break;
+ case 'b':
+ offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
+ break;
+ case 'r':
+ offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
+ break;
+ default:
+ offsets = [25, -13-this.anchorOffset];
+ break;
+ }
+ }
+ var mouseOffset = this.getMouseOffset();
+ offsets[0] += mouseOffset[0];
+ offsets[1] += mouseOffset[1];
+
+ return offsets;
+ },
+
+
+ onTargetOver : function(e){
+ if(this.disabled || e.within(this.target.dom, true)){
+ return;
+ }
+ var t = e.getTarget(this.delegate);
+ if (t) {
+ this.triggerElement = t;
+ this.clearTimer('hide');
+ this.targetXY = e.getXY();
+ this.delayShow();
+ }
+ },
+
+
+ delayShow : function(){
+ if(this.hidden && !this.showTimer){
+ if(this.lastActive.getElapsed() < this.quickShowInterval){
+ this.show();
+ }else{
+ this.showTimer = this.show.defer(this.showDelay, this);
+ }
+ }else if(!this.hidden && this.autoHide !== false){
+ this.show();
+ }
+ },
+
+
+ onTargetOut : function(e){
+ if(this.disabled || e.within(this.target.dom, true)){
+ return;
+ }
+ this.clearTimer('show');
+ if(this.autoHide !== false){
+ this.delayHide();
+ }
+ },
+
+
+ delayHide : function(){
+ if(!this.hidden && !this.hideTimer){
+ this.hideTimer = this.hide.defer(this.hideDelay, this);
+ }
+ },
+
+
+ hide: function(){
+ this.clearTimer('dismiss');
+ this.lastActive = new Date();
+ if(this.anchorEl){
+ this.anchorEl.hide();
+ }
+ Ext.ToolTip.superclass.hide.call(this);
+ delete this.triggerElement;
+ },
+
+
+ show : function(){
+ if(this.anchor){
+
+
+ this.showAt([-1000,-1000]);
+ this.origConstrainPosition = this.constrainPosition;
+ this.constrainPosition = false;
+ this.anchor = this.origAnchor;
+ }
+ this.showAt(this.getTargetXY());
+
+ if(this.anchor){
+ this.anchorEl.show();
+ this.syncAnchor();
+ this.constrainPosition = this.origConstrainPosition;
+ }else{
+ this.anchorEl.hide();
+ }
+ },
+
+
+ showAt : function(xy){
+ this.lastActive = new Date();
+ this.clearTimers();
+ Ext.ToolTip.superclass.showAt.call(this, xy);
+ if(this.dismissDelay && this.autoHide !== false){
+ this.dismissTimer = this.hide.defer(this.dismissDelay, this);
+ }
+ if(this.anchor && !this.anchorEl.isVisible()){
+ this.syncAnchor();
+ this.anchorEl.show();
+ }else{
+ this.anchorEl.hide();
+ }
+ },
+
+
+ syncAnchor : function(){
+ var anchorPos, targetPos, offset;
+ switch(this.tipAnchor.charAt(0)){
+ case 't':
+ anchorPos = 'b';
+ targetPos = 'tl';
+ offset = [20+this.anchorOffset, 2];
+ break;
+ case 'r':
+ anchorPos = 'l';
+ targetPos = 'tr';
+ offset = [-2, 11+this.anchorOffset];
+ break;
+ case 'b':
+ anchorPos = 't';
+ targetPos = 'bl';
+ offset = [20+this.anchorOffset, -2];
+ break;
+ default:
+ anchorPos = 'r';
+ targetPos = 'tl';
+ offset = [2, 11+this.anchorOffset];
+ break;
+ }
+ this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
+ },
+
+
+ setPagePosition : function(x, y){
+ Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
+ if(this.anchor){
+ this.syncAnchor();
+ }
+ },
+
+
+ clearTimer : function(name){
+ name = name + 'Timer';
+ clearTimeout(this[name]);
+ delete this[name];
+ },
+
+
+ clearTimers : function(){
+ this.clearTimer('show');
+ this.clearTimer('dismiss');
+ this.clearTimer('hide');
+ },
+
+
+ onShow : function(){
+ Ext.ToolTip.superclass.onShow.call(this);
+ Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
+ },
+
+
+ onHide : function(){
+ Ext.ToolTip.superclass.onHide.call(this);
+ Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
+ },
+
+
+ onDocMouseDown : function(e){
+ if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
+ this.disable();
+ this.doEnable.defer(100, this);
+ }
+ },
+
+
+ doEnable : function(){
+ if(!this.isDestroyed){
+ this.enable();
+ }
+ },
+
+
+ onDisable : function(){
+ this.clearTimers();
+ this.hide();
+ },
+
+
+ adjustPosition : function(x, y){
+ if(this.constrainPosition){
+ var ay = this.targetXY[1], h = this.getSize().height;
+ if(y <= ay && (y+h) >= ay){
+ y = ay-h-5;
+ }
+ }
+ return {x : x, y: y};
+ },
+
+ beforeDestroy : function(){
+ this.clearTimers();
+ Ext.destroy(this.anchorEl);
+ delete this.anchorEl;
+ delete this.target;
+ delete this.anchorTarget;
+ delete this.triggerElement;
+ Ext.ToolTip.superclass.beforeDestroy.call(this);
+ },
+
+
+ onDestroy : function(){
+ Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
+ Ext.ToolTip.superclass.onDestroy.call(this);
+ }
+});
+
+Ext.reg('tooltip', Ext.ToolTip);
+Ext.QuickTip = Ext.extend(Ext.ToolTip, {
+
+
+ interceptTitles : false,
+
+
+ tagConfig : {
+ namespace : "ext",
+ attribute : "qtip",
+ width : "qwidth",
+ target : "target",
+ title : "qtitle",
+ hide : "hide",
+ cls : "qclass",
+ align : "qalign",
+ anchor : "anchor"
+ },
+
+
+ initComponent : function(){
+ this.target = this.target || Ext.getDoc();
+ this.targets = this.targets || {};
+ Ext.QuickTip.superclass.initComponent.call(this);
+ },
+
+
+ register : function(config){
+ var cs = Ext.isArray(config) ? config : arguments;
+ for(var i = 0, len = cs.length; i < len; i++){
+ var c = cs[i];
+ var target = c.target;
+ if(target){
+ if(Ext.isArray(target)){
+ for(var j = 0, jlen = target.length; j < jlen; j++){
+ this.targets[Ext.id(target[j])] = c;
+ }
+ } else{
+ this.targets[Ext.id(target)] = c;
+ }
+ }
+ }
+ },
+
+
+ unregister : function(el){
+ delete this.targets[Ext.id(el)];
+ },
+
+
+ cancelShow: function(el){
+ var at = this.activeTarget;
+ el = Ext.get(el).dom;
+ if(this.isVisible()){
+ if(at && at.el == el){
+ this.hide();
+ }
+ }else if(at && at.el == el){
+ this.clearTimer('show');
+ }
+ },
+
+ getTipCfg: function(e) {
+ var t = e.getTarget(),
+ ttp,
+ cfg;
+ if(this.interceptTitles && t.title && Ext.isString(t.title)){
+ ttp = t.title;
+ t.qtip = ttp;
+ t.removeAttribute("title");
+ e.preventDefault();
+ }else{
+ cfg = this.tagConfig;
+ ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
+ }
+ return ttp;
+ },
+
+
+ onTargetOver : function(e){
+ if(this.disabled){
+ return;
+ }
+ this.targetXY = e.getXY();
+ var t = e.getTarget();
+ if(!t || t.nodeType !== 1 || t == document || t == document.body){
+ return;
+ }
+ if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
+ this.clearTimer('hide');
+ this.show();
+ return;
+ }
+ if(t && this.targets[t.id]){
+ this.activeTarget = this.targets[t.id];
+ this.activeTarget.el = t;
+ this.anchor = this.activeTarget.anchor;
+ if(this.anchor){
+ this.anchorTarget = t;
+ }
+ this.delayShow();
+ return;
+ }
+ var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
+ if(ttp = this.getTipCfg(e)){
+ var autoHide = et.getAttribute(cfg.hide, ns);
+ this.activeTarget = {
+ el: t,
+ text: ttp,
+ width: et.getAttribute(cfg.width, ns),
+ autoHide: autoHide != "user" && autoHide !== 'false',
+ title: et.getAttribute(cfg.title, ns),
+ cls: et.getAttribute(cfg.cls, ns),
+ align: et.getAttribute(cfg.align, ns)
+
+ };
+ this.anchor = et.getAttribute(cfg.anchor, ns);
+ if(this.anchor){
+ this.anchorTarget = t;
+ }
+ this.delayShow();
+ }
+ },
+
+
+ onTargetOut : function(e){
+
+
+ if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
+ return;
+ }
+
+ this.clearTimer('show');
+ if(this.autoHide !== false){
+ this.delayHide();
+ }
+ },
+
+
+ showAt : function(xy){
+ var t = this.activeTarget;
+ if(t){
+ if(!this.rendered){
+ this.render(Ext.getBody());
+ this.activeTarget = t;
+ }
+ if(t.width){
+ this.setWidth(t.width);
+ this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
+ this.measureWidth = false;
+ } else{
+ this.measureWidth = true;
+ }
+ this.setTitle(t.title || '');
+ this.body.update(t.text);
+ this.autoHide = t.autoHide;
+ this.dismissDelay = t.dismissDelay || this.dismissDelay;
+ if(this.lastCls){
+ this.el.removeClass(this.lastCls);
+ delete this.lastCls;
+ }
+ if(t.cls){
+ this.el.addClass(t.cls);
+ this.lastCls = t.cls;
+ }
+ if(this.anchor){
+ this.constrainPosition = false;
+ }else if(t.align){
+ xy = this.el.getAlignToXY(t.el, t.align);
+ this.constrainPosition = false;
+ }else{
+ this.constrainPosition = true;
+ }
+ }
+ Ext.QuickTip.superclass.showAt.call(this, xy);
+ },
+
+
+ hide: function(){
+ delete this.activeTarget;
+ Ext.QuickTip.superclass.hide.call(this);
+ }
+});
+Ext.reg('quicktip', Ext.QuickTip);
+Ext.QuickTips = function(){
+ var tip,
+ disabled = false;
+
+ return {
+
+ init : function(autoRender){
+ if(!tip){
+ if(!Ext.isReady){
+ Ext.onReady(function(){
+ Ext.QuickTips.init(autoRender);
+ });
+ return;
+ }
+ tip = new Ext.QuickTip({
+ elements:'header,body',
+ disabled: disabled
+ });
+ if(autoRender !== false){
+ tip.render(Ext.getBody());
+ }
+ }
+ },
+
+
+ ddDisable : function(){
+
+ if(tip && !disabled){
+ tip.disable();
+ }
+ },
+
+
+ ddEnable : function(){
+
+ if(tip && !disabled){
+ tip.enable();
+ }
+ },
+
+
+ enable : function(){
+ if(tip){
+ tip.enable();
+ }
+ disabled = false;
+ },
+
+
+ disable : function(){
+ if(tip){
+ tip.disable();
+ }
+ disabled = true;
+ },
+
+
+ isEnabled : function(){
+ return tip !== undefined && !tip.disabled;
+ },
+
+
+ getQuickTip : function(){
+ return tip;
+ },
+
+
+ register : function(){
+ tip.register.apply(tip, arguments);
+ },
+
+
+ unregister : function(){
+ tip.unregister.apply(tip, arguments);
+ },
+
+
+ tips : function(){
+ tip.register.apply(tip, arguments);
+ }
+ };
+}();
+Ext.slider.Tip = Ext.extend(Ext.Tip, {
+ minWidth: 10,
+ offsets : [0, -10],
+
+ init: function(slider) {
+ slider.on({
+ scope : this,
+ dragstart: this.onSlide,
+ drag : this.onSlide,
+ dragend : this.hide,
+ destroy : this.destroy
+ });
+ },
+
+
+ onSlide : function(slider, e, thumb) {
+ this.show();
+ this.body.update(this.getText(thumb));
+ this.doAutoWidth();
+ this.el.alignTo(thumb.el, 'b-t?', this.offsets);
+ },
+
+
+ getText : function(thumb) {
+ return String(thumb.value);
+ }
+});
+
+
+Ext.ux.SliderTip = Ext.slider.Tip;
+Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
+ rootVisible : true,
+ animate : Ext.enableFx,
+ lines : true,
+ enableDD : false,
+ hlDrop : Ext.enableFx,
+ pathSeparator : '/',
+
+
+ bubbleEvents : [],
+
+ initComponent : function(){
+ Ext.tree.TreePanel.superclass.initComponent.call(this);
+
+ if(!this.eventModel){
+ this.eventModel = new Ext.tree.TreeEventModel(this);
+ }
+
+
+ var l = this.loader;
+ if(!l){
+ l = new Ext.tree.TreeLoader({
+ dataUrl: this.dataUrl,
+ requestMethod: this.requestMethod
+ });
+ }else if(Ext.isObject(l) && !l.load){
+ l = new Ext.tree.TreeLoader(l);
+ }
+ this.loader = l;
+
+ this.nodeHash = {};
+
+
+ if(this.root){
+ var r = this.root;
+ delete this.root;
+ this.setRootNode(r);
+ }
+
+
+ this.addEvents(
+
+
+ 'append',
+
+ 'remove',
+
+ 'movenode',
+
+ 'insert',
+
+ 'beforeappend',
+
+ 'beforeremove',
+
+ 'beforemovenode',
+
+ 'beforeinsert',
+
+
+ 'beforeload',
+
+ 'load',
+
+ 'textchange',
+
+ 'beforeexpandnode',
+
+ 'beforecollapsenode',
+
+ 'expandnode',
+
+ 'disabledchange',
+
+ 'collapsenode',
+
+ 'beforeclick',
+
+ 'click',
+
+ 'containerclick',
+
+ 'checkchange',
+
+ 'beforedblclick',
+
+ 'dblclick',
+
+ 'containerdblclick',
+
+ 'contextmenu',
+
+ 'containercontextmenu',
+
+ 'beforechildrenrendered',
+
+ 'startdrag',
+
+ 'enddrag',
+
+ 'dragdrop',
+
+ 'beforenodedrop',
+
+ 'nodedrop',
+
+ 'nodedragover'
+ );
+ if(this.singleExpand){
+ this.on('beforeexpandnode', this.restrictExpand, this);
+ }
+ },
+
+
+ proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
+ if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
+ ename = ename+'node';
+ }
+
+ return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
+ },
+
+
+
+ getRootNode : function(){
+ return this.root;
+ },
+
+
+ setRootNode : function(node){
+ this.destroyRoot();
+ if(!node.render){
+ node = this.loader.createNode(node);
+ }
+ this.root = node;
+ node.ownerTree = this;
+ node.isRoot = true;
+ this.registerNode(node);
+ if(!this.rootVisible){
+ var uiP = node.attributes.uiProvider;
+ node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
+ }
+ if(this.innerCt){
+ this.clearInnerCt();
+ this.renderRoot();
+ }
+ return node;
+ },
+
+ clearInnerCt : function(){
+ this.innerCt.update('');
+ },
+
+
+ renderRoot : function(){
+ this.root.render();
+ if(!this.rootVisible){
+ this.root.renderChildren();
+ }
+ },
+
+
+ getNodeById : function(id){
+ return this.nodeHash[id];
+ },
+
+
+ registerNode : function(node){
+ this.nodeHash[node.id] = node;
+ },
+
+
+ unregisterNode : function(node){
+ delete this.nodeHash[node.id];
+ },
+
+
+ toString : function(){
+ return '[Tree'+(this.id?' '+this.id:'')+']';
+ },
+
+
+ restrictExpand : function(node){
+ var p = node.parentNode;
+ if(p){
+ if(p.expandedChild && p.expandedChild.parentNode == p){
+ p.expandedChild.collapse();
+ }
+ p.expandedChild = node;
+ }
+ },
+
+
+ getChecked : function(a, startNode){
+ startNode = startNode || this.root;
+ var r = [];
+ var f = function(){
+ if(this.attributes.checked){
+ r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
+ }
+ };
+ startNode.cascade(f);
+ return r;
+ },
+
+
+ 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(path, attr, callback){
+ if(Ext.isEmpty(path)){
+ if(callback){
+ callback(false, undefined);
+ }
+ return;
+ }
+ attr = attr || 'id';
+ var keys = path.split(this.pathSeparator);
+ var curNode = this.root;
+ if(curNode.attributes[attr] != keys[1]){
+ if(callback){
+ callback(false, null);
+ }
+ return;
+ }
+ var index = 1;
+ var f = function(){
+ if(++index == keys.length){
+ if(callback){
+ callback(true, curNode);
+ }
+ return;
+ }
+ var c = curNode.findChild(attr, keys[index]);
+ if(!c){
+ if(callback){
+ callback(false, curNode);
+ }
+ return;
+ }
+ curNode = c;
+ c.expand(false, false, f);
+ };
+ curNode.expand(false, false, f);
+ },
+
+
+ selectPath : function(path, attr, callback){
+ if(Ext.isEmpty(path)){
+ if(callback){
+ callback(false, undefined);
+ }
+ return;
+ }
+ attr = attr || 'id';
+ var keys = path.split(this.pathSeparator),
+ v = keys.pop();
+ if(keys.length > 1){
+ var f = function(success, node){
+ if(success && node){
+ var n = node.findChild(attr, v);
+ if(n){
+ n.select();
+ if(callback){
+ callback(true, n);
+ }
+ }else if(callback){
+ callback(false, n);
+ }
+ }else{
+ if(callback){
+ callback(false, n);
+ }
+ }
+ };
+ this.expandPath(keys.join(this.pathSeparator), attr, f);
+ }else{
+ this.root.select();
+ if(callback){
+ callback(true, this.root);
+ }
+ }
+ },
+
+
+ getTreeEl : function(){
+ return this.body;
+ },
+
+
+ onRender : function(ct, position){
+ Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
+ this.el.addClass('x-tree');
+ this.innerCt = this.body.createChild({tag:'ul',
+ cls:'x-tree-root-ct ' +
+ (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
+ },
+
+
+ initEvents : function(){
+ Ext.tree.TreePanel.superclass.initEvents.call(this);
+
+ if(this.containerScroll){
+ Ext.dd.ScrollManager.register(this.body);
+ }
+ 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);
+ },
+
+
+ afterRender : function(){
+ Ext.tree.TreePanel.superclass.afterRender.call(this);
+ this.renderRoot();
+ },
+
+ beforeDestroy : function(){
+ if(this.rendered){
+ Ext.dd.ScrollManager.unregister(this.body);
+ Ext.destroy(this.dropZone, this.dragZone);
+ }
+ this.destroyRoot();
+ Ext.destroy(this.loader);
+ this.nodeHash = this.root = this.loader = null;
+ Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
+ },
+
+
+ destroyRoot : function(){
+ if(this.root && this.root.destroy){
+ this.root.destroy(true);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+});
+
+Ext.tree.TreePanel.nodeTypes = {};
+
+Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
+ this.tree = tree;
+ this.tree.on('render', this.initEvents, this);
+};
+
+Ext.tree.TreeEventModel.prototype = {
+ initEvents : function(){
+ var t = this.tree;
+
+ if(t.trackMouseOver !== false){
+ t.mon(t.innerCt, {
+ scope: this,
+ mouseover: this.delegateOver,
+ mouseout: this.delegateOut
+ });
+ }
+ t.mon(t.getTreeEl(), {
+ scope: this,
+ click: this.delegateClick,
+ dblclick: this.delegateDblClick,
+ contextmenu: this.delegateContextMenu
+ });
+ },
+
+ getNode : function(e){
+ var t;
+ if(t = e.getTarget('.x-tree-node-el', 10)){
+ var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
+ if(id){
+ return this.tree.getNodeById(id);
+ }
+ }
+ return null;
+ },
+
+ getNodeTarget : function(e){
+ var t = e.getTarget('.x-tree-node-icon', 1);
+ if(!t){
+ t = e.getTarget('.x-tree-node-el', 6);
+ }
+ return t;
+ },
+
+ delegateOut : function(e, t){
+ if(!this.beforeEvent(e)){
+ return;
+ }
+ if(e.getTarget('.x-tree-ec-icon', 1)){
+ var n = this.getNode(e);
+ this.onIconOut(e, n);
+ if(n == this.lastEcOver){
+ delete this.lastEcOver;
+ }
+ }
+ if((t = this.getNodeTarget(e)) && !e.within(t, true)){
+ this.onNodeOut(e, this.getNode(e));
+ }
+ },
+
+ delegateOver : function(e, t){
+ if(!this.beforeEvent(e)){
+ return;
+ }
+ if(Ext.isGecko && !this.trackingDoc){
+ Ext.getBody().on('mouseover', this.trackExit, this);
+ this.trackingDoc = true;
+ }
+ if(this.lastEcOver){
+ this.onIconOut(e, this.lastEcOver);
+ delete this.lastEcOver;
+ }
+ if(e.getTarget('.x-tree-ec-icon', 1)){
+ this.lastEcOver = this.getNode(e);
+ this.onIconOver(e, this.lastEcOver);
+ }
+ if(t = this.getNodeTarget(e)){
+ this.onNodeOver(e, this.getNode(e));
+ }
+ },
+
+ trackExit : function(e){
+ if(this.lastOverNode){
+ if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
+ this.onNodeOut(e, this.lastOverNode);
+ }
+ delete this.lastOverNode;
+ Ext.getBody().un('mouseover', this.trackExit, this);
+ this.trackingDoc = false;
+ }
+
+ },
+
+ delegateClick : function(e, t){
+ if(this.beforeEvent(e)){
+ if(e.getTarget('input[type=checkbox]', 1)){
+ this.onCheckboxClick(e, this.getNode(e));
+ }else if(e.getTarget('.x-tree-ec-icon', 1)){
+ this.onIconClick(e, this.getNode(e));
+ }else if(this.getNodeTarget(e)){
+ this.onNodeClick(e, this.getNode(e));
+ }
+ }else{
+ this.checkContainerEvent(e, 'click');
+ }
+ },
+
+ delegateDblClick : function(e, t){
+ if(this.beforeEvent(e)){
+ if(this.getNodeTarget(e)){
+ this.onNodeDblClick(e, this.getNode(e));
+ }
+ }else{
+ this.checkContainerEvent(e, 'dblclick');
+ }
+ },
+
+ delegateContextMenu : function(e, t){
+ if(this.beforeEvent(e)){
+ if(this.getNodeTarget(e)){
+ this.onNodeContextMenu(e, this.getNode(e));
+ }
+ }else{
+ this.checkContainerEvent(e, 'contextmenu');
+ }
+ },
+
+ checkContainerEvent: function(e, type){
+ if(this.disabled){
+ e.stopEvent();
+ return false;
+ }
+ this.onContainerEvent(e, type);
+ },
+
+ onContainerEvent: function(e, type){
+ this.tree.fireEvent('container' + type, this.tree, e);
+ },
+
+ onNodeClick : function(e, node){
+ node.ui.onClick(e);
+ },
+
+ onNodeOver : function(e, node){
+ this.lastOverNode = node;
+ node.ui.onOver(e);
+ },
+
+ onNodeOut : function(e, node){
+ node.ui.onOut(e);
+ },
+
+ onIconOver : function(e, node){
+ node.ui.addClass('x-tree-ec-over');
+ },
+
+ onIconOut : function(e, node){
+ node.ui.removeClass('x-tree-ec-over');
+ },
+
+ onIconClick : function(e, node){
+ node.ui.ecClick(e);
+ },
+
+ onCheckboxClick : function(e, node){
+ node.ui.onCheckChange(e);
+ },
+
+ onNodeDblClick : function(e, node){
+ node.ui.onDblClick(e);
+ },
+
+ onNodeContextMenu : function(e, node){
+ node.ui.onContextMenu(e);
+ },
+
+ beforeEvent : function(e){
+ var node = this.getNode(e);
+ if(this.disabled || !node || !node.ui){
+ e.stopEvent();
+ return false;
+ }
+ return true;
+ },
+
+ disable: function(){
+ this.disabled = true;
+ },
+
+ enable: function(){
+ this.disabled = false;
+ }
+};
+Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
+
+ constructor : function(config){
+ this.selNode = null;
+
+ this.addEvents(
+
+ 'selectionchange',
+
+
+ 'beforeselect'
+ );
+
+ Ext.apply(this, config);
+ Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
+ },
+
+ init : function(tree){
+ this.tree = tree;
+ tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
+ tree.on('click', this.onNodeClick, this);
+ },
+
+ onNodeClick : function(node, e){
+ this.select(node);
+ },
+
+
+ select : function(node, selectNextNode){
+
+ if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
+ return selectNextNode.call(this, node);
+ }
+ var last = this.selNode;
+ if(node == last){
+ node.ui.onSelectedChange(true);
+ }else if(this.fireEvent('beforeselect', this, node, last) !== false){
+ if(last && last.ui){
+ last.ui.onSelectedChange(false);
+ }
+ this.selNode = node;
+ node.ui.onSelectedChange(true);
+ this.fireEvent('selectionchange', this, node, last);
+ }
+ return node;
+ },
+
+
+ unselect : function(node, silent){
+ if(this.selNode == node){
+ this.clearSelections(silent);
+ }
+ },
+
+
+ clearSelections : function(silent){
+ var n = this.selNode;
+ if(n){
+ n.ui.onSelectedChange(false);
+ this.selNode = null;
+ if(silent !== true){
+ this.fireEvent('selectionchange', this, null);
+ }
+ }
+ return n;
+ },
+
+
+ getSelectedNode : function(){
+ return this.selNode;
+ },
+
+
+ isSelected : function(node){
+ return this.selNode == node;
+ },
+
+
+ selectPrevious : function( s){
+ if(!(s = s || this.selNode || this.lastSelNode)){
+ return null;
+ }
+
+ var ps = s.previousSibling;
+ if(ps){
+ if(!ps.isExpanded() || ps.childNodes.length < 1){
+ return this.select(ps, this.selectPrevious);
+ } else{
+ var lc = ps.lastChild;
+ while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
+ lc = lc.lastChild;
+ }
+ return this.select(lc, this.selectPrevious);
+ }
+ } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
+ return this.select(s.parentNode, this.selectPrevious);
+ }
+ return null;
+ },
+
+
+ selectNext : function( s){
+ if(!(s = s || this.selNode || this.lastSelNode)){
+ return null;
+ }
+
+ if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
+ return this.select(s.firstChild, this.selectNext);
+ }else if(s.nextSibling){
+ return this.select(s.nextSibling, this.selectNext);
+ }else if(s.parentNode){
+ var newS = null;
+ s.parentNode.bubble(function(){
+ if(this.nextSibling){
+ newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
+ return false;
+ }
+ });
+ return newS;
+ }
+ 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 = Ext.extend(Ext.util.Observable, {
+
+ constructor : function(config){
+ this.selNodes = [];
+ this.selMap = {};
+ this.addEvents(
+
+ 'selectionchange'
+ );
+ Ext.apply(this, config);
+ Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
+ },
+
+ init : function(tree){
+ this.tree = tree;
+ tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
+ tree.on('click', this.onNodeClick, this);
+ },
+
+ onNodeClick : function(node, e){
+ if(e.ctrlKey && this.isSelected(node)){
+ this.unselect(node);
+ }else{
+ this.select(node, e, e.ctrlKey);
+ }
+ },
+
+
+ select : function(node, e, keepExisting){
+ if(keepExisting !== true){
+ this.clearSelections(true);
+ }
+ if(this.isSelected(node)){
+ this.lastSelNode = node;
+ return node;
+ }
+ this.selNodes.push(node);
+ this.selMap[node.id] = node;
+ this.lastSelNode = node;
+ node.ui.onSelectedChange(true);
+ this.fireEvent('selectionchange', this, this.selNodes);
+ return node;
+ },
+
+
+ unselect : function(node){
+ if(this.selMap[node.id]){
+ node.ui.onSelectedChange(false);
+ var sn = this.selNodes;
+ var index = sn.indexOf(node);
+ if(index != -1){
+ this.selNodes.splice(index, 1);
+ }
+ delete this.selMap[node.id];
+ this.fireEvent('selectionchange', this, this.selNodes);
+ }
+ },
+
+
+ clearSelections : function(suppressEvent){
+ 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(suppressEvent !== true){
+ this.fireEvent('selectionchange', this, this.selNodes);
+ }
+ }
+ },
+
+
+ isSelected : function(node){
+ return this.selMap[node.id] ? true : false;
+ },
+
+
+ getSelectedNodes : function(){
+ return this.selNodes.concat([]);
+ },
+
+ onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
+
+ selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
+
+ selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
+});
+Ext.data.Tree = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(root){
+ this.nodeHash = {};
+
+ this.root = null;
+ if(root){
+ this.setRootNode(root);
+ }
+ this.addEvents(
+
+ "append",
+
+ "remove",
+
+ "move",
+
+ "insert",
+
+ "beforeappend",
+
+ "beforeremove",
+
+ "beforemove",
+
+ "beforeinsert"
+ );
+ Ext.data.Tree.superclass.constructor.call(this);
+ },
+
+
+ pathSeparator: "/",
+
+
+ proxyNodeEvent : function(){
+ return this.fireEvent.apply(this, arguments);
+ },
+
+
+ getRootNode : function(){
+ return this.root;
+ },
+
+
+ setRootNode : function(node){
+ this.root = node;
+ node.ownerTree = this;
+ node.isRoot = true;
+ this.registerNode(node);
+ return node;
+ },
+
+
+ getNodeById : function(id){
+ return this.nodeHash[id];
+ },
+
+
+ registerNode : function(node){
+ this.nodeHash[node.id] = node;
+ },
+
+
+ unregisterNode : function(node){
+ delete this.nodeHash[node.id];
+ },
+
+ toString : function(){
+ return "[Tree"+(this.id?" "+this.id:"")+"]";
+ }
+});
+
+
+Ext.data.Node = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(attributes){
+
+ this.attributes = attributes || {};
+ this.leaf = this.attributes.leaf;
+
+ this.id = this.attributes.id;
+ if(!this.id){
+ this.id = Ext.id(null, "xnode-");
+ this.attributes.id = this.id;
+ }
+
+ this.childNodes = [];
+
+ this.parentNode = null;
+
+ this.firstChild = null;
+
+ this.lastChild = null;
+
+ this.previousSibling = null;
+
+ this.nextSibling = null;
+
+ this.addEvents({
+
+ "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);
+ },
+
+
+ fireEvent : function(evtName){
+
+ if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
+ return false;
+ }
+
+ var ot = this.getOwnerTree();
+ if(ot){
+ if(ot.proxyNodeEvent.apply(ot, arguments) === false){
+ return false;
+ }
+ }
+ return true;
+ },
+
+
+ isLeaf : function(){
+ return this.leaf === true;
+ },
+
+
+ setFirstChild : function(node){
+ this.firstChild = node;
+ },
+
+
+ setLastChild : function(node){
+ this.lastChild = node;
+ },
+
+
+
+ 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;
+ },
+
+
+ isExpandable : function(){
+ return this.attributes.expandable || this.hasChildNodes();
+ },
+
+
+ appendChild : function(node){
+ var multi = false;
+ if(Ext.isArray(node)){
+ multi = node;
+ }else if(arguments.length > 1){
+ multi = arguments;
+ }
+
+ if(multi){
+ for(var i = 0, len = multi.length; i < len; i++) {
+ this.appendChild(multi[i]);
+ }
+ }else{
+ if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
+ return false;
+ }
+ var index = this.childNodes.length;
+ var oldParent = node.parentNode;
+
+ if(oldParent){
+ if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
+ return false;
+ }
+ oldParent.removeChild(node);
+ }
+ index = this.childNodes.length;
+ if(index === 0){
+ this.setFirstChild(node);
+ }
+ this.childNodes.push(node);
+ node.parentNode = this;
+ var ps = this.childNodes[index-1];
+ if(ps){
+ node.previousSibling = ps;
+ ps.nextSibling = node;
+ }else{
+ node.previousSibling = null;
+ }
+ node.nextSibling = null;
+ this.setLastChild(node);
+ node.setOwnerTree(this.getOwnerTree());
+ this.fireEvent("append", this.ownerTree, this, node, index);
+ if(oldParent){
+ node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
+ }
+ return node;
+ }
+ },
+
+
+ removeChild : function(node, destroy){
+ var index = this.childNodes.indexOf(node);
+ if(index == -1){
+ return false;
+ }
+ if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
+ return false;
+ }
+
+
+ this.childNodes.splice(index, 1);
+
+
+ if(node.previousSibling){
+ node.previousSibling.nextSibling = node.nextSibling;
+ }
+ if(node.nextSibling){
+ node.nextSibling.previousSibling = node.previousSibling;
+ }
+
+
+ if(this.firstChild == node){
+ this.setFirstChild(node.nextSibling);
+ }
+ if(this.lastChild == node){
+ this.setLastChild(node.previousSibling);
+ }
+
+ this.fireEvent("remove", this.ownerTree, this, node);
+ if(destroy){
+ node.destroy(true);
+ }else{
+ node.clear();
+ }
+ return node;
+ },
+
+
+ clear : function(destroy){
+
+ this.setOwnerTree(null, destroy);
+ this.parentNode = this.previousSibling = this.nextSibling = null;
+ if(destroy){
+ this.firstChild = this.lastChild = null;
+ }
+ },
+
+
+ destroy : function( silent){
+
+ if(silent === true){
+ this.purgeListeners();
+ this.clear(true);
+ Ext.each(this.childNodes, function(n){
+ n.destroy(true);
+ });
+ this.childNodes = null;
+ }else{
+ this.remove(true);
+ }
+ },
+
+
+ insertBefore : function(node, refNode){
+ if(!refNode){
+ return this.appendChild(node);
+ }
+
+ if(node == refNode){
+ return false;
+ }
+
+ if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
+ return false;
+ }
+ var index = this.childNodes.indexOf(refNode);
+ var oldParent = node.parentNode;
+ var refIndex = index;
+
+
+ if(oldParent == this && this.childNodes.indexOf(node) < index){
+ refIndex--;
+ }
+
+
+ if(oldParent){
+ if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
+ return false;
+ }
+ oldParent.removeChild(node);
+ }
+ if(refIndex === 0){
+ this.setFirstChild(node);
+ }
+ this.childNodes.splice(refIndex, 0, node);
+ node.parentNode = this;
+ var ps = this.childNodes[refIndex-1];
+ if(ps){
+ node.previousSibling = ps;
+ ps.nextSibling = node;
+ }else{
+ node.previousSibling = null;
+ }
+ node.nextSibling = refNode;
+ refNode.previousSibling = node;
+ node.setOwnerTree(this.getOwnerTree());
+ this.fireEvent("insert", this.ownerTree, this, node, refNode);
+ if(oldParent){
+ node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
+ }
+ return node;
+ },
+
+
+ remove : function(destroy){
+ if (this.parentNode) {
+ this.parentNode.removeChild(this, destroy);
+ }
+ return this;
+ },
+
+
+ removeAll : function(destroy){
+ var cn = this.childNodes,
+ n;
+ while((n = cn[0])){
+ this.removeChild(n, destroy);
+ }
+ return this;
+ },
+
+
+ item : function(index){
+ return this.childNodes[index];
+ },
+
+
+ replaceChild : function(newChild, oldChild){
+ var s = oldChild ? oldChild.nextSibling : null;
+ this.removeChild(oldChild);
+ this.insertBefore(newChild, s);
+ return oldChild;
+ },
+
+
+ indexOf : function(child){
+ return this.childNodes.indexOf(child);
+ },
+
+
+ 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 depth = 0;
+ var p = this;
+ while(p.parentNode){
+ ++depth;
+ p = p.parentNode;
+ }
+ return depth;
+ },
+
+
+ setOwnerTree : function(tree, destroy){
+
+ if(tree != this.ownerTree){
+ if(this.ownerTree){
+ this.ownerTree.unregisterNode(this);
+ }
+ this.ownerTree = tree;
+
+ if(destroy !== true){
+ Ext.each(this.childNodes, function(n){
+ n.setOwnerTree(tree);
+ });
+ }
+ if(tree){
+ tree.registerNode(this);
+ }
+ }
+ },
+
+
+ setId: function(id){
+ if(id !== this.id){
+ var t = this.ownerTree;
+ if(t){
+ t.unregisterNode(this);
+ }
+ this.id = this.attributes.id = id;
+ if(t){
+ t.registerNode(this);
+ }
+ this.onIdChange(id);
+ }
+ },
+
+
+ onIdChange: Ext.emptyFn,
+
+
+ getPath : function(attr){
+ attr = attr || "id";
+ var p = this.parentNode;
+ var b = [this.attributes[attr]];
+ while(p){
+ b.unshift(p.attributes[attr]);
+ p = p.parentNode;
+ }
+ var sep = this.getOwnerTree().pathSeparator;
+ return sep + b.join(sep);
+ },
+
+
+ bubble : function(fn, scope, args){
+ var p = this;
+ while(p){
+ if(fn.apply(scope || p, args || [p]) === false){
+ break;
+ }
+ p = p.parentNode;
+ }
+ },
+
+
+ cascade : function(fn, scope, args){
+ if(fn.apply(scope || this, args || [this]) !== false){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].cascade(fn, scope, args);
+ }
+ }
+ },
+
+
+ eachChild : function(fn, scope, args){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
+ break;
+ }
+ }
+ },
+
+
+ findChild : function(attribute, value, deep){
+ return this.findChildBy(function(){
+ return this.attributes[attribute] == value;
+ }, null, deep);
+ },
+
+
+ findChildBy : function(fn, scope, deep){
+ var cs = this.childNodes,
+ len = cs.length,
+ i = 0,
+ n,
+ res;
+ for(; i < len; i++){
+ n = cs[i];
+ if(fn.call(scope || n, n) === true){
+ return n;
+ }else if (deep){
+ res = n.findChildBy(fn, scope, deep);
+ if(res != null){
+ return res;
+ }
+ }
+
+ }
+ return null;
+ },
+
+
+ sort : function(fn, scope){
+ var cs = this.childNodes;
+ var len = cs.length;
+ if(len > 0){
+ var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
+ cs.sort(sortFn);
+ 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(node){
+ return node.isAncestor(this);
+ },
+
+
+ isAncestor : function(node){
+ var p = this.parentNode;
+ while(p){
+ if(p == node){
+ return true;
+ }
+ p = p.parentNode;
+ }
+ return false;
+ },
+
+ toString : function(){
+ return "[Node"+(this.id?" "+this.id:"")+"]";
+ }
+});
+Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {
+
+ constructor : function(attributes){
+ attributes = attributes || {};
+ if(Ext.isString(attributes)){
+ attributes = {text: attributes};
+ }
+ this.childrenRendered = false;
+ this.rendered = false;
+ Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
+ this.expanded = attributes.expanded === true;
+ this.isTarget = attributes.isTarget !== false;
+ this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
+ this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
+
+
+ this.text = attributes.text;
+
+ this.disabled = attributes.disabled === true;
+
+ this.hidden = attributes.hidden === true;
+
+ this.addEvents(
+
+ 'textchange',
+
+ 'beforeexpand',
+
+ 'beforecollapse',
+
+ 'expand',
+
+ 'disabledchange',
+
+ 'collapse',
+
+ 'beforeclick',
+
+ 'click',
+
+ 'checkchange',
+
+ 'beforedblclick',
+
+ 'dblclick',
+
+ 'contextmenu',
+
+ 'beforechildrenrendered'
+ );
+
+ var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
+
+
+ this.ui = new uiClass(this);
+ },
+
+ preventHScroll : true,
+
+ isExpanded : function(){
+ return this.expanded;
+ },
+
+
+ getUI : function(){
+ return this.ui;
+ },
+
+ getLoader : function(){
+ var owner;
+ return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
+ },
+
+
+ setFirstChild : function(node){
+ var of = this.firstChild;
+ Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
+ if(this.childrenRendered && of && node != of){
+ of.renderIndent(true, true);
+ }
+ if(this.rendered){
+ this.renderIndent(true, true);
+ }
+ },
+
+
+ setLastChild : function(node){
+ var ol = this.lastChild;
+ Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
+ if(this.childrenRendered && ol && node != ol){
+ ol.renderIndent(true, true);
+ }
+ if(this.rendered){
+ this.renderIndent(true, true);
+ }
+ },
+
+
+
+ appendChild : function(n){
+ if(!n.render && !Ext.isArray(n)){
+ n = this.getLoader().createNode(n);
+ }
+ var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
+ if(node && this.childrenRendered){
+ node.render();
+ }
+ this.ui.updateExpandIcon();
+ return node;
+ },
+
+
+ removeChild : function(node, destroy){
+ this.ownerTree.getSelectionModel().unselect(node);
+ Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
+
+ if(!destroy){
+ var rendered = node.ui.rendered;
+
+ if(rendered){
+ node.ui.remove();
+ }
+ if(rendered && this.childNodes.length < 1){
+ this.collapse(false, false);
+ }else{
+ this.ui.updateExpandIcon();
+ }
+ if(!this.firstChild && !this.isHiddenRoot()){
+ this.childrenRendered = false;
+ }
+ }
+ return node;
+ },
+
+
+ insertBefore : function(node, refNode){
+ if(!node.render){
+ node = this.getLoader().createNode(node);
+ }
+ var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
+ if(newNode && refNode && this.childrenRendered){
+ node.render();
+ }
+ this.ui.updateExpandIcon();
+ return newNode;
+ },
+
+
+ setText : function(text){
+ var oldText = this.text;
+ this.text = this.attributes.text = text;
+ if(this.rendered){
+ this.ui.onTextChange(this, text, oldText);
+ }
+ this.fireEvent('textchange', this, text, oldText);
+ },
+
+
+ setIconCls : function(cls){
+ var old = this.attributes.iconCls;
+ this.attributes.iconCls = cls;
+ if(this.rendered){
+ this.ui.onIconClsChange(this, cls, old);
+ }
+ },
+
+
+ setTooltip : function(tip, title){
+ this.attributes.qtip = tip;
+ this.attributes.qtipTitle = title;
+ if(this.rendered){
+ this.ui.onTipChange(this, tip, title);
+ }
+ },
+
+
+ setIcon : function(icon){
+ this.attributes.icon = icon;
+ if(this.rendered){
+ this.ui.onIconChange(this, icon);
+ }
+ },
+
+
+ setHref : function(href, target){
+ this.attributes.href = href;
+ this.attributes.hrefTarget = target;
+ if(this.rendered){
+ this.ui.onHrefChange(this, href, target);
+ }
+ },
+
+
+ setCls : function(cls){
+ var old = this.attributes.cls;
+ this.attributes.cls = cls;
+ if(this.rendered){
+ this.ui.onClsChange(this, cls, old);
+ }
+ },
+
+
+ select : function(){
+ var t = this.getOwnerTree();
+ if(t){
+ t.getSelectionModel().select(this);
+ }
+ },
+
+
+ unselect : function(silent){
+ var t = this.getOwnerTree();
+ if(t){
+ t.getSelectionModel().unselect(this, silent);
+ }
+ },
+
+
+ isSelected : function(){
+ var t = this.getOwnerTree();
+ return t ? t.getSelectionModel().isSelected(this) : false;
+ },
+
+
+ expand : function(deep, anim, callback, scope){
+ if(!this.expanded){
+ if(this.fireEvent('beforeexpand', this, deep, anim) === false){
+ return;
+ }
+ if(!this.childrenRendered){
+ this.renderChildren();
+ }
+ this.expanded = true;
+ if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
+ this.ui.animExpand(function(){
+ this.fireEvent('expand', this);
+ this.runCallback(callback, scope || this, [this]);
+ if(deep === true){
+ this.expandChildNodes(true, true);
+ }
+ }.createDelegate(this));
+ return;
+ }else{
+ this.ui.expand();
+ this.fireEvent('expand', this);
+ this.runCallback(callback, scope || this, [this]);
+ }
+ }else{
+ this.runCallback(callback, scope || this, [this]);
+ }
+ if(deep === true){
+ this.expandChildNodes(true);
+ }
+ },
+
+ runCallback : function(cb, scope, args){
+ if(Ext.isFunction(cb)){
+ cb.apply(scope, args);
+ }
+ },
+
+ isHiddenRoot : function(){
+ return this.isRoot && !this.getOwnerTree().rootVisible;
+ },
+
+
+ collapse : function(deep, anim, callback, scope){
+ if(this.expanded && !this.isHiddenRoot()){
+ if(this.fireEvent('beforecollapse', this, deep, anim) === false){
+ return;
+ }
+ this.expanded = false;
+ if((this.getOwnerTree().animate && anim !== false) || anim){
+ this.ui.animCollapse(function(){
+ this.fireEvent('collapse', this);
+ this.runCallback(callback, scope || this, [this]);
+ if(deep === true){
+ this.collapseChildNodes(true);
+ }
+ }.createDelegate(this));
+ return;
+ }else{
+ this.ui.collapse();
+ this.fireEvent('collapse', this);
+ this.runCallback(callback, scope || this, [this]);
+ }
+ }else if(!this.expanded){
+ this.runCallback(callback, scope || this, [this]);
+ }
+ if(deep === true){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].collapse(true, false);
+ }
+ }
+ },
+
+
+ delayedExpand : function(delay){
+ if(!this.expandProcId){
+ this.expandProcId = this.expand.defer(delay, this);
+ }
+ },
+
+
+ cancelExpand : function(){
+ if(this.expandProcId){
+ clearTimeout(this.expandProcId);
+ }
+ this.expandProcId = false;
+ },
+
+
+ toggle : function(){
+ if(this.expanded){
+ this.collapse();
+ }else{
+ this.expand();
+ }
+ },
+
+
+ ensureVisible : function(callback, scope){
+ var tree = this.getOwnerTree();
+ tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
+ var node = tree.getNodeById(this.id);
+ tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
+ this.runCallback(callback, scope || this, [this]);
+ }.createDelegate(this));
+ },
+
+
+ expandChildNodes : function(deep, anim) {
+ var cs = this.childNodes,
+ i,
+ len = cs.length;
+ for (i = 0; i < len; i++) {
+ cs[i].expand(deep, anim);
+ }
+ },
+
+
+ collapseChildNodes : function(deep){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].collapse(deep);
+ }
+ },
+
+
+ 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(suppressEvent){
+ if(suppressEvent !== 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, scope){
+ 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(bulkRender){
+ this.ui.render(bulkRender);
+ if(!this.rendered){
+
+ this.getOwnerTree().registerNode(this);
+ this.rendered = true;
+ if(this.expanded){
+ this.expanded = false;
+ this.expand(false, false);
+ }
+ }
+ },
+
+
+ renderIndent : function(deep, refresh){
+ if(refresh){
+ this.ui.childIndent = null;
+ }
+ this.ui.renderIndent();
+ if(deep === true && this.childrenRendered){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++){
+ cs[i].renderIndent(true, refresh);
+ }
+ }
+ },
+
+ beginUpdate : function(){
+ this.childrenRendered = false;
+ },
+
+ endUpdate : function(){
+ if(this.expanded && this.rendered){
+ this.renderChildren();
+ }
+ },
+
+
+ destroy : function(silent){
+ if(silent === true){
+ this.unselect(true);
+ }
+ Ext.tree.TreeNode.superclass.destroy.call(this, silent);
+ Ext.destroy(this.ui, this.loader);
+ this.ui = this.loader = null;
+ },
+
+
+ onIdChange : function(id){
+ this.ui.onIdChange(id);
+ }
+});
+
+Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
+ Ext.tree.AsyncTreeNode = function(config){
+ this.loaded = config && config.loaded === true;
+ this.loading = false;
+ Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
+
+ this.addEvents('beforeload', 'load');
+
+
+};
+Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
+ expand : function(deep, anim, callback, scope){
+ if(this.loading){
+ var timer;
+ var f = function(){
+ if(!this.loading){
+ clearInterval(timer);
+ this.expand(deep, anim, callback, scope);
+ }
+ }.createDelegate(this);
+ timer = setInterval(f, 200);
+ return;
+ }
+ if(!this.loaded){
+ if(this.fireEvent("beforeload", this) === false){
+ return;
+ }
+ this.loading = true;
+ this.ui.beforeLoad(this);
+ var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
+ if(loader){
+ loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
+ return;
+ }
+ }
+ Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
+ },
+
+
+ isLoading : function(){
+ return this.loading;
+ },
+
+ loadComplete : function(deep, anim, callback, scope){
+ this.loading = false;
+ this.loaded = true;
+ this.ui.afterLoad(this);
+ this.fireEvent("load", this);
+ this.expand(deep, anim, callback, scope);
+ },
+
+
+ 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(callback, scope){
+ this.collapse(false, false);
+ while(this.firstChild){
+ this.removeChild(this.firstChild).destroy();
+ }
+ this.childrenRendered = false;
+ this.loaded = false;
+ if(this.isHiddenRoot()){
+ this.expanded = false;
+ }
+ this.expand(false, false, callback, scope);
+ }
+});
+
+Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
+Ext.tree.TreeNodeUI = Ext.extend(Object, {
+
+ constructor : function(node){
+ Ext.apply(this, {
+ node: node,
+ rendered: false,
+ animating: false,
+ wasLeaf: true,
+ ecc: 'x-tree-ec-icon x-tree-elbow',
+ emptyIcon: Ext.BLANK_IMAGE_URL
+ });
+ },
+
+
+ removeChild : function(node){
+ if(this.rendered){
+ this.ctNode.removeChild(node.ui.getEl());
+ }
+ },
+
+
+ beforeLoad : function(){
+ this.addClass("x-tree-node-loading");
+ },
+
+
+ afterLoad : function(){
+ this.removeClass("x-tree-node-loading");
+ },
+
+
+ onTextChange : function(node, text, oldText){
+ if(this.rendered){
+ this.textNode.innerHTML = text;
+ }
+ },
+
+
+ onIconClsChange : function(node, cls, oldCls){
+ if(this.rendered){
+ Ext.fly(this.iconNode).replaceClass(oldCls, cls);
+ }
+ },
+
+
+ onIconChange : function(node, icon){
+ if(this.rendered){
+
+ var empty = Ext.isEmpty(icon);
+ this.iconNode.src = empty ? this.emptyIcon : icon;
+ Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
+ }
+ },
+
+
+ onTipChange : function(node, tip, title){
+ if(this.rendered){
+ var hasTitle = Ext.isDefined(title);
+ if(this.textNode.setAttributeNS){
+ this.textNode.setAttributeNS("ext", "qtip", tip);
+ if(hasTitle){
+ this.textNode.setAttributeNS("ext", "qtitle", title);
+ }
+ }else{
+ this.textNode.setAttribute("ext:qtip", tip);
+ if(hasTitle){
+ this.textNode.setAttribute("ext:qtitle", title);
+ }
+ }
+ }
+ },
+
+
+ onHrefChange : function(node, href, target){
+ if(this.rendered){
+ this.anchor.href = this.getHref(href);
+ if(Ext.isDefined(target)){
+ this.anchor.target = target;
+ }
+ }
+ },
+
+
+ onClsChange : function(node, cls, oldCls){
+ if(this.rendered){
+ Ext.fly(this.elNode).replaceClass(oldCls, cls);
+ }
+ },
+
+
+ onDisableChange : function(node, state){
+ this.disabled = state;
+ if (this.checkbox) {
+ this.checkbox.disabled = state;
+ }
+ this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
+ },
+
+
+ onSelectedChange : function(state){
+ if(state){
+ this.focus();
+ this.addClass("x-tree-selected");
+ }else{
+
+ this.removeClass("x-tree-selected");
+ }
+ },
+
+
+ onMove : function(tree, node, oldParent, newParent, index, refNode){
+ this.childIndent = null;
+ if(this.rendered){
+ var targetNode = newParent.ui.getContainer();
+ if(!targetNode){
+ this.holder = document.createElement("div");
+ this.holder.appendChild(this.wrap);
+ return;
+ }
+ var insertBefore = refNode ? refNode.ui.getEl() : null;
+ if(insertBefore){
+ targetNode.insertBefore(this.wrap, insertBefore);
+ }else{
+ targetNode.appendChild(this.wrap);
+ }
+ this.node.renderIndent(true, oldParent != newParent);
+ }
+ },
+
+
+ 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);
+
+ if(this.node.disabled){
+ this.onDisableChange(this.node, true);
+ }
+ if(this.node.hidden){
+ this.hide();
+ }
+ 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.getDDHandles(),
+ isHandle: false
+ });
+ }
+ },
+
+
+ getDDHandles : function(){
+ return [this.iconNode, this.textNode, this.elNode];
+ },
+
+
+ hide : function(){
+ this.node.hidden = true;
+ if(this.wrap){
+ this.wrap.style.display = "none";
+ }
+ },
+
+
+ show : function(){
+ this.node.hidden = false;
+ if(this.wrap){
+ this.wrap.style.display = "";
+ }
+ },
+
+
+ onContextMenu : function(e){
+ if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
+ e.preventDefault();
+ this.focus();
+ this.fireEvent("contextmenu", this.node, e);
+ }
+ },
+
+
+ onClick : function(e){
+ if(this.dropping){
+ e.stopEvent();
+ return;
+ }
+ if(this.fireEvent("beforeclick", this.node, e) !== false){
+ var a = e.getTarget('a');
+ if(!this.disabled && this.node.attributes.href && a){
+ this.fireEvent("click", this.node, e);
+ return;
+ }else if(a && e.ctrlKey){
+ e.stopEvent();
+ }
+ e.preventDefault();
+ if(this.disabled){
+ return;
+ }
+
+ if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
+ this.node.toggle();
+ }
+
+ this.fireEvent("click", this.node, e);
+ }else{
+ e.stopEvent();
+ }
+ },
+
+
+ onDblClick : function(e){
+ e.preventDefault();
+ if(this.disabled){
+ return;
+ }
+ if(this.fireEvent("beforedblclick", this.node, e) !== false){
+ if(this.checkbox){
+ this.toggleCheck();
+ }
+ if(!this.animating && this.node.isExpandable()){
+ this.node.toggle();
+ }
+ this.fireEvent("dblclick", this.node, e);
+ }
+ },
+
+ onOver : function(e){
+ this.addClass('x-tree-node-over');
+ },
+
+ onOut : function(e){
+ this.removeClass('x-tree-node-over');
+ },
+
+
+ onCheckChange : function(){
+ var checked = this.checkbox.checked;
+
+ this.checkbox.defaultChecked = checked;
+ this.node.attributes.checked = checked;
+ this.fireEvent('checkchange', this.node, checked);
+ },
+
+
+ ecClick : function(e){
+ if(!this.animating && this.node.isExpandable()){
+ 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{
+ try{
+ var noscroll = this.node.getOwnerTree().getTreeEl().dom;
+ var l = noscroll.scrollLeft;
+ this.anchor.focus();
+ noscroll.scrollLeft = l;
+ }catch(e){}
+ }
+ },
+
+
+ toggleCheck : function(value){
+ var cb = this.checkbox;
+ if(cb){
+ cb.checked = (value === undefined ? !cb.checked : value);
+ this.onCheckChange();
+ }
+ },
+
+
+ blur : function(){
+ try{
+ this.anchor.blur();
+ }catch(e){}
+ },
+
+
+ animExpand : function(callback){
+ var ct = Ext.get(this.ctNode);
+ ct.stopFx();
+ if(!this.node.isExpandable()){
+ this.updateExpandIcon();
+ this.ctNode.style.display = "";
+ Ext.callback(callback);
+ return;
+ }
+ this.animating = true;
+ this.updateExpandIcon();
+
+ ct.slideIn('t', {
+ callback : function(){
+ this.animating = false;
+ Ext.callback(callback);
+ },
+ scope: this,
+ duration: this.node.ownerTree.duration || .25
+ });
+ },
+
+
+ highlight : function(){
+ var tree = this.node.getOwnerTree();
+ Ext.fly(this.wrap).highlight(
+ tree.hlColor || "C3DAF9",
+ {endColor: tree.hlBaseColor}
+ );
+ },
+
+
+ collapse : function(){
+ this.updateExpandIcon();
+ this.ctNode.style.display = "none";
+ },
+
+
+ animCollapse : function(callback){
+ 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(callback);
+ },
+ scope: this,
+ duration: this.node.ownerTree.duration || .25
+ });
+ },
+
+
+ getContainer : function(){
+ return this.ctNode;
+ },
+
+
+ getEl : function(){
+ return this.wrap;
+ },
+
+
+ appendDDGhost : function(ghostNode){
+ ghostNode.appendChild(this.elNode.cloneNode(true));
+ },
+
+
+ getDDRepairXY : function(){
+ return Ext.lib.Dom.getXY(this.iconNode);
+ },
+
+
+ onRender : function(){
+ this.render();
+ },
+
+
+ render : function(bulkRender){
+ var n = this.node, a = n.attributes;
+ var targetNode = n.parentNode ?
+ n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
+
+ if(!this.rendered){
+ this.rendered = true;
+
+ this.renderElements(n, a, targetNode, bulkRender);
+
+ if(a.qtip){
+ this.onTipChange(n, a.qtip, a.qtipTitle);
+ }else if(a.qtipCfg){
+ a.qtipCfg.target = Ext.id(this.textNode);
+ Ext.QuickTips.register(a.qtipCfg);
+ }
+ this.initEvents();
+ if(!this.node.expanded){
+ this.updateExpandIcon(true);
+ }
+ }else{
+ if(bulkRender === true) {
+ targetNode.appendChild(this.wrap);
+ }
+ }
+ },
+
+
+ renderElements : function(n, a, targetNode, bulkRender){
+
+ this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
+
+ var cb = Ext.isBoolean(a.checked),
+ nel,
+ href = this.getHref(a.href),
+ buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
+ '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
+ '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
+ '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
+ cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
+ '<a hidefocus="on" class="x-tree-node-anchor" href="',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>"].join('');
+
+ if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
+ this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
+ }else{
+ this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
+ }
+
+ 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];
+ var index = 3;
+ if(cb){
+ this.checkbox = cs[3];
+
+ this.checkbox.defaultChecked = this.checkbox.checked;
+ index++;
+ }
+ this.anchor = cs[index];
+ this.textNode = cs[index].firstChild;
+ },
+
+
+ getHref : function(href){
+ return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
+ },
+
+
+ getAnchor : function(){
+ return this.anchor;
+ },
+
+
+ getTextEl : function(){
+ return this.textNode;
+ },
+
+
+ getIconEl : function(){
+ return this.iconNode;
+ },
+
+
+ isChecked : function(){
+ return this.checkbox ? this.checkbox.checked : false;
+ },
+
+
+ updateExpandIcon : function(){
+ if(this.rendered){
+ var n = this.node,
+ c1,
+ c2,
+ cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
+ hasChild = n.hasChildNodes();
+ if(hasChild || n.attributes.expandable){
+ 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-collapsed");
+ delete this.c1;
+ delete this.c2;
+ this.wasLeaf = true;
+ }
+ }
+ var ecc = "x-tree-ec-icon "+cls;
+ if(this.ecc != ecc){
+ this.ecNode.className = ecc;
+ this.ecc = ecc;
+ }
+ }
+ },
+
+
+ onIdChange: function(id){
+ if(this.rendered){
+ this.elNode.setAttribute('ext:tree-node-id', id);
+ }
+ },
+
+
+ getChildIndent : function(){
+ if(!this.childIndent){
+ var buf = [],
+ p = this.node;
+ while(p){
+ if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
+ if(!p.isLast()) {
+ buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
+ } else {
+ buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
+ }
+ }
+ p = p.parentNode;
+ }
+ this.childIndent = buf.join("");
+ }
+ return this.childIndent;
+ },
+
+
+ renderIndent : function(){
+ if(this.rendered){
+ var indent = "",
+ p = this.node.parentNode;
+ if(p){
+ indent = p.ui.getChildIndent();
+ }
+ if(this.indentMarkup != indent){
+ this.indentNode.innerHTML = indent;
+ this.indentMarkup = indent;
+ }
+ this.updateExpandIcon();
+ }
+ },
+
+ destroy : function(){
+ if(this.elNode){
+ Ext.dd.Registry.unregister(this.elNode.id);
+ }
+
+ Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
+ if(this[el]){
+ Ext.fly(this[el]).remove();
+ delete this[el];
+ }
+ }, this);
+ delete this.node;
+ }
+});
+
+
+Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+
+ render : function(){
+ if(!this.rendered){
+ var targetNode = this.node.ownerTree.innerCt.dom;
+ this.node.expanded = true;
+ targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
+ this.wrap = this.ctNode = targetNode.firstChild;
+ }
+ },
+ collapse : Ext.emptyFn,
+ expand : Ext.emptyFn
+});
+Ext.tree.TreeLoader = function(config){
+ this.baseParams = {};
+ Ext.apply(this, config);
+
+ this.addEvents(
+
+ "beforeload",
+
+ "load",
+
+ "loadexception"
+ );
+ Ext.tree.TreeLoader.superclass.constructor.call(this);
+ if(Ext.isString(this.paramOrder)){
+ this.paramOrder = this.paramOrder.split(/[\s,|]/);
+ }
+};
+
+Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
+
+
+
+
+
+
+
+ uiProviders : {},
+
+
+ clearOnLoad : true,
+
+
+ paramOrder: undefined,
+
+
+ paramsAsHash: false,
+
+
+ nodeParameter: 'node',
+
+
+ directFn : undefined,
+
+
+ load : function(node, callback, scope){
+ if(this.clearOnLoad){
+ while(node.firstChild){
+ node.removeChild(node.firstChild);
+ }
+ }
+ if(this.doPreload(node)){
+ this.runCallback(callback, scope || node, [node]);
+ }else if(this.directFn || this.dataUrl || this.url){
+ this.requestData(node, callback, scope || node);
+ }
+ },
+
+ doPreload : function(node){
+ if(node.attributes.children){
+ if(node.childNodes.length < 1){
+ var cs = node.attributes.children;
+ node.beginUpdate();
+ for(var i = 0, len = cs.length; i < len; i++){
+ var cn = node.appendChild(this.createNode(cs[i]));
+ if(this.preloadChildren){
+ this.doPreload(cn);
+ }
+ }
+ node.endUpdate();
+ }
+ return true;
+ }
+ return false;
+ },
+
+ getParams: function(node){
+ var bp = Ext.apply({}, this.baseParams),
+ np = this.nodeParameter,
+ po = this.paramOrder;
+
+ np && (bp[ np ] = node.id);
+
+ if(this.directFn){
+ var buf = [node.id];
+ if(po){
+
+ if(np && po.indexOf(np) > -1){
+ buf = [];
+ }
+
+ for(var i = 0, len = po.length; i < len; i++){
+ buf.push(bp[ po[i] ]);
+ }
+ }else if(this.paramsAsHash){
+ buf = [bp];
+ }
+ return buf;
+ }else{
+ return bp;
+ }
+ },
+
+ requestData : function(node, callback, scope){
+ if(this.fireEvent("beforeload", this, node, callback) !== false){
+ if(this.directFn){
+ var args = this.getParams(node);
+ args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
+ this.directFn.apply(window, args);
+ }else{
+ this.transId = Ext.Ajax.request({
+ method:this.requestMethod,
+ url: this.dataUrl||this.url,
+ success: this.handleResponse,
+ failure: this.handleFailure,
+ scope: this,
+ argument: {callback: callback, node: node, scope: scope},
+ params: this.getParams(node)
+ });
+ }
+ }else{
+
+
+ this.runCallback(callback, scope || node, []);
+ }
+ },
+
+ processDirectResponse: function(result, response, args){
+ if(response.status){
+ this.handleResponse({
+ responseData: Ext.isArray(result) ? result : null,
+ responseText: result,
+ argument: args
+ });
+ }else{
+ this.handleFailure({
+ argument: args
+ });
+ }
+ },
+
+
+ runCallback: function(cb, scope, args){
+ if(Ext.isFunction(cb)){
+ cb.apply(scope, args);
+ }
+ },
+
+ isLoading : function(){
+ return !!this.transId;
+ },
+
+ abort : function(){
+ if(this.isLoading()){
+ Ext.Ajax.abort(this.transId);
+ }
+ },
+
+
+ createNode : function(attr){
+
+ if(this.baseAttrs){
+ Ext.applyIf(attr, this.baseAttrs);
+ }
+ if(this.applyLoader !== false && !attr.loader){
+ attr.loader = this;
+ }
+ if(Ext.isString(attr.uiProvider)){
+ attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
+ }
+ if(attr.nodeType){
+ return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
+ }else{
+ return attr.leaf ?
+ new Ext.tree.TreeNode(attr) :
+ new Ext.tree.AsyncTreeNode(attr);
+ }
+ },
+
+ processResponse : function(response, node, callback, scope){
+ var json = response.responseText;
+ try {
+ var o = response.responseData || Ext.decode(json);
+ node.beginUpdate();
+ for(var i = 0, len = o.length; i < len; i++){
+ var n = this.createNode(o[i]);
+ if(n){
+ node.appendChild(n);
+ }
+ }
+ node.endUpdate();
+ this.runCallback(callback, scope || node, [node]);
+ }catch(e){
+ this.handleFailure(response);
+ }
+ },
+
+ handleResponse : function(response){
+ this.transId = false;
+ var a = response.argument;
+ this.processResponse(response, a.node, a.callback, a.scope);
+ this.fireEvent("load", this, a.node, response);
+ },
+
+ handleFailure : function(response){
+ this.transId = false;
+ var a = response.argument;
+ this.fireEvent("loadexception", this, a.node, response);
+ this.runCallback(a.callback, a.scope || a.node, [a.node]);
+ },
+
+ destroy : function(){
+ this.abort();
+ this.purgeListeners();
+ }
+});
+Ext.tree.TreeFilter = function(tree, config){
+ this.tree = tree;
+ this.filtered = {};
+ Ext.apply(this, config);
+};
+
+Ext.tree.TreeFilter.prototype = {
+ clearBlank:false,
+ reverse:false,
+ autoClear:false,
+ remove:false,
+
+
+ filter : function(value, attr, startNode){
+ attr = attr || "text";
+ var f;
+ if(typeof value == "string"){
+ var vlen = value.length;
+
+ if(vlen == 0 && this.clearBlank){
+ this.clear();
+ return;
+ }
+ value = value.toLowerCase();
+ f = function(n){
+ return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
+ };
+ }else if(value.exec){
+ f = function(n){
+ return value.test(n.attributes[attr]);
+ };
+ }else{
+ throw 'Illegal filter type, must be string or regex';
+ }
+ this.filterBy(f, null, startNode);
+ },
+
+
+ filterBy : function(fn, scope, startNode){
+ startNode = startNode || this.tree.root;
+ if(this.autoClear){
+ this.clear();
+ }
+ var af = this.filtered, rv = this.reverse;
+ var f = function(n){
+ if(n == startNode){
+ return true;
+ }
+ if(af[n.id]){
+ return false;
+ }
+ var m = fn.call(scope || n, n);
+ if(!m || rv){
+ af[n.id] = n;
+ n.ui.hide();
+ return false;
+ }
+ return true;
+ };
+ startNode.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 = Ext.extend(Object, {
+
+ constructor: function(tree, config){
+
+
+
+
+
+
+
+ Ext.apply(this, config);
+ tree.on({
+ scope: this,
+ beforechildrenrendered: this.doSort,
+ append: this.updateSort,
+ insert: this.updateSort,
+ textchange: this.updateSortParent
+ });
+
+ var desc = this.dir && this.dir.toLowerCase() == 'desc',
+ prop = this.property || 'text',
+ sortType = this.sortType,
+ folderSort = this.folderSort,
+ caseSensitive = this.caseSensitive === true,
+ leafAttr = this.leafAttr || 'leaf';
+
+ if(Ext.isString(sortType)){
+ sortType = Ext.data.SortTypes[sortType];
+ }
+ this.sortFn = function(n1, n2){
+ var attr1 = n1.attributes,
+ attr2 = n2.attributes;
+
+ if(folderSort){
+ if(attr1[leafAttr] && !attr2[leafAttr]){
+ return 1;
+ }
+ if(!attr1[leafAttr] && attr2[leafAttr]){
+ return -1;
+ }
+ }
+ var prop1 = attr1[prop],
+ prop2 = attr2[prop],
+ v1 = sortType ? sortType(prop1, n1) : (caseSensitive ? prop1 : prop1.toUpperCase()),
+ v2 = sortType ? sortType(prop2, n2) : (caseSensitive ? prop2 : prop2.toUpperCase());
+
+ if(v1 < v2){
+ return desc ? 1 : -1;
+ }else if(v1 > v2){
+ return desc ? -1 : 1;
+ }
+ return 0;
+ };
+ },
+
+ doSort : function(node){
+ node.sort(this.sortFn);
+ },
+
+ updateSort : function(tree, node){
+ if(node.childrenRendered){
+ this.doSort.defer(1, this, [node]);
+ }
+ },
+
+ updateSortParent : function(node){
+ var p = node.parentNode;
+ if(p && p.childrenRendered){
+ this.doSort.defer(1, this, [p]);
+ }
+ }
+});
+
+if(Ext.dd.DropZone){
+
+Ext.tree.TreeDropZone = function(tree, config){
+
+ this.allowParentInsert = config.allowParentInsert || false;
+
+ this.allowContainerDrop = config.allowContainerDrop || false;
+
+ this.appendOnly = config.appendOnly || false;
+
+ Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
+
+ this.tree = tree;
+
+ this.dragOverData = {};
+
+ this.lastInsertClass = "x-tree-no-status";
+};
+
+Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
+
+ ddGroup : "TreeDD",
+
+
+ expandDelay : 1000,
+
+
+ expandNode : function(node){
+ if(node.hasChildNodes() && !node.isExpanded()){
+ node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
+ }
+ },
+
+
+ queueExpand : function(node){
+ this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
+ },
+
+
+ cancelExpand : function(){
+ if(this.expandProcId){
+ clearTimeout(this.expandProcId);
+ this.expandProcId = false;
+ }
+ },
+
+
+ isValidDropPoint : function(n, pt, dd, e, data){
+ if(!n || !data){ return false; }
+ var targetNode = n.node;
+ var dropNode = data.node;
+
+ if(!(targetNode && targetNode.isTarget && pt)){
+ return false;
+ }
+ if(pt == "append" && targetNode.allowChildren === false){
+ return false;
+ }
+ if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
+ return false;
+ }
+ if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
+ return false;
+ }
+
+ var overEvent = this.dragOverData;
+ overEvent.tree = this.tree;
+ overEvent.target = targetNode;
+ overEvent.data = data;
+ overEvent.point = pt;
+ overEvent.source = dd;
+ overEvent.rawEvent = e;
+ overEvent.dropNode = dropNode;
+ overEvent.cancel = false;
+ var result = this.tree.fireEvent("nodedragover", overEvent);
+ return overEvent.cancel === false && result !== false;
+ },
+
+
+ getDropPoint : function(e, n, dd){
+ var tn = n.node;
+ if(tn.isRoot){
+ return tn.allowChildren !== false ? "append" : false;
+ }
+ var dragEl = n.ddel;
+ var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
+ var y = Ext.lib.Event.getPageY(e);
+ var noAppend = tn.allowChildren === false || tn.isLeaf();
+ if(this.appendOnly || tn.parentNode.allowChildren === false){
+ return noAppend ? false : "append";
+ }
+ var noBelow = false;
+ if(!this.allowParentInsert){
+ noBelow = tn.hasChildNodes() && tn.isExpanded();
+ }
+ var q = (b - t) / (noAppend ? 2 : 3);
+ if(y >= t && y < (t + q)){
+ return "above";
+ }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
+ return "below";
+ }else{
+ return "append";
+ }
+ },
+
+
+ onNodeEnter : function(n, dd, e, data){
+ this.cancelExpand();
+ },
+
+ onContainerOver : function(dd, e, data) {
+ if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
+ return this.dropAllowed;
+ }
+ return this.dropNotAllowed;
+ },
+
+
+ onNodeOver : function(n, dd, e, data){
+ var pt = this.getDropPoint(e, n, dd);
+ var node = n.node;
+
+
+ if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
+ this.queueExpand(node);
+ }else if(pt != "append"){
+ this.cancelExpand();
+ }
+
+
+ var returnCls = this.dropNotAllowed;
+ if(this.isValidDropPoint(n, pt, dd, e, data)){
+ if(pt){
+ var el = n.ddel;
+ var cls;
+ if(pt == "above"){
+ returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
+ cls = "x-tree-drag-insert-above";
+ }else if(pt == "below"){
+ returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
+ cls = "x-tree-drag-insert-below";
+ }else{
+ returnCls = "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 returnCls;
+ },
+
+
+ onNodeOut : function(n, dd, e, data){
+ this.cancelExpand();
+ this.removeDropIndicators(n);
+ },
+
+
+ onNodeDrop : function(n, dd, e, data){
+ var point = this.getDropPoint(e, n, dd);
+ var targetNode = n.node;
+ targetNode.ui.startDrop();
+ if(!this.isValidDropPoint(n, point, dd, e, data)){
+ targetNode.ui.endDrop();
+ return false;
+ }
+
+ var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
+ return this.processDrop(targetNode, data, point, dd, e, dropNode);
+ },
+
+ onContainerDrop : function(dd, e, data){
+ if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
+ var targetNode = this.tree.getRootNode();
+ targetNode.ui.startDrop();
+ var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
+ return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
+ }
+ return false;
+ },
+
+
+ processDrop: function(target, data, point, dd, e, dropNode){
+ var dropEvent = {
+ tree : this.tree,
+ target: target,
+ data: data,
+ point: point,
+ source: dd,
+ rawEvent: e,
+ dropNode: dropNode,
+ cancel: !dropNode,
+ dropStatus: false
+ };
+ var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
+ if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
+ target.ui.endDrop();
+ return dropEvent.dropStatus;
+ }
+
+ target = dropEvent.target;
+ if(point == 'append' && !target.isExpanded()){
+ target.expand(false, null, function(){
+ this.completeDrop(dropEvent);
+ }.createDelegate(this));
+ }else{
+ this.completeDrop(dropEvent);
+ }
+ return true;
+ },
+
+
+ completeDrop : function(de){
+ var ns = de.dropNode, p = de.point, t = de.target;
+ if(!Ext.isArray(ns)){
+ 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(Ext.enableFx && this.tree.hlDrop){
+ n.ui.highlight();
+ }
+ t.ui.endDrop();
+ this.tree.fireEvent("nodedrop", de);
+ },
+
+
+ afterNodeMoved : function(dd, data, e, targetNode, dropNode){
+ if(Ext.enableFx && this.tree.hlDrop){
+ dropNode.ui.focus();
+ dropNode.ui.highlight();
+ }
+ this.tree.fireEvent("nodedrop", this.tree, targetNode, data, 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(target, e, id){
+ this.cancelExpand();
+ return true;
+ },
+
+
+ afterRepair : function(data){
+ if(data && Ext.enableFx){
+ data.node.ui.highlight();
+ }
+ this.hideProxy();
+ }
+});
+
+}
+if(Ext.dd.DragZone){
+Ext.tree.TreeDragZone = function(tree, config){
+ Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
+
+ this.tree = tree;
+};
+
+Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
+
+ ddGroup : "TreeDD",
+
+
+ onBeforeDrag : function(data, e){
+ var n = data.node;
+ return n && n.draggable && !n.disabled;
+ },
+
+
+ onInitDrag : function(e){
+ var data = this.dragData;
+ this.tree.getSelectionModel().select(data.node);
+ this.tree.eventModel.disable();
+ this.proxy.update("");
+ data.node.ui.appendDDGhost(this.proxy.ghost.dom);
+ this.tree.fireEvent("startdrag", this.tree, data.node, e);
+ },
+
+
+ getRepairXY : function(e, data){
+ return data.node.ui.getDDRepairXY();
+ },
+
+
+ onEndDrag : function(data, e){
+ this.tree.eventModel.enable.defer(100, this.tree.eventModel);
+ this.tree.fireEvent("enddrag", this.tree, data.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);
+ },
+
+
+ afterRepair : function(){
+ if (Ext.enableFx && this.tree.hlDrop) {
+ Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
+ }
+ this.dragging = false;
+ }
+});
+}
+Ext.tree.TreeEditor = function(tree, fc, config){
+ fc = fc || {};
+ var field = fc.events ? fc : new Ext.form.TextField(fc);
+
+ Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
+
+ this.tree = tree;
+
+ if(!tree.rendered){
+ tree.on('render', this.initEditor, this);
+ }else{
+ this.initEditor(tree);
+ }
+};
+
+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,
+
+ editDelay : 350,
+
+ initEditor : function(tree){
+ tree.on({
+ scope : this,
+ beforeclick: this.beforeNodeClick,
+ dblclick : this.onNodeDblClick
+ });
+
+ this.on({
+ scope : this,
+ complete : this.updateNode,
+ beforestartedit: this.fitToTree,
+ specialkey : this.onSpecialKey
+ });
+
+ this.on('startedit', this.bindScroll, this, {delay:10});
+ },
+
+
+ fitToTree : function(ed, el){
+ var td = this.tree.getTreeEl().dom, nd = el.dom;
+ if(td.scrollLeft > nd.offsetLeft){
+ td.scrollLeft = nd.offsetLeft;
+ }
+ var w = Math.min(
+ this.maxWidth,
+ (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
+ this.setSize(w, '');
+ },
+
+
+ triggerEdit : function(node, defer){
+ this.completeEdit();
+ if(node.attributes.editable !== false){
+
+ this.editNode = node;
+ if(this.tree.autoScroll){
+ Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
+ }
+ var value = node.text || '';
+ if (!Ext.isGecko && Ext.isEmpty(node.text)){
+ node.setText('&#160;');
+ }
+ this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
+ return false;
+ }
+ },
+
+
+ bindScroll : function(){
+ this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
+ },
+
+
+ beforeNodeClick : function(node, e){
+ clearTimeout(this.autoEditTimer);
+ if(this.tree.getSelectionModel().isSelected(node)){
+ e.stopEvent();
+ return this.triggerEdit(node);
+ }
+ },
+
+ onNodeDblClick : function(node, e){
+ clearTimeout(this.autoEditTimer);
+ },
+
+
+ updateNode : function(ed, value){
+ this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
+ this.editNode.setText(value);
+ },
+
+
+ onHide : function(){
+ Ext.tree.TreeEditor.superclass.onHide.call(this);
+ if(this.editNode){
+ this.editNode.ui.focus.defer(50, this.editNode.ui);
+ }
+ },
+
+
+ onSpecialKey : function(field, e){
+ var k = e.getKey();
+ if(k == e.ESC){
+ e.stopEvent();
+ this.cancelEdit();
+ }else if(k == e.ENTER && !e.hasModifier()){
+ e.stopEvent();
+ this.completeEdit();
+ }
+ },
+
+ onDestroy : function(){
+ clearTimeout(this.autoEditTimer);
+ Ext.tree.TreeEditor.superclass.onDestroy.call(this);
+ var tree = this.tree;
+ tree.un('beforeclick', this.beforeNodeClick, this);
+ tree.un('dblclick', this.onNodeDblClick, this);
+ }
+});
+
+var swfobject = function() {
+
+ var UNDEF = "undefined",
+ OBJECT = "object",
+ SHOCKWAVE_FLASH = "Shockwave Flash",
+ SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
+ FLASH_MIME_TYPE = "application/x-shockwave-flash",
+ EXPRESS_INSTALL_ID = "SWFObjectExprInst",
+ ON_READY_STATE_CHANGE = "onreadystatechange",
+
+ win = window,
+ doc = document,
+ nav = navigator,
+
+ plugin = false,
+ domLoadFnArr = [main],
+ regObjArr = [],
+ objIdArr = [],
+ listenersArr = [],
+ storedAltContent,
+ storedAltContentId,
+ storedCallbackFn,
+ storedCallbackObj,
+ isDomLoaded = false,
+ isExpressInstallActive = false,
+ dynamicStylesheet,
+ dynamicStylesheetMedia,
+ autoHideShow = true,
+
+
+ ua = function() {
+ var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
+ u = nav.userAgent.toLowerCase(),
+ p = nav.platform.toLowerCase(),
+ windows = p ? (/win/).test(p) : /win/.test(u),
+ mac = p ? (/mac/).test(p) : /mac/.test(u),
+ webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
+ ie = !+"\v1",
+ playerVersion = [0,0,0],
+ d = null;
+ if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
+ d = nav.plugins[SHOCKWAVE_FLASH].description;
+ if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
+ plugin = true;
+ ie = false;
+ d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
+ playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
+ playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
+ playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
+ }
+ }
+ else if (typeof win.ActiveXObject != UNDEF) {
+ try {
+ var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
+ if (a) {
+ d = a.GetVariable("$version");
+ if (d) {
+ ie = true;
+ d = d.split(" ")[1].split(",");
+ playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ }
+ catch(e) {}
+ }
+ return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
+ }(),
+
+
+ onDomLoad = function() {
+ if (!ua.w3) { return; }
+ if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
+ callDomLoadFunctions();
+ }
+ if (!isDomLoaded) {
+ if (typeof doc.addEventListener != UNDEF) {
+ doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
+ }
+ if (ua.ie && ua.win) {
+ doc.attachEvent(ON_READY_STATE_CHANGE, function() {
+ if (doc.readyState == "complete") {
+ doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
+ callDomLoadFunctions();
+ }
+ });
+ if (win == top) {
+ (function(){
+ if (isDomLoaded) { return; }
+ try {
+ doc.documentElement.doScroll("left");
+ }
+ catch(e) {
+ setTimeout(arguments.callee, 0);
+ return;
+ }
+ callDomLoadFunctions();
+ })();
+ }
+ }
+ if (ua.wk) {
+ (function(){
+ if (isDomLoaded) { return; }
+ if (!(/loaded|complete/).test(doc.readyState)) {
+ setTimeout(arguments.callee, 0);
+ return;
+ }
+ callDomLoadFunctions();
+ })();
+ }
+ addLoadEvent(callDomLoadFunctions);
+ }
+ }();
+
+ function callDomLoadFunctions() {
+ if (isDomLoaded) { return; }
+ try {
+ var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
+ t.parentNode.removeChild(t);
+ }
+ catch (e) { return; }
+ isDomLoaded = true;
+ var dl = domLoadFnArr.length;
+ for (var i = 0; i < dl; i++) {
+ domLoadFnArr[i]();
+ }
+ }
+
+ function addDomLoadEvent(fn) {
+ if (isDomLoaded) {
+ fn();
+ }
+ else {
+ domLoadFnArr[domLoadFnArr.length] = fn;
+ }
+ }
+
+
+ function addLoadEvent(fn) {
+ if (typeof win.addEventListener != UNDEF) {
+ win.addEventListener("load", fn, false);
+ }
+ else if (typeof doc.addEventListener != UNDEF) {
+ doc.addEventListener("load", fn, false);
+ }
+ else if (typeof win.attachEvent != UNDEF) {
+ addListener(win, "onload", fn);
+ }
+ else if (typeof win.onload == "function") {
+ var fnOld = win.onload;
+ win.onload = function() {
+ fnOld();
+ fn();
+ };
+ }
+ else {
+ win.onload = fn;
+ }
+ }
+
+
+ function main() {
+ //~ if (plugin) {
+ //~ testPlayerVersion();
+ //~ }
+ //~ else {
+ matchVersions();
+ //~ }
+ }
+
+
+ function testPlayerVersion() {
+ var b = doc.getElementsByTagName("body")[0];
+ var o = createElement(OBJECT);
+ o.setAttribute("type", FLASH_MIME_TYPE);
+ var t = b.appendChild(o);
+ if (t) {
+ var counter = 0;
+ (function(){
+ if (typeof t.GetVariable != UNDEF) {
+ var d = t.GetVariable("$version");
+ if (d) {
+ d = d.split(" ")[1].split(",");
+ ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ else if (counter < 10) {
+ counter++;
+ setTimeout(arguments.callee, 10);
+ return;
+ }
+ b.removeChild(o);
+ t = null;
+ matchVersions();
+ })();
+ }
+ else {
+ matchVersions();
+ }
+ }
+
+
+ function matchVersions() {
+ var rl = regObjArr.length;
+ if (rl > 0) {
+ for (var i = 0; i < rl; i++) {
+ var id = regObjArr[i].id;
+ var cb = regObjArr[i].callbackFn;
+ var cbObj = {success:false, id:id};
+ if (ua.pv[0] > 0) {
+ var obj = getElementById(id);
+ if (obj) {
+ if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
+ setVisibility(id, true);
+ if (cb) {
+ cbObj.success = true;
+ cbObj.ref = getObjectById(id);
+ cb(cbObj);
+ }
+ }
+ else if (regObjArr[i].expressInstall && canExpressInstall()) {
+ var att = {};
+ att.data = regObjArr[i].expressInstall;
+ att.width = obj.getAttribute("width") || "0";
+ att.height = obj.getAttribute("height") || "0";
+ if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
+ if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
+
+ var par = {};
+ var p = obj.getElementsByTagName("param");
+ var pl = p.length;
+ for (var j = 0; j < pl; j++) {
+ if (p[j].getAttribute("name").toLowerCase() != "movie") {
+ par[p[j].getAttribute("name")] = p[j].getAttribute("value");
+ }
+ }
+ showExpressInstall(att, par, id, cb);
+ }
+ else {
+ displayAltContent(obj);
+ if (cb) { cb(cbObj); }
+ }
+ }
+ }
+ else {
+ setVisibility(id, true);
+ if (cb) {
+ var o = getObjectById(id);
+ if (o && typeof o.SetVariable != UNDEF) {
+ cbObj.success = true;
+ cbObj.ref = o;
+ }
+ cb(cbObj);
+ }
+ }
+ }
+ }
+ }
+
+ function getObjectById(objectIdStr) {
+ var r = null;
+ var o = getElementById(objectIdStr);
+ if (o && o.nodeName == "OBJECT") {
+ if (typeof o.SetVariable != UNDEF) {
+ r = o;
+ }
+ else {
+ var n = o.getElementsByTagName(OBJECT)[0];
+ if (n) {
+ r = n;
+ }
+ }
+ }
+ return r;
+ }
+
+
+ function canExpressInstall() {
+ return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
+ }
+
+
+ function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
+ isExpressInstallActive = true;
+ storedCallbackFn = callbackFn || null;
+ storedCallbackObj = {success:false, id:replaceElemIdStr};
+ var obj = getElementById(replaceElemIdStr);
+ if (obj) {
+ if (obj.nodeName == "OBJECT") {
+ storedAltContent = abstractAltContent(obj);
+ storedAltContentId = null;
+ }
+ else {
+ storedAltContent = obj;
+ storedAltContentId = replaceElemIdStr;
+ }
+ att.id = EXPRESS_INSTALL_ID;
+ if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
+ att.width = "310";
+ }
+
+ if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
+ att.height = "137";
+ }
+ doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
+ var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
+ fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
+ if (typeof par.flashvars != UNDEF) {
+ par.flashvars += "&" + fv;
+ }
+ else {
+ par.flashvars = fv;
+ }
+
+
+ if (ua.ie && ua.win && obj.readyState != 4) {
+ var newObj = createElement("div");
+ replaceElemIdStr += "SWFObjectNew";
+ newObj.setAttribute("id", replaceElemIdStr);
+ obj.parentNode.insertBefore(newObj, obj);
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ obj.parentNode.removeChild(obj);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ createSWF(att, par, replaceElemIdStr);
+ }
+ }
+
+
+ function displayAltContent(obj) {
+ if (ua.ie && ua.win && obj.readyState != 4) {
+
+
+ var el = createElement("div");
+ obj.parentNode.insertBefore(el, obj);
+ el.parentNode.replaceChild(abstractAltContent(obj), el);
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ obj.parentNode.removeChild(obj);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ else {
+ obj.parentNode.replaceChild(abstractAltContent(obj), obj);
+ }
+ }
+
+ function abstractAltContent(obj) {
+ var ac = createElement("div");
+ if (ua.win && ua.ie) {
+ ac.innerHTML = obj.innerHTML;
+ }
+ else {
+ var nestedObj = obj.getElementsByTagName(OBJECT)[0];
+ if (nestedObj) {
+ var c = nestedObj.childNodes;
+ if (c) {
+ var cl = c.length;
+ for (var i = 0; i < cl; i++) {
+ if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
+ ac.appendChild(c[i].cloneNode(true));
+ }
+ }
+ }
+ }
+ }
+ return ac;
+ }
+
+
+ function createSWF(attObj, parObj, id) {
+ var r, el = getElementById(id);
+ if (ua.wk && ua.wk < 312) { return r; }
+ if (el) {
+ if (typeof attObj.id == UNDEF) {
+ attObj.id = id;
+ }
+ if (ua.ie && ua.win) {
+ var att = "";
+ for (var i in attObj) {
+ if (attObj[i] != Object.prototype[i]) {
+ if (i.toLowerCase() == "data") {
+ parObj.movie = attObj[i];
+ }
+ else if (i.toLowerCase() == "styleclass") {
+ att += ' class="' + attObj[i] + '"';
+ }
+ else if (i.toLowerCase() != "classid") {
+ att += ' ' + i + '="' + attObj[i] + '"';
+ }
+ }
+ }
+ var par = "";
+ for (var j in parObj) {
+ if (parObj[j] != Object.prototype[j]) {
+ par += '<param name="' + j + '" value="' + parObj[j] + '" />';
+ }
+ }
+ el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
+ objIdArr[objIdArr.length] = attObj.id;
+ r = getElementById(attObj.id);
+ }
+ else {
+ var o = createElement(OBJECT);
+ o.setAttribute("type", FLASH_MIME_TYPE);
+ for (var m in attObj) {
+ if (attObj[m] != Object.prototype[m]) {
+ if (m.toLowerCase() == "styleclass") {
+ o.setAttribute("class", attObj[m]);
+ }
+ else if (m.toLowerCase() != "classid") {
+ o.setAttribute(m, attObj[m]);
+ }
+ }
+ }
+ for (var n in parObj) {
+ if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
+ createObjParam(o, n, parObj[n]);
+ }
+ }
+ el.parentNode.replaceChild(o, el);
+ r = o;
+ }
+ }
+ return r;
+ }
+
+ function createObjParam(el, pName, pValue) {
+ var p = createElement("param");
+ p.setAttribute("name", pName);
+ p.setAttribute("value", pValue);
+ el.appendChild(p);
+ }
+
+
+ function removeSWF(id) {
+ var obj = getElementById(id);
+ if (obj && obj.nodeName == "OBJECT") {
+ if (ua.ie && ua.win) {
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ removeObjectInIE(id);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ else {
+ obj.parentNode.removeChild(obj);
+ }
+ }
+ }
+
+ function removeObjectInIE(id) {
+ var obj = getElementById(id);
+ if (obj) {
+ for (var i in obj) {
+ if (typeof obj[i] == "function") {
+ obj[i] = null;
+ }
+ }
+ obj.parentNode.removeChild(obj);
+ }
+ }
+
+
+ function getElementById(id) {
+ var el = null;
+ try {
+ el = doc.getElementById(id);
+ }
+ catch (e) {}
+ return el;
+ }
+
+ function createElement(el) {
+ return doc.createElement(el);
+ }
+
+
+ function addListener(target, eventType, fn) {
+ target.attachEvent(eventType, fn);
+ listenersArr[listenersArr.length] = [target, eventType, fn];
+ }
+
+
+ function hasPlayerVersion(rv) {
+ var pv = ua.pv, v = rv.split(".");
+ v[0] = parseInt(v[0], 10);
+ v[1] = parseInt(v[1], 10) || 0;
+ v[2] = parseInt(v[2], 10) || 0;
+ return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
+ }
+
+
+ function createCSS(sel, decl, media, newStyle) {
+ if (ua.ie && ua.mac) { return; }
+ var h = doc.getElementsByTagName("head")[0];
+ if (!h) { return; }
+ var m = (media && typeof media == "string") ? media : "screen";
+ if (newStyle) {
+ dynamicStylesheet = null;
+ dynamicStylesheetMedia = null;
+ }
+ if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
+
+ var s = createElement("style");
+ s.setAttribute("type", "text/css");
+ s.setAttribute("media", m);
+ dynamicStylesheet = h.appendChild(s);
+ if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
+ dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
+ }
+ dynamicStylesheetMedia = m;
+ }
+
+ if (ua.ie && ua.win) {
+ if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
+ dynamicStylesheet.addRule(sel, decl);
+ }
+ }
+ else {
+ if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
+ dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
+ }
+ }
+ }
+
+ function setVisibility(id, isVisible) {
+ if (!autoHideShow) { return; }
+ var v = isVisible ? "visible" : "hidden";
+ if (isDomLoaded && getElementById(id)) {
+ getElementById(id).style.visibility = v;
+ }
+ else {
+ createCSS("#" + id, "visibility:" + v);
+ }
+ }
+
+
+ function urlEncodeIfNecessary(s) {
+ var regex = /[\\\"<>\.;]/;
+ var hasBadChars = regex.exec(s) != null;
+ return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
+ }
+
+
+ var cleanup = function() {
+ if (ua.ie && ua.win) {
+ window.attachEvent("onunload", function() {
+
+ var ll = listenersArr.length;
+ for (var i = 0; i < ll; i++) {
+ listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
+ }
+
+ var il = objIdArr.length;
+ for (var j = 0; j < il; j++) {
+ removeSWF(objIdArr[j]);
+ }
+
+ for (var k in ua) {
+ ua[k] = null;
+ }
+ ua = null;
+ for (var l in swfobject) {
+ swfobject[l] = null;
+ }
+ swfobject = null;
+ window.detachEvent('onunload', arguments.callee);
+ });
+ }
+ }();
+
+ return {
+
+ registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
+ if (ua.w3 && objectIdStr && swfVersionStr) {
+ var regObj = {};
+ regObj.id = objectIdStr;
+ regObj.swfVersion = swfVersionStr;
+ regObj.expressInstall = xiSwfUrlStr;
+ regObj.callbackFn = callbackFn;
+ regObjArr[regObjArr.length] = regObj;
+ setVisibility(objectIdStr, false);
+ }
+ else if (callbackFn) {
+ callbackFn({success:false, id:objectIdStr});
+ }
+ },
+
+ getObjectById: function(objectIdStr) {
+ if (ua.w3) {
+ return getObjectById(objectIdStr);
+ }
+ },
+
+ embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
+ var callbackObj = {success:false, id:replaceElemIdStr};
+ if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
+ setVisibility(replaceElemIdStr, false);
+ addDomLoadEvent(function() {
+ widthStr += "";
+ heightStr += "";
+ var att = {};
+ if (attObj && typeof attObj === OBJECT) {
+ for (var i in attObj) {
+ att[i] = attObj[i];
+ }
+ }
+ att.data = swfUrlStr;
+ att.width = widthStr;
+ att.height = heightStr;
+ var par = {};
+ if (parObj && typeof parObj === OBJECT) {
+ for (var j in parObj) {
+ par[j] = parObj[j];
+ }
+ }
+ if (flashvarsObj && typeof flashvarsObj === OBJECT) {
+ for (var k in flashvarsObj) {
+ if (typeof par.flashvars != UNDEF) {
+ par.flashvars += "&" + k + "=" + flashvarsObj[k];
+ }
+ else {
+ par.flashvars = k + "=" + flashvarsObj[k];
+ }
+ }
+ }
+ if (hasPlayerVersion(swfVersionStr)) {
+ var obj = createSWF(att, par, replaceElemIdStr);
+ if (att.id == replaceElemIdStr) {
+ setVisibility(replaceElemIdStr, true);
+ }
+ callbackObj.success = true;
+ callbackObj.ref = obj;
+ }
+ else if (xiSwfUrlStr && canExpressInstall()) {
+ att.data = xiSwfUrlStr;
+ showExpressInstall(att, par, replaceElemIdStr, callbackFn);
+ return;
+ }
+ else {
+ setVisibility(replaceElemIdStr, true);
+ }
+ if (callbackFn) { callbackFn(callbackObj); }
+ });
+ }
+ else if (callbackFn) { callbackFn(callbackObj); }
+ },
+
+ switchOffAutoHideShow: function() {
+ autoHideShow = false;
+ },
+
+ ua: ua,
+
+ getFlashPlayerVersion: function() {
+ return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
+ },
+
+ hasFlashPlayerVersion: hasPlayerVersion,
+
+ createSWF: function(attObj, parObj, replaceElemIdStr) {
+ if (ua.w3) {
+ return createSWF(attObj, parObj, replaceElemIdStr);
+ }
+ else {
+ return undefined;
+ }
+ },
+
+ showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
+ if (ua.w3 && canExpressInstall()) {
+ showExpressInstall(att, par, replaceElemIdStr, callbackFn);
+ }
+ },
+
+ removeSWF: function(objElemIdStr) {
+ if (ua.w3) {
+ removeSWF(objElemIdStr);
+ }
+ },
+
+ createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
+ if (ua.w3) {
+ createCSS(selStr, declStr, mediaStr, newStyleBoolean);
+ }
+ },
+
+ addDomLoadEvent: addDomLoadEvent,
+
+ addLoadEvent: addLoadEvent,
+
+ getQueryParamValue: function(param) {
+ var q = doc.location.search || doc.location.hash;
+ if (q) {
+ if (/\?/.test(q)) { q = q.split("?")[1]; }
+ if (param == null) {
+ return urlEncodeIfNecessary(q);
+ }
+ var pairs = q.split("&");
+ for (var i = 0; i < pairs.length; i++) {
+ if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
+ return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
+ }
+ }
+ }
+ return "";
+ },
+
+
+ expressInstallCallback: function() {
+ if (isExpressInstallActive) {
+ var obj = getElementById(EXPRESS_INSTALL_ID);
+ if (obj && storedAltContent) {
+ obj.parentNode.replaceChild(storedAltContent, obj);
+ if (storedAltContentId) {
+ setVisibility(storedAltContentId, true);
+ if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
+ }
+ if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
+ }
+ isExpressInstallActive = false;
+ }
+ }
+ };
+}();
+
+Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
+
+ flashVersion : '9.0.115',
+
+
+ backgroundColor: '#ffffff',
+
+
+ wmode: 'opaque',
+
+
+ flashVars: undefined,
+
+
+ flashParams: undefined,
+
+
+ url: undefined,
+ swfId : undefined,
+ swfWidth: '100%',
+ swfHeight: '100%',
+
+
+ expressInstall: false,
+
+ initComponent : function(){
+ Ext.FlashComponent.superclass.initComponent.call(this);
+
+ this.addEvents(
+
+ 'initialize'
+ );
+ },
+
+ onRender : function(){
+ Ext.FlashComponent.superclass.onRender.apply(this, arguments);
+
+ var params = Ext.apply({
+ allowScriptAccess: 'always',
+ bgcolor: this.backgroundColor,
+ wmode: this.wmode
+ }, this.flashParams), vars = Ext.apply({
+ allowedDomain: document.location.hostname,
+ YUISwfId: this.getId(),
+ YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
+ }, this.flashVars);
+
+ new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
+ this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
+
+ this.swf = Ext.getDom(this.id);
+ this.el = Ext.get(this.swf);
+ },
+
+ getSwfId : function(){
+ return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
+ },
+
+ getId : function(){
+ return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
+ },
+
+ onFlashEvent : function(e){
+ switch(e.type){
+ case "swfReady":
+ this.initSwf();
+ return;
+ case "log":
+ return;
+ }
+ e.component = this;
+ this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
+ },
+
+ initSwf : function(){
+ this.onSwfReady(!!this.isInitialized);
+ this.isInitialized = true;
+ this.fireEvent('initialize', this);
+ },
+
+ beforeDestroy: function(){
+ if(this.rendered){
+ swfobject.removeSWF(this.swf.id);
+ }
+ Ext.FlashComponent.superclass.beforeDestroy.call(this);
+ },
+
+ onSwfReady : Ext.emptyFn
+});
+
+
+Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
+
+Ext.reg('flash', Ext.FlashComponent);
+Ext.FlashEventProxy = {
+ onEvent : function(id, e){
+ var fp = Ext.getCmp(id);
+ if(fp){
+ fp.onFlashEvent(e);
+ }else{
+ arguments.callee.defer(10, this, [id, e]);
+ }
+ }
+};
+
+ Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
+ refreshBuffer: 100,
+
+
+
+
+ chartStyle: {
+ padding: 10,
+ animationEnabled: true,
+ font: {
+ name: 'Tahoma',
+ color: 0x444444,
+ size: 11
+ },
+ dataTip: {
+ padding: 5,
+ border: {
+ color: 0x99bbe8,
+ size:1
+ },
+ background: {
+ color: 0xDAE7F6,
+ alpha: .9
+ },
+ font: {
+ name: 'Tahoma',
+ color: 0x15428B,
+ size: 10,
+ bold: true
+ }
+ }
+ },
+
+
+
+
+ extraStyle: null,
+
+
+ seriesStyles: null,
+
+
+ disableCaching: Ext.isIE || Ext.isOpera,
+ disableCacheParam: '_dc',
+
+ initComponent : function(){
+ Ext.chart.Chart.superclass.initComponent.call(this);
+ if(!this.url){
+ this.url = Ext.chart.Chart.CHART_URL;
+ }
+ if(this.disableCaching){
+ this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
+ }
+ this.addEvents(
+ 'itemmouseover',
+ 'itemmouseout',
+ 'itemclick',
+ 'itemdoubleclick',
+ 'itemdragstart',
+ 'itemdrag',
+ 'itemdragend',
+
+ 'beforerefresh',
+
+ 'refresh'
+ );
+ this.store = Ext.StoreMgr.lookup(this.store);
+ },
+
+
+ setStyle: function(name, value){
+ this.swf.setStyle(name, Ext.encode(value));
+ },
+
+
+ setStyles: function(styles){
+ this.swf.setStyles(Ext.encode(styles));
+ },
+
+
+ setSeriesStyles: function(styles){
+ this.seriesStyles = styles;
+ var s = [];
+ Ext.each(styles, function(style){
+ s.push(Ext.encode(style));
+ });
+ this.swf.setSeriesStyles(s);
+ },
+
+ setCategoryNames : function(names){
+ this.swf.setCategoryNames(names);
+ },
+
+ setLegendRenderer : function(fn, scope){
+ var chart = this;
+ scope = scope || chart;
+ chart.removeFnProxy(chart.legendFnName);
+ chart.legendFnName = chart.createFnProxy(function(name){
+ return fn.call(scope, name);
+ });
+ chart.swf.setLegendLabelFunction(chart.legendFnName);
+ },
+
+ setTipRenderer : function(fn, scope){
+ var chart = this;
+ scope = scope || chart;
+ chart.removeFnProxy(chart.tipFnName);
+ chart.tipFnName = chart.createFnProxy(function(item, index, series){
+ var record = chart.store.getAt(index);
+ return fn.call(scope, chart, record, index, series);
+ });
+ chart.swf.setDataTipFunction(chart.tipFnName);
+ },
+
+ setSeries : function(series){
+ this.series = series;
+ this.refresh();
+ },
+
+
+ bindStore : function(store, initial){
+ if(!initial && this.store){
+ if(store !== this.store && this.store.autoDestroy){
+ this.store.destroy();
+ }else{
+ this.store.un("datachanged", this.refresh, this);
+ this.store.un("add", this.delayRefresh, this);
+ this.store.un("remove", this.delayRefresh, this);
+ this.store.un("update", this.delayRefresh, this);
+ this.store.un("clear", this.refresh, this);
+ }
+ }
+ if(store){
+ store = Ext.StoreMgr.lookup(store);
+ store.on({
+ scope: this,
+ datachanged: this.refresh,
+ add: this.delayRefresh,
+ remove: this.delayRefresh,
+ update: this.delayRefresh,
+ clear: this.refresh
+ });
+ }
+ this.store = store;
+ if(store && !initial){
+ this.refresh();
+ }
+ },
+
+ onSwfReady : function(isReset){
+ Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
+ var ref;
+ this.swf.setType(this.type);
+
+ if(this.chartStyle){
+ this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
+ }
+
+ if(this.categoryNames){
+ this.setCategoryNames(this.categoryNames);
+ }
+
+ if(this.tipRenderer){
+ ref = this.getFunctionRef(this.tipRenderer);
+ this.setTipRenderer(ref.fn, ref.scope);
+ }
+ if(this.legendRenderer){
+ ref = this.getFunctionRef(this.legendRenderer);
+ this.setLegendRenderer(ref.fn, ref.scope);
+ }
+ if(!isReset){
+ this.bindStore(this.store, true);
+ }
+ this.refresh.defer(10, this);
+ },
+
+ delayRefresh : function(){
+ if(!this.refreshTask){
+ this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
+ }
+ this.refreshTask.delay(this.refreshBuffer);
+ },
+
+ refresh : function(){
+ if(this.fireEvent('beforerefresh', this) !== false){
+ var styleChanged = false;
+
+ var data = [], rs = this.store.data.items;
+ for(var j = 0, len = rs.length; j < len; j++){
+ data[j] = rs[j].data;
+ }
+
+
+ var dataProvider = [];
+ var seriesCount = 0;
+ var currentSeries = null;
+ var i = 0;
+ if(this.series){
+ seriesCount = this.series.length;
+ for(i = 0; i < seriesCount; i++){
+ currentSeries = this.series[i];
+ var clonedSeries = {};
+ for(var prop in currentSeries){
+ if(prop == "style" && currentSeries.style !== null){
+ clonedSeries.style = Ext.encode(currentSeries.style);
+ styleChanged = true;
+
+
+
+
+ } else{
+ clonedSeries[prop] = currentSeries[prop];
+ }
+ }
+ dataProvider.push(clonedSeries);
+ }
+ }
+
+ if(seriesCount > 0){
+ for(i = 0; i < seriesCount; i++){
+ currentSeries = dataProvider[i];
+ if(!currentSeries.type){
+ currentSeries.type = this.type;
+ }
+ currentSeries.dataProvider = data;
+ }
+ } else{
+ dataProvider.push({type: this.type, dataProvider: data});
+ }
+ this.swf.setDataProvider(dataProvider);
+ if(this.seriesStyles){
+ this.setSeriesStyles(this.seriesStyles);
+ }
+ this.fireEvent('refresh', this);
+ }
+ },
+
+
+ createFnProxy : function(fn){
+ var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
+ Ext.chart.Chart.proxyFunction[fnName] = fn;
+ return 'Ext.chart.Chart.proxyFunction.' + fnName;
+ },
+
+
+ removeFnProxy : function(fn){
+ if(!Ext.isEmpty(fn)){
+ fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
+ delete Ext.chart.Chart.proxyFunction[fn];
+ }
+ },
+
+
+ getFunctionRef : function(val){
+ if(Ext.isFunction(val)){
+ return {
+ fn: val,
+ scope: this
+ };
+ }else{
+ return {
+ fn: val.fn,
+ scope: val.scope || this
+ };
+ }
+ },
+
+
+ onDestroy: function(){
+ if (this.refreshTask && this.refreshTask.cancel){
+ this.refreshTask.cancel();
+ }
+ Ext.chart.Chart.superclass.onDestroy.call(this);
+ this.bindStore(null);
+ this.removeFnProxy(this.tipFnName);
+ this.removeFnProxy(this.legendFnName);
+ }
+});
+Ext.reg('chart', Ext.chart.Chart);
+Ext.chart.Chart.PROXY_FN_ID = 0;
+Ext.chart.Chart.proxyFunction = {};
+
+
+Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
+
+
+Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
+ type: 'pie',
+
+ onSwfReady : function(isReset){
+ Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
+
+ this.setDataField(this.dataField);
+ this.setCategoryField(this.categoryField);
+ },
+
+ setDataField : function(field){
+ this.dataField = field;
+ this.swf.setDataField(field);
+ },
+
+ setCategoryField : function(field){
+ this.categoryField = field;
+ this.swf.setCategoryField(field);
+ }
+});
+Ext.reg('piechart', Ext.chart.PieChart);
+
+
+Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
+ onSwfReady : function(isReset){
+ Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
+ this.labelFn = [];
+ if(this.xField){
+ this.setXField(this.xField);
+ }
+ if(this.yField){
+ this.setYField(this.yField);
+ }
+ if(this.xAxis){
+ this.setXAxis(this.xAxis);
+ }
+ if(this.xAxes){
+ this.setXAxes(this.xAxes);
+ }
+ if(this.yAxis){
+ this.setYAxis(this.yAxis);
+ }
+ if(this.yAxes){
+ this.setYAxes(this.yAxes);
+ }
+ if(Ext.isDefined(this.constrainViewport)){
+ this.swf.setConstrainViewport(this.constrainViewport);
+ }
+ },
+
+ setXField : function(value){
+ this.xField = value;
+ this.swf.setHorizontalField(value);
+ },
+
+ setYField : function(value){
+ this.yField = value;
+ this.swf.setVerticalField(value);
+ },
+
+ setXAxis : function(value){
+ this.xAxis = this.createAxis('xAxis', value);
+ this.swf.setHorizontalAxis(this.xAxis);
+ },
+
+ setXAxes : function(value){
+ var axis;
+ for(var i = 0; i < value.length; i++) {
+ axis = this.createAxis('xAxis' + i, value[i]);
+ this.swf.setHorizontalAxis(axis);
+ }
+ },
+
+ setYAxis : function(value){
+ this.yAxis = this.createAxis('yAxis', value);
+ this.swf.setVerticalAxis(this.yAxis);
+ },
+
+ setYAxes : function(value){
+ var axis;
+ for(var i = 0; i < value.length; i++) {
+ axis = this.createAxis('yAxis' + i, value[i]);
+ this.swf.setVerticalAxis(axis);
+ }
+ },
+
+ createAxis : function(axis, value){
+ var o = Ext.apply({}, value),
+ ref,
+ old;
+
+ if(this[axis]){
+ old = this[axis].labelFunction;
+ this.removeFnProxy(old);
+ this.labelFn.remove(old);
+ }
+ if(o.labelRenderer){
+ ref = this.getFunctionRef(o.labelRenderer);
+ o.labelFunction = this.createFnProxy(function(v){
+ return ref.fn.call(ref.scope, v);
+ });
+ delete o.labelRenderer;
+ this.labelFn.push(o.labelFunction);
+ }
+ if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
+ o.position = 'bottom';
+ }
+ return o;
+ },
+
+ onDestroy : function(){
+ Ext.chart.CartesianChart.superclass.onDestroy.call(this);
+ Ext.each(this.labelFn, function(fn){
+ this.removeFnProxy(fn);
+ }, this);
+ }
+});
+Ext.reg('cartesianchart', Ext.chart.CartesianChart);
+
+
+Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
+ type: 'line'
+});
+Ext.reg('linechart', Ext.chart.LineChart);
+
+
+Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
+ type: 'column'
+});
+Ext.reg('columnchart', Ext.chart.ColumnChart);
+
+
+Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
+ type: 'stackcolumn'
+});
+Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
+
+
+Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
+ type: 'bar'
+});
+Ext.reg('barchart', Ext.chart.BarChart);
+
+
+Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
+ type: 'stackbar'
+});
+Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
+
+
+
+
+Ext.chart.Axis = function(config){
+ Ext.apply(this, config);
+};
+
+Ext.chart.Axis.prototype =
+{
+
+ type: null,
+
+
+ orientation: "horizontal",
+
+
+ reverse: false,
+
+
+ labelFunction: null,
+
+
+ hideOverlappingLabels: true,
+
+
+ labelSpacing: 2
+};
+
+
+Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
+ type: "numeric",
+
+
+ minimum: NaN,
+
+
+ maximum: NaN,
+
+
+ majorUnit: NaN,
+
+
+ minorUnit: NaN,
+
+
+ snapToUnits: true,
+
+
+ alwaysShowZero: true,
+
+
+ scale: "linear",
+
+
+ roundMajorUnit: true,
+
+
+ calculateByLabelSize: true,
+
+
+ position: 'left',
+
+
+ adjustMaximumByMajorUnit: true,
+
+
+ adjustMinimumByMajorUnit: true
+
+});
+
+
+Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
+ type: "time",
+
+
+ minimum: null,
+
+
+ maximum: null,
+
+
+ majorUnit: NaN,
+
+
+ majorTimeUnit: null,
+
+
+ minorUnit: NaN,
+
+
+ minorTimeUnit: null,
+
+
+ snapToUnits: true,
+
+
+ stackingEnabled: false,
+
+
+ calculateByLabelSize: true
+
+});
+
+
+Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
+ type: "category",
+
+
+ categoryNames: null,
+
+
+ calculateCategoryCount: false
+
+});
+
+
+Ext.chart.Series = function(config) { Ext.apply(this, config); };
+
+Ext.chart.Series.prototype =
+{
+
+ type: null,
+
+
+ displayName: null
+};
+
+
+Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
+
+ xField: null,
+
+
+ yField: null,
+
+
+ showInLegend: true,
+
+
+ axis: 'primary'
+});
+
+
+Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
+ type: "column"
+});
+
+
+Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
+ type: "line"
+});
+
+
+Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
+ type: "bar"
+});
+
+
+
+Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
+ type: "pie",
+ dataField: null,
+ categoryField: null
+});
+Ext.menu.Menu = Ext.extend(Ext.Container, {
+
+
+
+ minWidth : 120,
+
+ shadow : 'sides',
+
+ subMenuAlign : 'tl-tr?',
+
+ defaultAlign : 'tl-bl?',
+
+ allowOtherMenus : false,
+
+ ignoreParentClicks : false,
+
+ enableScrolling : true,
+
+ maxHeight : null,
+
+ scrollIncrement : 24,
+
+ showSeparator : true,
+
+ defaultOffsets : [0, 0],
+
+
+ plain : false,
+
+
+ floating : true,
+
+
+
+ zIndex: 15000,
+
+
+ hidden : true,
+
+
+ layout : 'menu',
+ hideMode : 'offsets',
+ scrollerHeight : 8,
+ autoLayout : true,
+ defaultType : 'menuitem',
+ bufferResize : false,
+
+ initComponent : function(){
+ if(Ext.isArray(this.initialConfig)){
+ Ext.apply(this, {items:this.initialConfig});
+ }
+ this.addEvents(
+
+ 'click',
+
+ 'mouseover',
+
+ 'mouseout',
+
+ 'itemclick'
+ );
+ Ext.menu.MenuMgr.register(this);
+ if(this.floating){
+ Ext.EventManager.onWindowResize(this.hide, this);
+ }else{
+ if(this.initialConfig.hidden !== false){
+ this.hidden = false;
+ }
+ this.internalDefaults = {hideOnClick: false};
+ }
+ Ext.menu.Menu.superclass.initComponent.call(this);
+ if(this.autoLayout){
+ var fn = this.doLayout.createDelegate(this, []);
+ this.on({
+ add: fn,
+ remove: fn
+ });
+ }
+ },
+
+
+ getLayoutTarget : function() {
+ return this.ul;
+ },
+
+
+ onRender : function(ct, position){
+ if(!ct){
+ ct = Ext.getBody();
+ }
+
+ var dh = {
+ id: this.getId(),
+ cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
+ style: this.style,
+ cn: [
+ {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
+ {tag: 'ul', cls: 'x-menu-list'}
+ ]
+ };
+ if(this.floating){
+ this.el = new Ext.Layer({
+ shadow: this.shadow,
+ dh: dh,
+ constrain: false,
+ parentEl: ct,
+ zindex: this.zIndex
+ });
+ }else{
+ this.el = ct.createChild(dh);
+ }
+ Ext.menu.Menu.superclass.onRender.call(this, ct, position);
+
+ if(!this.keyNav){
+ this.keyNav = new Ext.menu.MenuNav(this);
+ }
+
+ this.focusEl = this.el.child('a.x-menu-focus');
+ this.ul = this.el.child('ul.x-menu-list');
+ this.mon(this.ul, {
+ scope: this,
+ click: this.onClick,
+ mouseover: this.onMouseOver,
+ mouseout: this.onMouseOut
+ });
+ if(this.enableScrolling){
+ this.mon(this.el, {
+ scope: this,
+ delegate: '.x-menu-scroller',
+ click: this.onScroll,
+ mouseover: this.deactivateActive
+ });
+ }
+ },
+
+
+ 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 = this.findTargetItem(e);
+ if(t){
+ if(t.isFormField){
+ this.setActiveItem(t);
+ }else if(t instanceof Ext.menu.BaseItem){
+ if(t.menu && this.ignoreParentClicks){
+ t.expandMenu();
+ e.preventDefault();
+ }else if(t.onClick){
+ t.onClick(e);
+ this.fireEvent('click', this, t, e);
+ }
+ }
+ }
+ },
+
+
+ setActiveItem : function(item, autoExpand){
+ if(item != this.activeItem){
+ this.deactivateActive();
+ if((this.activeItem = item).isFormField){
+ item.focus();
+ }else{
+ item.activate(autoExpand);
+ }
+ }else if(autoExpand){
+ item.expandMenu();
+ }
+ },
+
+ deactivateActive : function(){
+ var a = this.activeItem;
+ if(a){
+ if(a.isFormField){
+
+ if(a.collapse){
+ a.collapse();
+ }
+ }else{
+ a.deactivate();
+ }
+ delete this.activeItem;
+ }
+ },
+
+
+ tryActivate : function(start, step){
+ var items = this.items;
+ for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
+ var item = items.get(i);
+ if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
+ this.setActiveItem(item, false);
+ return item;
+ }
+ }
+ return false;
+ },
+
+
+ onMouseOver : function(e){
+ var t = this.findTargetItem(e);
+ if(t){
+ if(t.canActivate && !t.disabled){
+ this.setActiveItem(t, true);
+ }
+ }
+ this.over = true;
+ this.fireEvent('mouseover', this, e, t);
+ },
+
+
+ onMouseOut : function(e){
+ var t = this.findTargetItem(e);
+ if(t){
+ if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
+ this.activeItem.deactivate();
+ delete this.activeItem;
+ }
+ }
+ this.over = false;
+ this.fireEvent('mouseout', this, e, t);
+ },
+
+
+ onScroll : function(e, t){
+ if(e){
+ e.stopEvent();
+ }
+ var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
+ ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
+ if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
+ this.onScrollerOut(null, t);
+ }
+ },
+
+
+ onScrollerIn : function(e, t){
+ var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
+ if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
+ Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
+ }
+ },
+
+
+ onScrollerOut : function(e, t){
+ Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
+ },
+
+
+ show : function(el, pos, parentMenu){
+ if(this.floating){
+ this.parentMenu = parentMenu;
+ if(!this.el){
+ this.render();
+ this.doLayout(false, true);
+ }
+ this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
+ }else{
+ Ext.menu.Menu.superclass.show.call(this);
+ }
+ },
+
+
+ showAt : function(xy, parentMenu){
+ if(this.fireEvent('beforeshow', this) !== false){
+ this.parentMenu = parentMenu;
+ if(!this.el){
+ this.render();
+ }
+ if(this.enableScrolling){
+
+ this.el.setXY(xy);
+
+ xy[1] = this.constrainScroll(xy[1]);
+ xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
+ }else{
+
+ xy = this.el.adjustForConstraints(xy);
+ }
+ this.el.setXY(xy);
+ this.el.show();
+ Ext.menu.Menu.superclass.onShow.call(this);
+ if(Ext.isIE9m){
+
+ this.fireEvent('autosize', this);
+ if(!Ext.isIE8){
+ this.el.repaint();
+ }
+ }
+ this.hidden = false;
+ this.focus();
+ this.fireEvent('show', this);
+ }
+ },
+
+ constrainScroll : function(y){
+ var max, full = this.ul.setHeight('auto').getHeight(),
+ returnY = y, normalY, parentEl, scrollTop, viewHeight;
+ if(this.floating){
+ parentEl = Ext.fly(this.el.dom.parentNode);
+ scrollTop = parentEl.getScroll().top;
+ viewHeight = parentEl.getViewSize().height;
+
+
+ normalY = y - scrollTop;
+ max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
+ if(full > viewHeight) {
+ max = viewHeight;
+
+ returnY = y - normalY;
+ } else if(max < full) {
+ returnY = y - (full - max);
+ max = full;
+ }
+ }else{
+ max = this.getHeight();
+ }
+
+ if (this.maxHeight){
+ max = Math.min(this.maxHeight, max);
+ }
+ if(full > max && max > 0){
+ this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
+ this.ul.setHeight(this.activeMax);
+ this.createScrollers();
+ this.el.select('.x-menu-scroller').setDisplayed('');
+ }else{
+ this.ul.setHeight(full);
+ this.el.select('.x-menu-scroller').setDisplayed('none');
+ }
+ this.ul.dom.scrollTop = 0;
+ return returnY;
+ },
+
+ createScrollers : function(){
+ if(!this.scroller){
+ this.scroller = {
+ pos: 0,
+ top: this.el.insertFirst({
+ tag: 'div',
+ cls: 'x-menu-scroller x-menu-scroller-top',
+ html: '&#160;'
+ }),
+ bottom: this.el.createChild({
+ tag: 'div',
+ cls: 'x-menu-scroller x-menu-scroller-bottom',
+ html: '&#160;'
+ })
+ };
+ this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
+ this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
+ listeners: {
+ click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
+ }
+ });
+ this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
+ this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
+ listeners: {
+ click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
+ }
+ });
+ }
+ },
+
+ onLayout : function(){
+ if(this.isVisible()){
+ if(this.enableScrolling){
+ this.constrainScroll(this.el.getTop());
+ }
+ if(this.floating){
+ this.el.sync();
+ }
+ }
+ },
+
+ focus : function(){
+ if(!this.hidden){
+ this.doFocus.defer(50, this);
+ }
+ },
+
+ doFocus : function(){
+ if(!this.hidden){
+ this.focusEl.focus();
+ }
+ },
+
+
+ hide : function(deep){
+ if (!this.isDestroyed) {
+ this.deepHide = deep;
+ Ext.menu.Menu.superclass.hide.call(this);
+ delete this.deepHide;
+ }
+ },
+
+
+ onHide : function(){
+ Ext.menu.Menu.superclass.onHide.call(this);
+ this.deactivateActive();
+ if(this.el && this.floating){
+ this.el.hide();
+ }
+ var pm = this.parentMenu;
+ if(this.deepHide === true && pm){
+ if(pm.floating){
+ pm.hide(true);
+ }else{
+ pm.deactivateActive();
+ }
+ }
+ },
+
+
+ lookupComponent : function(c){
+ if(Ext.isString(c)){
+ c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
+ this.applyDefaults(c);
+ }else{
+ if(Ext.isObject(c)){
+ c = this.getMenuItem(c);
+ }else if(c.tagName || c.el){
+ c = new Ext.BoxComponent({
+ el: c
+ });
+ }
+ }
+ return c;
+ },
+
+ applyDefaults : function(c) {
+ if (!Ext.isString(c)) {
+ c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
+ var d = this.internalDefaults;
+ if(d){
+ if(c.events){
+ Ext.applyIf(c.initialConfig, d);
+ Ext.apply(c, d);
+ }else{
+ Ext.applyIf(c, d);
+ }
+ }
+ }
+ return c;
+ },
+
+
+ getMenuItem : function(config) {
+ config.ownerCt = this;
+
+ if (!config.isXType) {
+ if (!config.xtype && Ext.isBoolean(config.checked)) {
+ return new Ext.menu.CheckItem(config);
+ }
+ return Ext.create(config, this.defaultType);
+ }
+ return config;
+ },
+
+
+ addSeparator : function() {
+ return this.add(new Ext.menu.Separator());
+ },
+
+
+ addElement : function(el) {
+ return this.add(new Ext.menu.BaseItem({
+ el: el
+ }));
+ },
+
+
+ addItem : function(item) {
+ return this.add(item);
+ },
+
+
+ addMenuItem : function(config) {
+ return this.add(this.getMenuItem(config));
+ },
+
+
+ addText : function(text){
+ return this.add(new Ext.menu.TextItem(text));
+ },
+
+
+ onDestroy : function(){
+ Ext.EventManager.removeResizeListener(this.hide, this);
+ var pm = this.parentMenu;
+ if(pm && pm.activeChild == this){
+ delete pm.activeChild;
+ }
+ delete this.parentMenu;
+ Ext.menu.Menu.superclass.onDestroy.call(this);
+ Ext.menu.MenuMgr.unregister(this);
+ if(this.keyNav) {
+ this.keyNav.disable();
+ }
+ var s = this.scroller;
+ if(s){
+ Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
+ }
+ Ext.destroy(
+ this.el,
+ this.focusEl,
+ this.ul
+ );
+ }
+});
+
+Ext.reg('menu', Ext.menu.Menu);
+
+
+Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
+ function up(e, m){
+ if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
+ m.tryActivate(m.items.length-1, -1);
+ }
+ }
+ function down(e, m){
+ if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
+ m.tryActivate(0, 1);
+ }
+ }
+ return {
+ constructor : function(menu){
+ Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
+ this.scope = this.menu = menu;
+ },
+
+ doRelay : function(e, h){
+ var k = e.getKey();
+
+ if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
+ return false;
+ }
+ 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);
+ },
+
+ tab: function(e, m) {
+ e.stopEvent();
+ if (e.shiftKey) {
+ up(e, m);
+ } else {
+ down(e, m);
+ }
+ },
+
+ up : up,
+
+ down : down,
+
+ 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 menus,
+ active,
+ map,
+ groups = {},
+ attached = false,
+ lastShow = new Date();
+
+
+
+ function init(){
+ menus = {};
+ active = new Ext.util.MixedCollection();
+ map = Ext.getDoc().addKeyListener(27, hideAll);
+ map.disable();
+ }
+
+
+ function hideAll(){
+ if(active && active.length > 0){
+ var c = active.clone();
+ c.each(function(m){
+ m.hide();
+ });
+ return true;
+ }
+ return false;
+ }
+
+
+ function onHide(m){
+ active.remove(m);
+ if(active.length < 1){
+ map.disable();
+ Ext.getDoc().un("mousedown", onMouseDown);
+ attached = false;
+ }
+ }
+
+
+ function onShow(m){
+ var last = active.last();
+ lastShow = new Date();
+ active.add(m);
+ if(!attached){
+ map.enable();
+ Ext.getDoc().on("mousedown", onMouseDown);
+ attached = true;
+ }
+ if(m.parentMenu){
+ m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
+ m.parentMenu.activeChild = m;
+ }else if(last && !last.isDestroyed && last.isVisible()){
+ m.getEl().setZIndex(parseInt(last.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(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
+ hideAll();
+ }
+ }
+
+ return {
+
+
+ hideAll : function(){
+ return hideAll();
+ },
+
+
+ register : function(menu){
+ if(!menus){
+ init();
+ }
+ menus[menu.id] = menu;
+ menu.on({
+ beforehide: onBeforeHide,
+ hide: onHide,
+ beforeshow: onBeforeShow,
+ show: onShow
+ });
+ },
+
+
+ get : function(menu){
+ if(typeof menu == "string"){
+ if(!menus){
+ return null;
+ }
+ return menus[menu];
+ }else if(menu.events){
+ return menu;
+ }else if(typeof menu.length == 'number'){
+ return new Ext.menu.Menu({items:menu});
+ }else{
+ return Ext.create(menu, 'menu');
+ }
+ },
+
+
+ unregister : function(menu){
+ delete menus[menu.id];
+ menu.un("beforehide", onBeforeHide);
+ menu.un("hide", onHide);
+ menu.un("beforeshow", onBeforeShow);
+ menu.un("show", onShow);
+ },
+
+
+ registerCheckable : function(menuItem){
+ var g = menuItem.group;
+ if(g){
+ if(!groups[g]){
+ groups[g] = [];
+ }
+ groups[g].push(menuItem);
+ }
+ },
+
+
+ unregisterCheckable : function(menuItem){
+ var g = menuItem.group;
+ if(g){
+ groups[g].remove(menuItem);
+ }
+ },
+
+
+ onCheckChange: function(item, state){
+ if(item.group && state){
+ var group = groups[item.group],
+ i = 0,
+ len = group.length,
+ current;
+
+ for(; i < len; i++){
+ current = group[i];
+ if(current != item){
+ current.setChecked(false);
+ }
+ }
+ }
+ },
+
+ getCheckedItem : function(groupId){
+ var g = groups[groupId];
+ if(g){
+ for(var i = 0, l = g.length; i < l; i++){
+ if(g[i].checked){
+ return g[i];
+ }
+ }
+ }
+ return null;
+ },
+
+ setCheckedItem : function(groupId, itemId){
+ var g = groups[groupId];
+ if(g){
+ for(var i = 0, l = g.length; i < l; i++){
+ if(g[i].id == itemId){
+ g[i].setChecked(true);
+ }
+ }
+ }
+ return null;
+ }
+ };
+}();
+
+Ext.menu.BaseItem = Ext.extend(Ext.Component, {
+
+
+
+
+ canActivate : false,
+
+ activeClass : "x-menu-item-active",
+
+ hideOnClick : true,
+
+ clickHideDelay : 1,
+
+
+ ctype : "Ext.menu.BaseItem",
+
+
+ actionMode : "container",
+
+ initComponent : function(){
+ Ext.menu.BaseItem.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'click',
+
+ 'activate',
+
+ 'deactivate'
+ );
+ if(this.handler){
+ this.on("click", this.handler, this.scope);
+ }
+ },
+
+
+ onRender : function(container, position){
+ Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
+ if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
+ this.parentMenu = this.ownerCt;
+ }else{
+ this.container.addClass('x-menu-list-item');
+ this.mon(this.el, {
+ scope: this,
+ click: this.onClick,
+ mouseenter: this.activate,
+ mouseleave: this.deactivate
+ });
+ }
+ },
+
+
+ setHandler : function(handler, scope){
+ if(this.handler){
+ this.un("click", this.handler, this.scope);
+ }
+ this.on("click", this.handler = handler, this.scope = scope);
+ },
+
+
+ onClick : function(e){
+ if(!this.disabled && this.fireEvent("click", this, e) !== false
+ && (this.parentMenu && 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){
+ var pm = this.parentMenu;
+ if(this.hideOnClick){
+ if(pm.floating){
+ this.clickHideDelayTimer = pm.hide.defer(this.clickHideDelay, pm, [true]);
+ }else{
+ pm.deactivateActive();
+ }
+ }
+ },
+
+ beforeDestroy: function(){
+ clearTimeout(this.clickHideDelayTimer);
+ Ext.menu.BaseItem.superclass.beforeDestroy.call(this);
+ },
+
+
+ expandMenu : Ext.emptyFn,
+
+
+ hideMenu : Ext.emptyFn
+});
+Ext.reg('menubaseitem', Ext.menu.BaseItem);
+Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
+
+
+ hideOnClick : false,
+
+ itemCls : "x-menu-text",
+
+ constructor : function(config) {
+ if (typeof config == 'string') {
+ config = {
+ text: config
+ };
+ }
+ Ext.menu.TextItem.superclass.constructor.call(this, config);
+ },
+
+
+ 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.reg('menutextitem', Ext.menu.TextItem);
+Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
+
+ itemCls : "x-menu-sep",
+
+ hideOnClick : false,
+
+
+ activeClass: '',
+
+
+ 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.reg('menuseparator', Ext.menu.Separator);
+Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
+
+
+
+
+
+
+
+
+ itemCls : 'x-menu-item',
+
+ canActivate : true,
+
+ showDelay: 200,
+
+
+ altText: '',
+
+
+ hideDelay: 200,
+
+
+ ctype: 'Ext.menu.Item',
+
+ initComponent : function(){
+ Ext.menu.Item.superclass.initComponent.call(this);
+ if(this.menu){
+
+
+ if (Ext.isArray(this.menu)){
+ this.menu = { items: this.menu };
+ }
+
+
+
+ if (Ext.isObject(this.menu)){
+ this.menu.ownerCt = this;
+ }
+
+ this.menu = Ext.menu.MenuMgr.get(this.menu);
+ this.menu.ownerCt = undefined;
+ }
+ },
+
+
+ onRender : function(container, position){
+ if (!this.itemTpl) {
+ this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
+ '<a id="{id}" class="{cls} x-unselectable" hidefocus="true" unselectable="on" href="{href}"',
+ '<tpl if="hrefTarget">',
+ ' target="{hrefTarget}"',
+ '</tpl>',
+ '>',
+ '<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
+ '<span class="x-menu-item-text">{text}</span>',
+ '</a>'
+ );
+ }
+ var a = this.getTemplateArgs();
+ this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
+ this.iconEl = this.el.child('img.x-menu-item-icon');
+ this.textEl = this.el.child('.x-menu-item-text');
+ if(!this.href) {
+ this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
+ }
+ Ext.menu.Item.superclass.onRender.call(this, container, position);
+ },
+
+ getTemplateArgs: function() {
+ return {
+ id: this.id,
+ cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
+ href: this.href || '#',
+ hrefTarget: this.hrefTarget,
+ icon: this.icon || Ext.BLANK_IMAGE_URL,
+ iconCls: this.iconCls || '',
+ text: this.itemText||this.text||'&#160;',
+ altText: this.altText || ''
+ };
+ },
+
+
+ setText : function(text){
+ this.text = text||'&#160;';
+ if(this.rendered){
+ this.textEl.update(this.text);
+ this.parentMenu.layout.doAutoSize();
+ }
+ },
+
+
+ setIconClass : function(cls){
+ var oldCls = this.iconCls;
+ this.iconCls = cls;
+ if(this.rendered){
+ this.iconEl.replaceClass(oldCls, this.iconCls);
+ }
+ },
+
+
+ beforeDestroy: function(){
+ clearTimeout(this.showTimer);
+ clearTimeout(this.hideTimer);
+ if (this.menu){
+ delete this.menu.ownerCt;
+ this.menu.destroy();
+ }
+ Ext.menu.Item.superclass.beforeDestroy.call(this);
+ },
+
+
+ handleClick : function(e){
+ if(!this.href){
+ e.stopEvent();
+ }
+ Ext.menu.Item.superclass.handleClick.apply(this, arguments);
+ },
+
+
+ activate : function(autoExpand){
+ if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
+ this.focus();
+ if(autoExpand){
+ 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(autoActivate){
+ if(!this.disabled && this.menu){
+ clearTimeout(this.hideTimer);
+ delete this.hideTimer;
+ if(!this.menu.isVisible() && !this.showTimer){
+ this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
+ }else if (this.menu.isVisible() && autoActivate){
+ this.menu.tryActivate(0, 1);
+ }
+ }
+ },
+
+
+ deferExpand : function(autoActivate){
+ delete this.showTimer;
+ this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
+ if(autoActivate){
+ this.menu.tryActivate(0, 1);
+ }
+ },
+
+
+ hideMenu : function(){
+ clearTimeout(this.showTimer);
+ delete this.showTimer;
+ if(!this.hideTimer && this.menu && this.menu.isVisible()){
+ this.hideTimer = this.deferHide.defer(this.hideDelay, this);
+ }
+ },
+
+
+ deferHide : function(){
+ delete this.hideTimer;
+ if(this.menu.over){
+ this.parentMenu.setActiveItem(this, false);
+ }else{
+ this.menu.hide();
+ }
+ }
+});
+Ext.reg('menuitem', Ext.menu.Item);
+Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
+
+
+ itemCls : "x-menu-item x-menu-check-item",
+
+ groupClass : "x-menu-group-item",
+
+
+ checked: false,
+
+
+ ctype: "Ext.menu.CheckItem",
+
+ initComponent : function(){
+ Ext.menu.CheckItem.superclass.initComponent.call(this);
+ this.addEvents(
+
+ "beforecheckchange" ,
+
+ "checkchange"
+ );
+
+ if(this.checkHandler){
+ this.on('checkchange', this.checkHandler, this.scope);
+ }
+ Ext.menu.MenuMgr.registerCheckable(this);
+ },
+
+
+ onRender : function(c){
+ Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
+ if(this.group){
+ this.el.addClass(this.groupClass);
+ }
+ if(this.checked){
+ this.checked = false;
+ this.setChecked(true, true);
+ }
+ },
+
+
+ destroy : function(){
+ Ext.menu.MenuMgr.unregisterCheckable(this);
+ Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
+ },
+
+
+ setChecked : function(state, suppressEvent){
+ var suppress = suppressEvent === true;
+ if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
+ Ext.menu.MenuMgr.onCheckChange(this, state);
+ if(this.container){
+ this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
+ }
+ this.checked = state;
+ if(!suppress){
+ this.fireEvent("checkchange", this, state);
+ }
+ }
+ },
+
+
+ handleClick : function(e){
+ if(!this.disabled && !(this.checked && this.group)){
+ this.setChecked(!this.checked);
+ }
+ Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
+ }
+});
+Ext.reg('menucheckitem', Ext.menu.CheckItem);
+ Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
+
+ enableScrolling : false,
+
+
+
+ hideOnClick : true,
+
+
+ pickerId : null,
+
+
+
+
+ cls : 'x-date-menu',
+
+
+
+
+
+ initComponent : function(){
+ this.on('beforeshow', this.onBeforeShow, this);
+ if(this.strict = (Ext.isIE7 && Ext.isStrict)){
+ this.on('show', this.onShow, this, {single: true, delay: 20});
+ }
+ Ext.apply(this, {
+ plain: true,
+ showSeparator: false,
+ items: this.picker = new Ext.DatePicker(Ext.applyIf({
+ internalRender: this.strict || !Ext.isIE9m,
+ ctCls: 'x-menu-date-item',
+ id: this.pickerId
+ }, this.initialConfig))
+ });
+ this.picker.purgeListeners();
+ Ext.menu.DateMenu.superclass.initComponent.call(this);
+
+ this.relayEvents(this.picker, ['select']);
+ this.on('show', this.picker.focus, this.picker);
+ this.on('select', this.menuHide, this);
+ if(this.handler){
+ this.on('select', this.handler, this.scope || this);
+ }
+ },
+
+ menuHide : function() {
+ if(this.hideOnClick){
+ this.hide(true);
+ }
+ },
+
+ onBeforeShow : function(){
+ if(this.picker){
+ this.picker.hideMonthPicker(true);
+ }
+ },
+
+ onShow : function(){
+ var el = this.picker.getEl();
+ el.setWidth(el.getWidth());
+ }
+ });
+ Ext.reg('datemenu', Ext.menu.DateMenu);
+
+ Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
+
+ enableScrolling : false,
+
+
+
+
+ hideOnClick : true,
+
+ cls : 'x-color-menu',
+
+
+ paletteId : null,
+
+
+
+
+
+
+
+
+
+
+ initComponent : function(){
+ Ext.apply(this, {
+ plain: true,
+ showSeparator: false,
+ items: this.palette = new Ext.ColorPalette(Ext.applyIf({
+ id: this.paletteId
+ }, this.initialConfig))
+ });
+ this.palette.purgeListeners();
+ Ext.menu.ColorMenu.superclass.initComponent.call(this);
+
+ this.relayEvents(this.palette, ['select']);
+ this.on('select', this.menuHide, this);
+ if(this.handler){
+ this.on('select', this.handler, this.scope || this);
+ }
+ },
+
+ menuHide : function(){
+ if(this.hideOnClick){
+ this.hide(true);
+ }
+ }
+});
+Ext.reg('colormenu', Ext.menu.ColorMenu);
+
+Ext.form.Field = Ext.extend(Ext.BoxComponent, {
+
+
+
+
+
+
+
+
+ invalidClass : 'x-form-invalid',
+
+ invalidText : 'The value in this field is invalid',
+
+ focusClass : 'x-form-focus',
+
+
+ validationEvent : 'keyup',
+
+ validateOnBlur : true,
+
+ validationDelay : 250,
+
+ defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
+
+ fieldClass : 'x-form-field',
+
+ msgTarget : 'qtip',
+
+ msgFx : 'normal',
+
+ readOnly : false,
+
+ disabled : false,
+
+ submitValue: true,
+
+
+ isFormField : true,
+
+
+ msgDisplay: '',
+
+
+ hasFocus : false,
+
+
+ initComponent : function(){
+ Ext.form.Field.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'focus',
+
+ 'blur',
+
+ 'specialkey',
+
+ 'change',
+
+ 'invalid',
+
+ 'valid'
+ );
+ },
+
+
+ getName : function(){
+ return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
+ },
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ var cfg = this.getAutoCreate();
+
+ if(!cfg.name){
+ cfg.name = this.name || this.id;
+ }
+ if(this.inputType){
+ cfg.type = this.inputType;
+ }
+ this.autoEl = cfg;
+ }
+ Ext.form.Field.superclass.onRender.call(this, ct, position);
+ if(this.submitValue === false){
+ this.el.dom.removeAttribute('name');
+ }
+ var type = this.el.dom.type;
+ if(type){
+ if(type == 'password'){
+ type = 'text';
+ }
+ this.el.addClass('x-form-'+type);
+ }
+ if(this.readOnly){
+ this.setReadOnly(true);
+ }
+ if(this.tabIndex !== undefined){
+ this.el.dom.setAttribute('tabIndex', this.tabIndex);
+ }
+
+ this.el.addClass([this.fieldClass, this.cls]);
+ },
+
+
+ getItemCt : function(){
+ return this.itemCt;
+ },
+
+
+ initValue : function(){
+ if(this.value !== undefined){
+ this.setValue(this.value);
+ }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
+ this.setValue(this.el.dom.value);
+ }
+
+ this.originalValue = this.getValue();
+ },
+
+
+ isDirty : function() {
+ if(this.disabled || !this.rendered) {
+ return false;
+ }
+ return String(this.getValue()) !== String(this.originalValue);
+ },
+
+
+ setReadOnly : function(readOnly){
+ if(this.rendered){
+ this.el.dom.readOnly = readOnly;
+ }
+ this.readOnly = readOnly;
+ },
+
+
+ afterRender : function(){
+ Ext.form.Field.superclass.afterRender.call(this);
+ this.initEvents();
+ this.initValue();
+ },
+
+
+ fireKey : function(e){
+ if(e.isSpecialKey()){
+ this.fireEvent('specialkey', this, e);
+ }
+ },
+
+
+ reset : function(){
+ this.setValue(this.originalValue);
+ this.clearInvalid();
+ },
+
+
+ initEvents : function(){
+ this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey, this);
+ this.mon(this.el, 'focus', this.onFocus, this);
+
+
+
+ this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
+ },
+
+
+ preFocus: Ext.emptyFn,
+
+
+ onFocus : function(){
+ this.preFocus();
+ if(this.focusClass){
+ this.el.addClass(this.focusClass);
+ }
+ if(!this.hasFocus){
+ this.hasFocus = true;
+
+ this.startValue = this.getValue();
+ this.fireEvent('focus', this);
+ }
+ },
+
+
+ beforeBlur : Ext.emptyFn,
+
+
+ onBlur : function(){
+ this.beforeBlur();
+ if(this.focusClass){
+ this.el.removeClass(this.focusClass);
+ }
+ this.hasFocus = false;
+ if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
+ this.validate();
+ }
+ var v = this.getValue();
+ if(String(v) !== String(this.startValue)){
+ this.fireEvent('change', this, v, this.startValue);
+ }
+ this.fireEvent('blur', this);
+ this.postBlur();
+ },
+
+
+ postBlur : Ext.emptyFn,
+
+
+ isValid : function(preventMark){
+ if(this.disabled){
+ return true;
+ }
+ var restore = this.preventMark;
+ this.preventMark = preventMark === true;
+ var v = this.validateValue(this.processValue(this.getRawValue()), preventMark);
+ this.preventMark = restore;
+ return v;
+ },
+
+
+ validate : function(){
+ if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
+ this.clearInvalid();
+ return true;
+ }
+ return false;
+ },
+
+
+ processValue : function(value){
+ return value;
+ },
+
+
+ validateValue : function(value) {
+
+ var error = this.getErrors(value)[0];
+
+ if (error == undefined) {
+ return true;
+ } else {
+ this.markInvalid(error);
+ return false;
+ }
+ },
+
+
+ getErrors: function() {
+ return [];
+ },
+
+
+ getActiveError : function(){
+ return this.activeError || '';
+ },
+
+
+ markInvalid : function(msg){
+
+ if (this.rendered && !this.preventMark) {
+ msg = msg || this.invalidText;
+
+ var mt = this.getMessageHandler();
+ if(mt){
+ mt.mark(this, msg);
+ }else if(this.msgTarget){
+ this.el.addClass(this.invalidClass);
+ var t = Ext.getDom(this.msgTarget);
+ if(t){
+ t.innerHTML = msg;
+ t.style.display = this.msgDisplay;
+ }
+ }
+ }
+
+ this.setActiveError(msg);
+ },
+
+
+ clearInvalid : function(){
+
+ if (this.rendered && !this.preventMark) {
+ this.el.removeClass(this.invalidClass);
+ var mt = this.getMessageHandler();
+ if(mt){
+ mt.clear(this);
+ }else if(this.msgTarget){
+ this.el.removeClass(this.invalidClass);
+ var t = Ext.getDom(this.msgTarget);
+ if(t){
+ t.innerHTML = '';
+ t.style.display = 'none';
+ }
+ }
+ }
+
+ this.unsetActiveError();
+ },
+
+
+ setActiveError: function(msg, suppressEvent) {
+ this.activeError = msg;
+ if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
+ },
+
+
+ unsetActiveError: function(suppressEvent) {
+ delete this.activeError;
+ if (suppressEvent !== true) this.fireEvent('valid', this);
+ },
+
+
+ getMessageHandler : function(){
+ return Ext.form.MessageTargets[this.msgTarget];
+ },
+
+
+ getErrorCt : function(){
+ return this.el.findParent('.x-form-element', 5, true) ||
+ this.el.findParent('.x-form-field-wrap', 5, true);
+ },
+
+
+ alignErrorEl : function(){
+ this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
+ },
+
+
+ alignErrorIcon : function(){
+ this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
+ },
+
+
+ getRawValue : function(){
+ var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
+ if(v === this.emptyText){
+ v = '';
+ }
+ return v;
+ },
+
+
+ getValue : function(){
+ if(!this.rendered) {
+ return this.value;
+ }
+ var v = this.el.getValue();
+ if(v === this.emptyText || v === undefined){
+ v = '';
+ }
+ return v;
+ },
+
+
+ setRawValue : function(v){
+ return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
+ },
+
+
+ setValue : function(v){
+ this.value = v;
+ if(this.rendered){
+ this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
+ this.validate();
+ }
+ return this;
+ },
+
+
+ append : function(v){
+ this.setValue([this.getValue(), v].join(''));
+ }
+
+
+
+
+
+});
+
+
+Ext.form.MessageTargets = {
+ 'qtip' : {
+ mark: function(field, msg){
+ field.el.addClass(field.invalidClass);
+ field.el.dom.qtip = msg;
+ field.el.dom.qclass = 'x-form-invalid-tip';
+ if(Ext.QuickTips){
+ Ext.QuickTips.enable();
+ }
+ },
+ clear: function(field){
+ field.el.removeClass(field.invalidClass);
+ field.el.dom.qtip = '';
+ }
+ },
+ 'title' : {
+ mark: function(field, msg){
+ field.el.addClass(field.invalidClass);
+ field.el.dom.title = msg;
+ },
+ clear: function(field){
+ field.el.dom.title = '';
+ }
+ },
+ 'under' : {
+ mark: function(field, msg){
+ field.el.addClass(field.invalidClass);
+ if(!field.errorEl){
+ var elp = field.getErrorCt();
+ if(!elp){
+ field.el.dom.title = msg;
+ return;
+ }
+ field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
+ field.on('resize', field.alignErrorEl, field);
+ field.on('destroy', function(){
+ Ext.destroy(this.errorEl);
+ }, field);
+ }
+ field.alignErrorEl();
+ field.errorEl.update(msg);
+ Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
+ },
+ clear: function(field){
+ field.el.removeClass(field.invalidClass);
+ if(field.errorEl){
+ Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
+ }else{
+ field.el.dom.title = '';
+ }
+ }
+ },
+ 'side' : {
+ mark: function(field, msg){
+ field.el.addClass(field.invalidClass);
+ if(!field.errorIcon){
+ var elp = field.getErrorCt();
+
+ if(!elp){
+ field.el.dom.title = msg;
+ return;
+ }
+ field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
+ if (field.ownerCt) {
+ field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
+ field.ownerCt.on('expand', field.alignErrorIcon, field);
+ }
+ field.on('resize', field.alignErrorIcon, field);
+ field.on('destroy', function(){
+ Ext.destroy(this.errorIcon);
+ }, field);
+ }
+ field.alignErrorIcon();
+ field.errorIcon.dom.qtip = msg;
+ field.errorIcon.dom.qclass = 'x-form-invalid-tip';
+ field.errorIcon.show();
+ },
+ clear: function(field){
+ field.el.removeClass(field.invalidClass);
+ if(field.errorIcon){
+ field.errorIcon.dom.qtip = '';
+ field.errorIcon.hide();
+ }else{
+ field.el.dom.title = '';
+ }
+ }
+ }
+};
+
+
+Ext.form.Field.msgFx = {
+ normal : {
+ show: function(msgEl, f){
+ msgEl.setDisplayed('block');
+ },
+
+ hide : function(msgEl, f){
+ msgEl.setDisplayed(false).update('');
+ }
+ },
+
+ slide : {
+ show: function(msgEl, f){
+ msgEl.slideIn('t', {stopFx:true});
+ },
+
+ hide : function(msgEl, f){
+ msgEl.slideOut('t', {stopFx:true,useDisplay:true});
+ }
+ },
+
+ slideRight : {
+ show: function(msgEl, f){
+ msgEl.fixDisplay();
+ msgEl.alignTo(f.el, 'tl-tr');
+ msgEl.slideIn('l', {stopFx:true});
+ },
+
+ hide : function(msgEl, f){
+ msgEl.slideOut('l', {stopFx:true,useDisplay:true});
+ }
+ }
+};
+Ext.reg('field', Ext.form.Field);
+
+Ext.form.TextField = Ext.extend(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',
+
+
+
+ initComponent : function(){
+ Ext.form.TextField.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'autosize',
+
+
+ 'keydown',
+
+ 'keyup',
+
+ 'keypress'
+ );
+ },
+
+
+ initEvents : function(){
+ Ext.form.TextField.superclass.initEvents.call(this);
+ if(this.validationEvent == 'keyup'){
+ this.validationTask = new Ext.util.DelayedTask(this.validate, this);
+ this.mon(this.el, 'keyup', this.filterValidation, this);
+ }
+ else if(this.validationEvent !== false && this.validationEvent != 'blur'){
+ this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
+ }
+ if(this.selectOnFocus || this.emptyText){
+ this.mon(this.el, 'mousedown', this.onMouseDown, this);
+
+ if(this.emptyText){
+ this.applyEmptyText();
+ }
+ }
+ if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
+ this.mon(this.el, 'keypress', this.filterKeys, this);
+ }
+ if(this.grow){
+ this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
+ this.mon(this.el, 'click', this.autoSize, this);
+ }
+ if(this.enableKeyEvents){
+ this.mon(this.el, {
+ scope: this,
+ keyup: this.onKeyUp,
+ keydown: this.onKeyDown,
+ keypress: this.onKeyPress
+ });
+ }
+ },
+
+ onMouseDown: function(e){
+ if(!this.hasFocus){
+ this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
+ }
+ },
+
+ processValue : function(value){
+ if(this.stripCharsRe){
+ var newValue = value.replace(this.stripCharsRe, '');
+ if(newValue !== value){
+ this.setRawValue(newValue);
+ return newValue;
+ }
+ }
+ return value;
+ },
+
+ filterValidation : function(e){
+ if(!e.isNavKeyPress()){
+ this.validationTask.delay(this.validationDelay);
+ }
+ },
+
+
+ onDisable: function(){
+ Ext.form.TextField.superclass.onDisable.call(this);
+ if(Ext.isIE){
+ this.el.dom.unselectable = 'on';
+ }
+ },
+
+
+ onEnable: function(){
+ Ext.form.TextField.superclass.onEnable.call(this);
+ if(Ext.isIE){
+ this.el.dom.unselectable = '';
+ }
+ },
+
+
+ onKeyUpBuffered : function(e){
+ if(this.doAutoSize(e)){
+ this.autoSize();
+ }
+ },
+
+
+ doAutoSize : function(e){
+ return !e.isNavKeyPress();
+ },
+
+
+ onKeyUp : function(e){
+ this.fireEvent('keyup', this, e);
+ },
+
+
+ onKeyDown : function(e){
+ this.fireEvent('keydown', this, e);
+ },
+
+
+ onKeyPress : function(e){
+ this.fireEvent('keypress', this, e);
+ },
+
+
+ reset : function(){
+ Ext.form.TextField.superclass.reset.call(this);
+ this.applyEmptyText();
+ },
+
+ applyEmptyText : function(){
+ if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
+ this.setRawValue(this.emptyText);
+ this.el.addClass(this.emptyClass);
+ }
+ },
+
+
+ preFocus : function(){
+ var el = this.el,
+ isEmpty;
+ if(this.emptyText){
+ if(el.dom.value == this.emptyText){
+ this.setRawValue('');
+ isEmpty = true;
+ }
+ el.removeClass(this.emptyClass);
+ }
+ if(this.selectOnFocus || isEmpty){
+ el.dom.select();
+ }
+ },
+
+
+ postBlur : function(){
+ this.applyEmptyText();
+ },
+
+
+ filterKeys : function(e){
+ if(e.ctrlKey){
+ return;
+ }
+ var k = e.getKey();
+ if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
+ return;
+ }
+ var cc = String.fromCharCode(e.getCharCode());
+ if(!Ext.isGecko && e.isSpecialKey() && !cc){
+ return;
+ }
+ if(!this.maskRe.test(cc)){
+ e.stopEvent();
+ }
+ },
+
+ setValue : function(v){
+ if(this.emptyText && this.el && !Ext.isEmpty(v)){
+ this.el.removeClass(this.emptyClass);
+ }
+ Ext.form.TextField.superclass.setValue.apply(this, arguments);
+ this.applyEmptyText();
+ this.autoSize();
+ return this;
+ },
+
+
+ getErrors: function(value) {
+ var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
+
+ value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
+
+ if (Ext.isFunction(this.validator)) {
+ var msg = this.validator(value);
+ if (msg !== true) {
+ errors.push(msg);
+ }
+ }
+
+ if (value.length < 1 || value === this.emptyText) {
+ if (this.allowBlank) {
+
+ return errors;
+ } else {
+ errors.push(this.blankText);
+ }
+ }
+
+ if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
+ errors.push(this.blankText);
+ }
+
+ if (value.length < this.minLength) {
+ errors.push(String.format(this.minLengthText, this.minLength));
+ }
+
+ if (value.length > this.maxLength) {
+ errors.push(String.format(this.maxLengthText, this.maxLength));
+ }
+
+ if (this.vtype) {
+ var vt = Ext.form.VTypes;
+ if(!vt[this.vtype](value, this)){
+ errors.push(this.vtypeText || vt[this.vtype +'Text']);
+ }
+ }
+
+ if (this.regex && !this.regex.test(value)) {
+ errors.push(this.regexText);
+ }
+
+ return errors;
+ },
+
+
+ selectText : function(start, end){
+ var v = this.getRawValue();
+ var doFocus = false;
+ if(v.length > 0){
+ start = start === undefined ? 0 : start;
+ end = end === undefined ? v.length : end;
+ var d = this.el.dom;
+ if(d.setSelectionRange){
+ d.setSelectionRange(start, end);
+ }else if(d.createTextRange){
+ var range = d.createTextRange();
+ range.moveStart('character', start);
+ range.moveEnd('character', end-v.length);
+ range.select();
+ }
+ doFocus = Ext.isGecko || Ext.isOpera;
+ }else{
+ doFocus = true;
+ }
+ if(doFocus){
+ this.focus();
+ }
+ },
+
+
+ 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;
+ var d = document.createElement('div');
+ d.appendChild(document.createTextNode(v));
+ v = d.innerHTML;
+ Ext.removeNode(d);
+ d = null;
+ v += '&#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);
+ },
+
+ onDestroy: function(){
+ if(this.validationTask){
+ this.validationTask.cancel();
+ this.validationTask = null;
+ }
+ Ext.form.TextField.superclass.onDestroy.call(this);
+ }
+});
+Ext.reg('textfield', Ext.form.TextField);
+
+Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
+
+
+
+ defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
+
+ hideTrigger:false,
+
+ editable: true,
+
+ readOnly: false,
+
+ wrapFocusClass: 'x-trigger-wrap-focus',
+
+ autoSize: Ext.emptyFn,
+
+ monitorTab : true,
+
+ deferHeight : true,
+
+ mimicing : false,
+
+ actionMode: 'wrap',
+
+ defaultTriggerWidth: 17,
+
+
+ onResize : function(w, h){
+ Ext.form.TriggerField.superclass.onResize.call(this, w, h);
+ var tw = this.getTriggerWidth();
+ if(Ext.isNumber(w)){
+ this.el.setWidth(w - tw);
+ }
+ this.wrap.setWidth(this.el.getWidth() + tw);
+ },
+
+ getTriggerWidth: function(){
+ var tw = this.trigger.getWidth();
+ if(!this.hideTrigger && !this.readOnly && tw === 0){
+ tw = this.defaultTriggerWidth;
+ }
+ return tw;
+ },
+
+
+ alignErrorIcon : function(){
+ if(this.wrap){
+ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
+ }
+ },
+
+
+ onRender : function(ct, position){
+ this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
+ Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
+
+ this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
+ this.trigger = this.wrap.createChild(this.triggerConfig ||
+ {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass});
+ this.initTrigger();
+ if(!this.width){
+ this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
+ }
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+
+ getWidth: function() {
+ return(this.el.getWidth() + this.trigger.getWidth());
+ },
+
+ updateEditState: function(){
+ if(this.rendered){
+ if (this.readOnly) {
+ this.el.dom.readOnly = true;
+ this.el.addClass('x-trigger-noedit');
+ this.mun(this.el, 'click', this.onTriggerClick, this);
+ this.trigger.setDisplayed(false);
+ } else {
+ if (!this.editable) {
+ this.el.dom.readOnly = true;
+ this.el.addClass('x-trigger-noedit');
+ this.mon(this.el, 'click', this.onTriggerClick, this);
+ } else {
+ this.el.dom.readOnly = false;
+ this.el.removeClass('x-trigger-noedit');
+ this.mun(this.el, 'click', this.onTriggerClick, this);
+ }
+ this.trigger.setDisplayed(!this.hideTrigger);
+ }
+ this.onResize(this.width || this.wrap.getWidth());
+ }
+ },
+
+
+ setHideTrigger: function(hideTrigger){
+ if(hideTrigger != this.hideTrigger){
+ this.hideTrigger = hideTrigger;
+ this.updateEditState();
+ }
+ },
+
+
+ setEditable: function(editable){
+ if(editable != this.editable){
+ this.editable = editable;
+ this.updateEditState();
+ }
+ },
+
+
+ setReadOnly: function(readOnly){
+ if(readOnly != this.readOnly){
+ this.readOnly = readOnly;
+ this.updateEditState();
+ }
+ },
+
+ afterRender : function(){
+ Ext.form.TriggerField.superclass.afterRender.call(this);
+ this.updateEditState();
+ },
+
+
+ initTrigger : function(){
+ this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
+ this.trigger.addClassOnOver('x-form-trigger-over');
+ this.trigger.addClassOnClick('x-form-trigger-click');
+ },
+
+
+ onDestroy : function(){
+ Ext.destroy(this.trigger, this.wrap);
+ if (this.mimicing){
+ this.doc.un('mousedown', this.mimicBlur, this);
+ }
+ delete this.doc;
+ Ext.form.TriggerField.superclass.onDestroy.call(this);
+ },
+
+
+ onFocus : function(){
+ Ext.form.TriggerField.superclass.onFocus.call(this);
+ if(!this.mimicing){
+ this.wrap.addClass(this.wrapFocusClass);
+ this.mimicing = true;
+ this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
+ if(this.monitorTab){
+ this.on('specialkey', this.checkTab, this);
+ }
+ }
+ },
+
+
+ checkTab : function(me, e){
+ if(e.getKey() == e.TAB){
+ this.triggerBlur();
+ }
+ },
+
+
+ onBlur : Ext.emptyFn,
+
+
+ mimicBlur : function(e){
+ if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
+ this.triggerBlur();
+ }
+ },
+
+
+ triggerBlur : function(){
+ this.mimicing = false;
+ this.doc.un('mousedown', this.mimicBlur, this);
+ if(this.monitorTab && this.el){
+ this.un('specialkey', this.checkTab, this);
+ }
+ Ext.form.TriggerField.superclass.onBlur.call(this);
+ if(this.wrap){
+ this.wrap.removeClass(this.wrapFocusClass);
+ }
+ },
+
+ beforeBlur : Ext.emptyFn,
+
+
+
+ validateBlur : function(e){
+ return true;
+ },
+
+
+ onTriggerClick : Ext.emptyFn
+
+
+
+
+});
+
+
+Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
+
+
+
+
+ initComponent : function(){
+ Ext.form.TwinTriggerField.superclass.initComponent.call(this);
+
+ this.triggerConfig = {
+ tag:'span', cls:'x-form-twin-triggers', cn:[
+ {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class},
+ {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class}
+ ]};
+ },
+
+ getTrigger : function(index){
+ return this.triggers[index];
+ },
+
+ afterRender: function(){
+ Ext.form.TwinTriggerField.superclass.afterRender.call(this);
+ var triggers = this.triggers,
+ i = 0,
+ len = triggers.length;
+
+ for(; i < len; ++i){
+ if(this['hideTrigger' + (i + 1)]){
+ triggers[i].hide();
+ }
+
+ }
+ },
+
+ initTrigger : function(){
+ var ts = this.trigger.select('.x-form-trigger', true),
+ triggerField = this;
+
+ ts.each(function(t, all, index){
+ var triggerIndex = 'Trigger'+(index+1);
+ t.hide = function(){
+ var w = triggerField.wrap.getWidth();
+ this.dom.style.display = 'none';
+ triggerField.el.setWidth(w-triggerField.trigger.getWidth());
+ triggerField['hidden' + triggerIndex] = true;
+ };
+ t.show = function(){
+ var w = triggerField.wrap.getWidth();
+ this.dom.style.display = '';
+ triggerField.el.setWidth(w-triggerField.trigger.getWidth());
+ triggerField['hidden' + triggerIndex] = false;
+ };
+ this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
+ t.addClassOnOver('x-form-trigger-over');
+ t.addClassOnClick('x-form-trigger-click');
+ }, this);
+ this.triggers = ts.elements;
+ },
+
+ getTriggerWidth: function(){
+ var tw = 0;
+ Ext.each(this.triggers, function(t, index){
+ var triggerIndex = 'Trigger' + (index + 1),
+ w = t.getWidth();
+ if(w === 0 && !this['hidden' + triggerIndex]){
+ tw += this.defaultTriggerWidth;
+ }else{
+ tw += w;
+ }
+ }, this);
+ return tw;
+ },
+
+
+ onDestroy : function() {
+ Ext.destroy(this.triggers);
+ Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
+ },
+
+
+ onTrigger1Click : Ext.emptyFn,
+
+ onTrigger2Click : Ext.emptyFn
+});
+Ext.reg('trigger', Ext.form.TriggerField);
+Ext.reg('twintrigger', Ext.form.TwinTriggerField);
+Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
+
+ growMin : 60,
+
+ growMax: 1000,
+ growAppend : '&#160;\n&#160;',
+
+ enterIsSpecial : false,
+
+
+ preventScrollbars: false,
+
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ this.defaultAutoCreate = {
+ tag: "textarea",
+ style:"width:100px;height:60px;",
+ autocomplete: "off"
+ };
+ }
+ Ext.form.TextArea.superclass.onRender.call(this, ct, position);
+ 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);
+ }
+ },
+
+ onDestroy : function(){
+ Ext.removeNode(this.textSizeEl);
+ Ext.form.TextArea.superclass.onDestroy.call(this);
+ },
+
+ fireKey : function(e){
+ if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
+ this.fireEvent("specialkey", this, e);
+ }
+ },
+
+
+ doAutoSize : function(e){
+ return !e.isNavKeyPress() || e.getKey() == e.ENTER;
+ },
+
+
+ filterValidation: function(e) {
+ if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
+ this.validationTask.delay(this.validationDelay);
+ }
+ },
+
+
+ autoSize: function(){
+ if(!this.grow || !this.textSizeEl){
+ return;
+ }
+ var el = this.el,
+ v = Ext.util.Format.htmlEncode(el.dom.value),
+ ts = this.textSizeEl,
+ h;
+
+ Ext.fly(ts).setWidth(this.el.getWidth());
+ if(v.length < 1){
+ v = "&#160;&#160;";
+ }else{
+ v += this.growAppend;
+ if(Ext.isIE){
+ v = v.replace(/\n/g, '&#160;<br />');
+ }
+ }
+ ts.innerHTML = v;
+ h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
+ if(h != this.lastHeight){
+ this.lastHeight = h;
+ this.el.setHeight(h);
+ this.fireEvent("autosize", this, h);
+ }
+ }
+});
+Ext.reg('textarea', Ext.form.TextArea);
+Ext.form.NumberField = Ext.extend(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",
+
+
+ baseChars : "0123456789",
+
+
+ autoStripChars: false,
+
+
+ initEvents : function() {
+ var allowed = this.baseChars + '';
+ if (this.allowDecimals) {
+ allowed += this.decimalSeparator;
+ }
+ if (this.allowNegative) {
+ allowed += '-';
+ }
+ allowed = Ext.escapeRe(allowed);
+ this.maskRe = new RegExp('[' + allowed + ']');
+ if (this.autoStripChars) {
+ this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
+ }
+
+ Ext.form.NumberField.superclass.initEvents.call(this);
+ },
+
+
+ getErrors: function(value) {
+ var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
+
+ value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
+
+ if (value.length < 1) {
+ return errors;
+ }
+
+ value = String(value).replace(this.decimalSeparator, ".");
+
+ if(isNaN(value)){
+ errors.push(String.format(this.nanText, value));
+ }
+
+ var num = this.parseValue(value);
+
+ if (num < this.minValue) {
+ errors.push(String.format(this.minText, this.minValue));
+ }
+
+ if (num > this.maxValue) {
+ errors.push(String.format(this.maxText, this.maxValue));
+ }
+
+ return errors;
+ },
+
+ getValue : function() {
+ return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
+ },
+
+ setValue : function(v) {
+ v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
+ v = this.fixPrecision(v);
+ v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
+ return Ext.form.NumberField.superclass.setValue.call(this, v);
+ },
+
+
+ setMinValue : function(value) {
+ this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
+ },
+
+
+ setMaxValue : function(value) {
+ this.maxValue = Ext.num(value, Number.MAX_VALUE);
+ },
+
+
+ parseValue : function(value) {
+ value = parseFloat(String(value).replace(this.decimalSeparator, "."));
+ return isNaN(value) ? '' : value;
+ },
+
+
+ fixPrecision : function(value) {
+ var nan = isNaN(value);
+
+ if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
+ return nan ? '' : value;
+ }
+
+ return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
+ },
+
+ beforeBlur : function() {
+ var v = this.parseValue(this.getRawValue());
+
+ if (!Ext.isEmpty(v)) {
+ this.setValue(v);
+ }
+ }
+});
+
+Ext.reg('numberfield', Ext.form.NumberField);
+
+Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
+
+ format : "m/d/Y",
+
+ altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",
+
+ disabledDaysText : "Disabled",
+
+ disabledDatesText : "Disabled",
+
+ minText : "The date in this field must be equal to or after {0}",
+
+ maxText : "The date in this field must be equal to or before {0}",
+
+ invalidText : "{0} is not a valid date - it must be in the format {1}",
+
+ triggerClass : 'x-form-date-trigger',
+
+ showToday : true,
+
+
+ startDay : 0,
+
+
+
+
+
+
+
+
+ defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
+
+
+
+ initTime: '12',
+
+ initTimeFormat: 'H',
+
+
+ safeParse : function(value, format) {
+ if (Date.formatContainsHourInfo(format)) {
+
+ return Date.parseDate(value, format);
+ } else {
+
+ var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
+
+ if (parsedDate) {
+ return parsedDate.clearTime();
+ }
+ }
+ },
+
+ initComponent : function(){
+ Ext.form.DateField.superclass.initComponent.call(this);
+
+ this.addEvents(
+
+ 'select'
+ );
+
+ if(Ext.isString(this.minValue)){
+ this.minValue = this.parseDate(this.minValue);
+ }
+ if(Ext.isString(this.maxValue)){
+ this.maxValue = this.parseDate(this.maxValue);
+ }
+ this.disabledDatesRE = null;
+ this.initDisabledDays();
+ },
+
+ initEvents: function() {
+ Ext.form.DateField.superclass.initEvents.call(this);
+ this.keyNav = new Ext.KeyNav(this.el, {
+ "down": function(e) {
+ this.onTriggerClick();
+ },
+ scope: this,
+ forceKeyDown: true
+ });
+ },
+
+
+
+ initDisabledDays : function(){
+ if(this.disabledDates){
+ var dd = this.disabledDates,
+ len = dd.length - 1,
+ re = "(?:";
+
+ Ext.each(dd, function(d, i){
+ re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
+ if(i != len){
+ re += '|';
+ }
+ }, this);
+ this.disabledDatesRE = new RegExp(re + ')');
+ }
+ },
+
+
+ setDisabledDates : function(dd){
+ this.disabledDates = dd;
+ this.initDisabledDays();
+ if(this.menu){
+ this.menu.picker.setDisabledDates(this.disabledDatesRE);
+ }
+ },
+
+
+ setDisabledDays : function(dd){
+ this.disabledDays = dd;
+ if(this.menu){
+ this.menu.picker.setDisabledDays(dd);
+ }
+ },
+
+
+ setMinValue : function(dt){
+ this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
+ if(this.menu){
+ this.menu.picker.setMinDate(this.minValue);
+ }
+ },
+
+
+ setMaxValue : function(dt){
+ this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
+ if(this.menu){
+ this.menu.picker.setMaxDate(this.maxValue);
+ }
+ },
+
+
+ getErrors: function(value) {
+ var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
+
+ value = this.formatDate(value || this.processValue(this.getRawValue()));
+
+ if (value.length < 1) {
+ return errors;
+ }
+
+ var svalue = value;
+ value = this.parseDate(value);
+ if (!value) {
+ errors.push(String.format(this.invalidText, svalue, this.format));
+ return errors;
+ }
+
+ var time = value.getTime();
+ if (this.minValue && time < this.minValue.clearTime().getTime()) {
+ errors.push(String.format(this.minText, this.formatDate(this.minValue)));
+ }
+
+ if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
+ errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
+ }
+
+ if (this.disabledDays) {
+ var day = value.getDay();
+
+ for(var i = 0; i < this.disabledDays.length; i++) {
+ if (day === this.disabledDays[i]) {
+ errors.push(this.disabledDaysText);
+ break;
+ }
+ }
+ }
+
+ var fvalue = this.formatDate(value);
+ if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
+ errors.push(String.format(this.disabledDatesText, fvalue));
+ }
+
+ return errors;
+ },
+
+
+
+ validateBlur : function(){
+ return !this.menu || !this.menu.isVisible();
+ },
+
+
+ getValue : function(){
+ return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
+ },
+
+
+ setValue : function(date){
+ return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
+ },
+
+
+ parseDate : function(value) {
+ if(!value || Ext.isDate(value)){
+ return value;
+ }
+
+ var v = this.safeParse(value, this.format),
+ af = this.altFormats,
+ afa = this.altFormatsArray;
+
+ if (!v && af) {
+ afa = afa || af.split("|");
+
+ for (var i = 0, len = afa.length; i < len && !v; i++) {
+ v = this.safeParse(value, afa[i]);
+ }
+ }
+ return v;
+ },
+
+
+ onDestroy : function(){
+ Ext.destroy(this.menu, this.keyNav);
+ Ext.form.DateField.superclass.onDestroy.call(this);
+ },
+
+
+ formatDate : function(date){
+ return Ext.isDate(date) ? date.dateFormat(this.format) : date;
+ },
+
+
+
+
+ onTriggerClick : function(){
+ if(this.disabled){
+ return;
+ }
+ if(this.menu == null){
+ this.menu = new Ext.menu.DateMenu({
+ hideOnClick: false,
+ focusOnSelect: false
+ });
+ }
+ this.onFocus();
+ Ext.apply(this.menu.picker, {
+ minDate : this.minValue,
+ maxDate : this.maxValue,
+ disabledDatesRE : this.disabledDatesRE,
+ disabledDatesText : this.disabledDatesText,
+ disabledDays : this.disabledDays,
+ disabledDaysText : this.disabledDaysText,
+ format : this.format,
+ showToday : this.showToday,
+ startDay: this.startDay,
+ minText : String.format(this.minText, this.formatDate(this.minValue)),
+ maxText : String.format(this.maxText, this.formatDate(this.maxValue))
+ });
+ this.menu.picker.setValue(this.getValue() || new Date());
+ this.menu.show(this.el, "tl-bl?");
+ this.menuEvents('on');
+ },
+
+
+ menuEvents: function(method){
+ this.menu[method]('select', this.onSelect, this);
+ this.menu[method]('hide', this.onMenuHide, this);
+ this.menu[method]('show', this.onFocus, this);
+ },
+
+ onSelect: function(m, d){
+ this.setValue(d);
+ this.fireEvent('select', this, d);
+ this.menu.hide();
+ },
+
+ onMenuHide: function(){
+ this.focus(false, 60);
+ this.menuEvents('un');
+ },
+
+
+ beforeBlur : function(){
+ var v = this.parseDate(this.getRawValue());
+ if(v){
+ this.setValue(v);
+ }
+ }
+
+
+
+
+
+});
+Ext.reg('datefield', Ext.form.DateField);
+
+Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
+ validationEvent : false,
+ validateOnBlur : false,
+ defaultAutoCreate : {tag: "div"},
+
+ fieldClass : "x-form-display-field",
+
+ htmlEncode: false,
+
+
+ initEvents : Ext.emptyFn,
+
+ isValid : function(){
+ return true;
+ },
+
+ validate : function(){
+ return true;
+ },
+
+ getRawValue : function(){
+ var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
+ if(v === this.emptyText){
+ v = '';
+ }
+ if(this.htmlEncode){
+ v = Ext.util.Format.htmlDecode(v);
+ }
+ return v;
+ },
+
+ getValue : function(){
+ return this.getRawValue();
+ },
+
+ getName: function() {
+ return this.name;
+ },
+
+ setRawValue : function(v){
+ if(this.htmlEncode){
+ v = Ext.util.Format.htmlEncode(v);
+ }
+ return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
+ },
+
+ setValue : function(v){
+ this.setRawValue(v);
+ return this;
+ }
+
+
+
+
+
+
+});
+
+Ext.reg('displayfield', Ext.form.DisplayField);
+
+Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
+
+
+
+
+
+
+
+ defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
+
+
+
+
+
+
+
+ listClass : '',
+
+ selectedClass : 'x-combo-selected',
+
+ listEmptyText: '',
+
+ triggerClass : 'x-form-arrow-trigger',
+
+ shadow : 'sides',
+
+ listAlign : 'tl-bl?',
+
+ maxHeight : 300,
+
+ minHeight : 90,
+
+ triggerAction : 'query',
+
+ minChars : 4,
+
+ autoSelect : true,
+
+ typeAhead : false,
+
+ queryDelay : 500,
+
+ pageSize : 0,
+
+ selectOnFocus : false,
+
+ queryParam : 'query',
+
+ loadingText : 'Loading...',
+
+ resizable : false,
+
+ handleHeight : 8,
+
+ allQuery: '',
+
+ mode: 'remote',
+
+ minListWidth : 70,
+
+ forceSelection : false,
+
+ typeAheadDelay : 250,
+
+
+
+ lazyInit : true,
+
+
+ clearFilterOnReset : true,
+
+
+ submitValue: undefined,
+
+
+
+
+ initComponent : function(){
+ Ext.form.ComboBox.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'expand',
+
+ 'collapse',
+
+
+ 'beforeselect',
+
+ 'select',
+
+ 'beforequery'
+ );
+ if(this.transform){
+ var s = Ext.getDom(this.transform);
+ if(!this.hiddenName){
+ this.hiddenName = s.name;
+ }
+ if(!this.store){
+ this.mode = 'local';
+ var d = [], opts = s.options;
+ for(var i = 0, len = opts.length;i < len; i++){
+ var o = opts[i],
+ value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
+ if(o.selected && Ext.isEmpty(this.value, true)) {
+ this.value = value;
+ }
+ d.push([value, o.text]);
+ }
+ this.store = new Ext.data.ArrayStore({
+ idIndex: 0,
+ fields: ['value', 'text'],
+ data : d,
+ autoDestroy: true
+ });
+ 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);
+ this.render(this.el.parentNode, s);
+ }
+ Ext.removeNode(s);
+ }
+
+ else if(this.store){
+ this.store = Ext.StoreMgr.lookup(this.store);
+ if(this.store.autoCreated){
+ this.displayField = this.valueField = 'field1';
+ if(!this.store.expandData){
+ this.displayField = 'field2';
+ }
+ this.mode = 'local';
+ }
+ }
+
+ this.selectedIndex = -1;
+ if(this.mode == 'local'){
+ if(!Ext.isDefined(this.initialConfig.queryDelay)){
+ this.queryDelay = 10;
+ }
+ if(!Ext.isDefined(this.initialConfig.minChars)){
+ this.minChars = 0;
+ }
+ }
+ },
+
+
+ onRender : function(ct, position){
+ if(this.hiddenName && !Ext.isDefined(this.submitValue)){
+ this.submitValue = false;
+ }
+ Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
+ if(this.hiddenName){
+ this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
+ id: (this.hiddenId || Ext.id())}, 'before', true);
+
+ }
+ if(Ext.isGecko){
+ this.el.dom.setAttribute('autocomplete', 'off');
+ }
+
+ if(!this.lazyInit){
+ this.initList();
+ }else{
+ this.on('focus', this.initList, this, {single: true});
+ }
+ },
+
+
+ initValue : function(){
+ Ext.form.ComboBox.superclass.initValue.call(this);
+ if(this.hiddenField){
+ this.hiddenField.value =
+ Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
+ }
+ },
+
+ getParentZIndex : function(){
+ var zindex;
+ if (this.ownerCt){
+ this.findParentBy(function(ct){
+ zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
+ return !!zindex;
+ });
+ }
+ return zindex;
+ },
+
+ getZIndex : function(listParent){
+ listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
+ var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
+ if(!zindex){
+ zindex = this.getParentZIndex();
+ }
+ return (zindex || 12000) + 5;
+ },
+
+
+ initList : function(){
+ if(!this.list){
+ var cls = 'x-combo-list',
+ listParent = Ext.getDom(this.getListParent() || Ext.getBody());
+
+ this.list = new Ext.Layer({
+ parentEl: listParent,
+ shadow: this.shadow,
+ cls: [cls, this.listClass].join(' '),
+ constrain:false,
+ zindex: this.getZIndex(listParent)
+ });
+
+ var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
+ this.list.setSize(lw, 0);
+ this.list.swallowEvent('mousewheel');
+ this.assetHeight = 0;
+ if(this.syncFont !== false){
+ this.list.setStyle('font-size', this.el.getStyle('font-size'));
+ }
+ if(this.title){
+ this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
+ this.assetHeight += this.header.getHeight();
+ }
+
+ this.innerList = this.list.createChild({cls:cls+'-inner'});
+ this.mon(this.innerList, 'mouseover', this.onViewOver, this);
+ this.mon(this.innerList, 'mousemove', this.onViewMove, this);
+ this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
+
+ if(this.pageSize){
+ this.footer = this.list.createChild({cls:cls+'-ft'});
+ this.pageTb = new Ext.PagingToolbar({
+ store: this.store,
+ pageSize: this.pageSize,
+ renderTo:this.footer
+ });
+ this.assetHeight += this.footer.getHeight();
+ }
+
+ if(!this.tpl){
+
+ this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
+
+ }
+
+
+ this.view = new Ext.DataView({
+ applyTo: this.innerList,
+ tpl: this.tpl,
+ singleSelect: true,
+ selectedClass: this.selectedClass,
+ itemSelector: this.itemSelector || '.' + cls + '-item',
+ emptyText: this.listEmptyText,
+ deferEmptyText: false
+ });
+
+ this.mon(this.view, {
+ containerclick : this.onViewClick,
+ click : this.onViewClick,
+ scope :this
+ });
+
+ this.bindStore(this.store, true);
+
+ if(this.resizable){
+ this.resizer = new Ext.Resizable(this.list, {
+ pinned:true, handles:'se'
+ });
+ this.mon(this.resizer, 'resize', function(r, w, h){
+ this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
+ this.listWidth = w;
+ this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
+ this.restrictHeight();
+ }, this);
+
+ this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
+ }
+ }
+ },
+
+
+ getListParent : function() {
+ return document.body;
+ },
+
+
+ getStore : function(){
+ return this.store;
+ },
+
+
+ bindStore : function(store, initial){
+ if(this.store && !initial){
+ if(this.store !== store && this.store.autoDestroy){
+ this.store.destroy();
+ }else{
+ this.store.un('beforeload', this.onBeforeLoad, this);
+ this.store.un('load', this.onLoad, this);
+ this.store.un('exception', this.collapse, this);
+ }
+ if(!store){
+ this.store = null;
+ if(this.view){
+ this.view.bindStore(null);
+ }
+ if(this.pageTb){
+ this.pageTb.bindStore(null);
+ }
+ }
+ }
+ if(store){
+ if(!initial) {
+ this.lastQuery = null;
+ if(this.pageTb) {
+ this.pageTb.bindStore(store);
+ }
+ }
+
+ this.store = Ext.StoreMgr.lookup(store);
+ this.store.on({
+ scope: this,
+ beforeload: this.onBeforeLoad,
+ load: this.onLoad,
+ exception: this.collapse
+ });
+
+ if(this.view){
+ this.view.bindStore(store);
+ }
+ }
+ },
+
+ reset : function(){
+ if(this.clearFilterOnReset && this.mode == 'local'){
+ this.store.clearFilter();
+ }
+ Ext.form.ComboBox.superclass.reset.call(this);
+ },
+
+
+ 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){
+ if (this.forceSelection === true) {
+ this.collapse();
+ } else {
+ this.onViewClick(false);
+ }
+ return true;
+ },
+
+ scope : this,
+
+ doRelay : function(e, h, hname){
+ if(hname == 'down' || this.scope.isExpanded()){
+
+ var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
+ if((((Ext.isIE9 && Ext.isStrict) || Ext.isIE10p) || !Ext.isIE) && Ext.EventManager.useKeydown){
+
+ this.scope.fireKey(e);
+ }
+ return relay;
+ }
+ return true;
+ },
+
+ forceKeyDown : true,
+ defaultEventAction: 'stopEvent'
+ });
+ 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.enableKeyEvents){
+ this.mon(this.el, 'keyup', this.onKeyUp, this);
+ }
+ },
+
+
+
+ onDestroy : function(){
+ if (this.dqTask){
+ this.dqTask.cancel();
+ this.dqTask = null;
+ }
+ this.bindStore(null);
+ Ext.destroy(
+ this.resizer,
+ this.view,
+ this.pageTb,
+ this.list
+ );
+ Ext.destroyMembers(this, 'hiddenField');
+ Ext.form.ComboBox.superclass.onDestroy.call(this);
+ },
+
+
+ fireKey : function(e){
+ if (!this.isExpanded()) {
+ Ext.form.ComboBox.superclass.fireKey.call(this, e);
+ }
+ },
+
+
+ onResize : function(w, h){
+ Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
+ if(!isNaN(w) && this.isVisible() && this.list){
+ this.doResize(w);
+ }else{
+ this.bufferSize = w;
+ }
+ },
+
+ doResize: function(w){
+ if(!Ext.isDefined(this.listWidth)){
+ var lw = Math.max(w, this.minListWidth);
+ this.list.setWidth(lw);
+ this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
+ }
+ },
+
+
+ onEnable : function(){
+ Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
+ if(this.hiddenField){
+ this.hiddenField.disabled = false;
+ }
+ },
+
+
+ onDisable : function(){
+ Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
+ if(this.hiddenField){
+ this.hiddenField.disabled = true;
+ }
+ },
+
+
+ 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.listEmptyText){
+ this.expand();
+ this.restrictHeight();
+ if(this.lastQuery == this.allQuery){
+ if(this.editable){
+ this.el.dom.select();
+ }
+
+ if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
+ this.select(0, true);
+ }
+ }else{
+ if(this.autoSelect !== false){
+ this.selectNext();
+ }
+ if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
+ this.taTask.delay(this.typeAheadDelay);
+ }
+ }
+ }else{
+ this.collapse();
+ }
+
+ },
+
+
+ onTypeAhead : function(){
+ if(this.store.getCount() > 0){
+ var r = this.store.getAt(0);
+ var newValue = r.data[this.displayField];
+ var len = newValue.length;
+ var selStart = this.getRawValue().length;
+ if(selStart != len){
+ this.setRawValue(newValue);
+ this.selectText(selStart, newValue.length);
+ }
+ }
+ },
+
+
+ assertValue : function(){
+ var val = this.getRawValue(),
+ rec;
+
+ if(this.valueField && Ext.isDefined(this.value)){
+ rec = this.findRecord(this.valueField, this.value);
+ }
+ if(!rec || rec.get(this.displayField) != val){
+ rec = this.findRecord(this.displayField, val);
+ }
+ if(!rec && this.forceSelection){
+ if(val.length > 0 && val != this.emptyText){
+ this.el.dom.value = Ext.value(this.lastSelectionText, '');
+ this.applyEmptyText();
+ }else{
+ this.clearValue();
+ }
+ }else{
+ if(rec && this.valueField){
+
+
+
+ if (this.value == val){
+ return;
+ }
+ val = rec.get(this.valueField || this.displayField);
+ }
+ this.setValue(val);
+ }
+ },
+
+
+ onSelect : function(record, index){
+ if(this.fireEvent('beforeselect', this, record, index) !== false){
+ this.setValue(record.data[this.valueField || this.displayField]);
+ this.collapse();
+ this.fireEvent('select', this, record, index);
+ }
+ },
+
+
+ getName: function(){
+ var hf = this.hiddenField;
+ return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
+ },
+
+
+ getValue : function(){
+ if(this.valueField){
+ return Ext.isDefined(this.value) ? this.value : '';
+ }else{
+ return Ext.form.ComboBox.superclass.getValue.call(this);
+ }
+ },
+
+
+ clearValue : function(){
+ if(this.hiddenField){
+ this.hiddenField.value = '';
+ }
+ this.setRawValue('');
+ this.lastSelectionText = '';
+ this.applyEmptyText();
+ this.value = '';
+ },
+
+
+ setValue : function(v){
+ var text = v;
+ if(this.valueField){
+ var r = this.findRecord(this.valueField, v);
+ if(r){
+ text = r.data[this.displayField];
+ }else if(Ext.isDefined(this.valueNotFoundText)){
+ text = this.valueNotFoundText;
+ }
+ }
+ this.lastSelectionText = text;
+ if(this.hiddenField){
+ this.hiddenField.value = Ext.value(v, '');
+ }
+ Ext.form.ComboBox.superclass.setValue.call(this, text);
+ this.value = v;
+ return this;
+ },
+
+
+ findRecord : function(prop, value){
+ var record;
+ if(this.store.getCount() > 0){
+ this.store.each(function(r){
+ if(r.data[prop] == value){
+ record = r;
+ return false;
+ }
+ });
+ }
+ return record;
+ },
+
+
+ onViewMove : function(e, t){
+ this.inKeyMode = false;
+ },
+
+
+ onViewOver : function(e, t){
+ if(this.inKeyMode){
+ return;
+ }
+ var item = this.view.findItemFromChild(t);
+ if(item){
+ var index = this.view.indexOf(item);
+ this.select(index, false);
+ }
+ },
+
+
+ onViewClick : function(doFocus){
+ var index = this.view.getSelectedIndexes()[0],
+ s = this.store,
+ r = s.getAt(index);
+ if(r){
+ this.onSelect(r, index);
+ }else {
+ this.collapse();
+ }
+ if(doFocus !== false){
+ this.el.focus();
+ }
+ },
+
+
+
+ restrictHeight : function(){
+ this.innerList.dom.style.height = '';
+ var inner = this.innerList.dom,
+ pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
+ h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
+ ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
+ hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
+ space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
+
+ h = Math.min(h, space, this.maxHeight);
+
+ this.innerList.setHeight(h);
+ this.list.beginUpdate();
+ this.list.setHeight(h+pad);
+ this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
+ this.list.endUpdate();
+ },
+
+
+ isExpanded : function(){
+ return this.list && this.list.isVisible();
+ },
+
+
+ selectByValue : function(v, scrollIntoView){
+ if(!Ext.isEmpty(v, true)){
+ var r = this.findRecord(this.valueField || this.displayField, v);
+ if(r){
+ this.select(this.store.indexOf(r), scrollIntoView);
+ return true;
+ }
+ }
+ return false;
+ },
+
+
+ select : function(index, scrollIntoView){
+ this.selectedIndex = index;
+ this.view.select(index);
+ if(scrollIntoView !== false){
+ var el = this.view.getNode(index);
+ if(el){
+ this.innerList.scrollChildIntoView(el, false);
+ }
+ }
+
+ },
+
+
+ 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){
+ var k = e.getKey();
+ if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
+
+ this.lastKey = k;
+ this.dqTask.delay(this.queryDelay);
+ }
+ Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
+ },
+
+
+ validateBlur : function(){
+ return !this.list || !this.list.isVisible();
+ },
+
+
+ initQuery : function(){
+ this.doQuery(this.getRawValue());
+ },
+
+
+ beforeBlur : function(){
+ this.assertValue();
+ },
+
+
+ postBlur : function(){
+ Ext.form.ComboBox.superclass.postBlur.call(this);
+ this.collapse();
+ this.inKeyMode = false;
+ },
+
+
+ doQuery : function(q, forceAll){
+ q = Ext.isEmpty(q) ? '' : q;
+ var qe = {
+ query: q,
+ forceAll: forceAll,
+ combo: this,
+ cancel:false
+ };
+ if(this.fireEvent('beforequery', qe)===false || qe.cancel){
+ return false;
+ }
+ q = qe.query;
+ forceAll = qe.forceAll;
+ if(forceAll === true || (q.length >= this.minChars)){
+ if(this.lastQuery !== q){
+ this.lastQuery = q;
+ if(this.mode == 'local'){
+ this.selectedIndex = -1;
+ if(forceAll){
+ 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 params = {},
+ paramNames = this.store.paramNames;
+ if(this.pageSize){
+ params[paramNames.start] = 0;
+ params[paramNames.limit] = this.pageSize;
+ }
+ return params;
+ },
+
+
+ collapse : function(){
+ if(!this.isExpanded()){
+ return;
+ }
+ this.list.hide();
+ Ext.getDoc().un('mousewheel', this.collapseIf, this);
+ Ext.getDoc().un('mousedown', this.collapseIf, this);
+ this.fireEvent('collapse', this);
+ },
+
+
+ collapseIf : function(e){
+ if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
+ this.collapse();
+ }
+ },
+
+
+ expand : function(){
+ if(this.isExpanded() || !this.hasFocus){
+ return;
+ }
+
+ if(this.title || this.pageSize){
+ this.assetHeight = 0;
+ if(this.title){
+ this.assetHeight += this.header.getHeight();
+ }
+ if(this.pageSize){
+ this.assetHeight += this.footer.getHeight();
+ }
+ }
+
+ if(this.bufferSize){
+ this.doResize(this.bufferSize);
+ delete this.bufferSize;
+ }
+ this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
+
+
+ this.list.setZIndex(this.getZIndex());
+ this.list.show();
+ if(Ext.isGecko2){
+ this.innerList.setOverflow('auto');
+ }
+ this.mon(Ext.getDoc(), {
+ scope: this,
+ mousewheel: this.collapseIf,
+ mousedown: this.collapseIf
+ });
+ this.fireEvent('expand', this);
+ },
+
+
+
+
+ onTriggerClick : function(){
+ if(this.readOnly || this.disabled){
+ return;
+ }
+ if(this.isExpanded()){
+ this.collapse();
+ this.el.focus();
+ }else {
+ this.onFocus({});
+ if(this.triggerAction == 'all') {
+ this.doQuery(this.allQuery, true);
+ } else {
+ this.doQuery(this.getRawValue());
+ }
+ this.el.focus();
+ }
+ }
+
+
+
+
+
+
+});
+Ext.reg('combo', Ext.form.ComboBox);
+
+Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
+
+ focusClass : undefined,
+
+ fieldClass : 'x-form-field',
+
+ checked : false,
+
+ boxLabel: '&#160;',
+
+ defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
+
+
+
+
+
+ actionMode : 'wrap',
+
+
+ initComponent : function(){
+ Ext.form.Checkbox.superclass.initComponent.call(this);
+ this.addEvents(
+
+ 'check'
+ );
+ },
+
+
+ onResize : function(){
+ Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
+ if(!this.boxLabel && !this.fieldLabel){
+ this.el.alignTo(this.wrap, 'c-c');
+ }
+ },
+
+
+ initEvents : function(){
+ Ext.form.Checkbox.superclass.initEvents.call(this);
+ this.mon(this.el, {
+ scope: this,
+ click: this.onClick,
+ change: this.onClick
+ });
+ },
+
+
+ markInvalid : Ext.emptyFn,
+
+ clearInvalid : Ext.emptyFn,
+
+
+ onRender : function(ct, position){
+ Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
+ 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);
+ }else{
+ this.checked = this.el.dom.checked;
+ }
+
+ if (Ext.isIEQuirks) {
+ this.wrap.repaint();
+ }
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+
+
+ onDestroy : function(){
+ Ext.destroy(this.wrap);
+ Ext.form.Checkbox.superclass.onDestroy.call(this);
+ },
+
+
+ initValue : function() {
+ this.originalValue = this.getValue();
+ },
+
+
+ getValue : function(){
+ if(this.rendered){
+ return this.el.dom.checked;
+ }
+ return this.checked;
+ },
+
+
+ onClick : function(){
+ if(this.el.dom.checked != this.checked){
+ this.setValue(this.el.dom.checked);
+ }
+ },
+
+
+ setValue : function(v){
+ var checked = this.checked,
+ inputVal = this.inputValue;
+
+ if (v === false) {
+ this.checked = false;
+ } else {
+ this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
+ }
+
+ if(this.rendered){
+ this.el.dom.checked = this.checked;
+ this.el.dom.defaultChecked = this.checked;
+ }
+ if(checked != this.checked){
+ this.fireEvent('check', this, this.checked);
+ if(this.handler){
+ this.handler.call(this.scope || this, this, this.checked);
+ }
+ }
+ return this;
+ }
+});
+Ext.reg('checkbox', Ext.form.Checkbox);
+
+Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
+
+
+ columns : 'auto',
+
+ vertical : false,
+
+ allowBlank : true,
+
+ blankText : "You must select at least one item in this group",
+
+
+ defaultType : 'checkbox',
+
+
+ groupCls : 'x-form-check-group',
+
+
+ initComponent: function(){
+ this.addEvents(
+
+ 'change'
+ );
+ this.on('change', this.validate, this);
+ Ext.form.CheckboxGroup.superclass.initComponent.call(this);
+ },
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ var panelCfg = {
+ autoEl: {
+ id: this.id
+ },
+ cls: this.groupCls,
+ layout: 'column',
+ renderTo: ct,
+ bufferResize: false
+ };
+ var colCfg = {
+ xtype: 'container',
+ defaultType: this.defaultType,
+ layout: 'form',
+ defaults: {
+ hideLabel: true,
+ anchor: '100%'
+ }
+ };
+
+ if(this.items[0].items){
+
+
+
+ Ext.apply(panelCfg, {
+ layoutConfig: {columns: this.items.length},
+ defaults: this.defaults,
+ items: this.items
+ });
+ for(var i=0, len=this.items.length; i<len; i++){
+ Ext.applyIf(this.items[i], colCfg);
+ }
+
+ }else{
+
+
+
+
+ var numCols, cols = [];
+
+ if(typeof this.columns == 'string'){
+ this.columns = this.items.length;
+ }
+ if(!Ext.isArray(this.columns)){
+ var cs = [];
+ for(var i=0; i<this.columns; i++){
+ cs.push((100/this.columns)*.01);
+ }
+ this.columns = cs;
+ }
+
+ numCols = this.columns.length;
+
+
+ for(var i=0; i<numCols; i++){
+ var cc = Ext.apply({items:[]}, colCfg);
+ cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
+ if(this.defaults){
+ cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
+ }
+ cols.push(cc);
+ };
+
+
+ if(this.vertical){
+ var rows = Math.ceil(this.items.length / numCols), ri = 0;
+ for(var i=0, len=this.items.length; i<len; i++){
+ if(i>0 && i%rows==0){
+ ri++;
+ }
+ if(this.items[i].fieldLabel){
+ this.items[i].hideLabel = false;
+ }
+ cols[ri].items.push(this.items[i]);
+ };
+ }else{
+ for(var i=0, len=this.items.length; i<len; i++){
+ var ci = i % numCols;
+ if(this.items[i].fieldLabel){
+ this.items[i].hideLabel = false;
+ }
+ cols[ci].items.push(this.items[i]);
+ };
+ }
+
+ Ext.apply(panelCfg, {
+ layoutConfig: {columns: numCols},
+ items: cols
+ });
+ }
+
+ this.panel = new Ext.Container(panelCfg);
+ this.panel.ownerCt = this;
+ this.el = this.panel.getEl();
+
+ if(this.forId && this.itemCls){
+ var l = this.el.up(this.itemCls).child('label', true);
+ if(l){
+ l.setAttribute('htmlFor', this.forId);
+ }
+ }
+
+ var fields = this.panel.findBy(function(c){
+ return c.isFormField;
+ }, this);
+
+ this.items = new Ext.util.MixedCollection();
+ this.items.addAll(fields);
+ }
+ Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
+ },
+
+ initValue : function(){
+ if(this.value){
+ this.setValue.apply(this, this.buffered ? this.value : [this.value]);
+ delete this.buffered;
+ delete this.value;
+ }
+ },
+
+ afterRender : function(){
+ Ext.form.CheckboxGroup.superclass.afterRender.call(this);
+ this.eachItem(function(item){
+ item.on('check', this.fireChecked, this);
+ item.inGroup = true;
+ });
+ },
+
+
+ doLayout: function(){
+
+ if(this.rendered){
+ this.panel.forceLayout = this.ownerCt.forceLayout;
+ this.panel.doLayout();
+ }
+ },
+
+
+ fireChecked: function(){
+ var arr = [];
+ this.eachItem(function(item){
+ if(item.checked){
+ arr.push(item);
+ }
+ });
+ this.fireEvent('change', this, arr);
+ },
+
+
+ getErrors: function() {
+ var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
+
+ if (!this.allowBlank) {
+ var blank = true;
+
+ this.eachItem(function(f){
+ if (f.checked) {
+ return (blank = false);
+ }
+ });
+
+ if (blank) errors.push(this.blankText);
+ }
+
+ return errors;
+ },
+
+
+ isDirty: function(){
+
+ if (this.disabled || !this.rendered) {
+ return false;
+ }
+
+ var dirty = false;
+
+ this.eachItem(function(item){
+ if(item.isDirty()){
+ dirty = true;
+ return false;
+ }
+ });
+
+ return dirty;
+ },
+
+
+ setReadOnly : function(readOnly){
+ if(this.rendered){
+ this.eachItem(function(item){
+ item.setReadOnly(readOnly);
+ });
+ }
+ this.readOnly = readOnly;
+ },
+
+
+ onDisable : function(){
+ this.eachItem(function(item){
+ item.disable();
+ });
+ },
+
+
+ onEnable : function(){
+ this.eachItem(function(item){
+ item.enable();
+ });
+ },
+
+
+ onResize : function(w, h){
+ this.panel.setSize(w, h);
+ this.panel.doLayout();
+ },
+
+
+ reset : function(){
+ if (this.originalValue) {
+
+ this.eachItem(function(c){
+ if(c.setValue){
+ c.setValue(false);
+ c.originalValue = c.getValue();
+ }
+ });
+
+
+ this.resetOriginal = true;
+ this.setValue(this.originalValue);
+ delete this.resetOriginal;
+ } else {
+ this.eachItem(function(c){
+ if(c.reset){
+ c.reset();
+ }
+ });
+ }
+
+
+ (function() {
+ this.clearInvalid();
+ }).defer(50, this);
+ },
+
+
+ setValue: function(){
+ if(this.rendered){
+ this.onSetValue.apply(this, arguments);
+ }else{
+ this.buffered = true;
+ this.value = arguments;
+ }
+ return this;
+ },
+
+
+ onSetValue: function(id, value){
+ if(arguments.length == 1){
+ if(Ext.isArray(id)){
+ Ext.each(id, function(val, idx){
+ if (Ext.isObject(val) && val.setValue){
+ val.setValue(true);
+ if (this.resetOriginal === true) {
+ val.originalValue = val.getValue();
+ }
+ } else {
+ var item = this.items.itemAt(idx);
+ if(item){
+ item.setValue(val);
+ }
+ }
+ }, this);
+ }else if(Ext.isObject(id)){
+
+ for(var i in id){
+ var f = this.getBox(i);
+ if(f){
+ f.setValue(id[i]);
+ }
+ }
+ }else{
+ this.setValueForItem(id);
+ }
+ }else{
+ var f = this.getBox(id);
+ if(f){
+ f.setValue(value);
+ }
+ }
+ },
+
+
+ beforeDestroy: function(){
+ Ext.destroy(this.panel);
+ if (!this.rendered) {
+ Ext.destroy(this.items);
+ }
+ Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
+
+ },
+
+ setValueForItem : function(val){
+ val = String(val).split(',');
+ this.eachItem(function(item){
+ if(val.indexOf(item.inputValue)> -1){
+ item.setValue(true);
+ }
+ });
+ },
+
+
+ getBox : function(id){
+ var box = null;
+ this.eachItem(function(f){
+ if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
+ box = f;
+ return false;
+ }
+ });
+ return box;
+ },
+
+
+ getValue : function(){
+ var out = [];
+ this.eachItem(function(item){
+ if(item.checked){
+ out.push(item);
+ }
+ });
+ return out;
+ },
+
+
+ eachItem: function(fn, scope) {
+ if(this.items && this.items.each){
+ this.items.each(fn, scope || this);
+ }
+ },
+
+
+
+
+ getRawValue : Ext.emptyFn,
+
+
+ setRawValue : Ext.emptyFn
+
+});
+
+Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
+
+Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
+
+
+ defaultMargins: '0 5 0 0',
+
+
+ skipLastItemMargin: true,
+
+
+ isComposite: true,
+
+
+ combineErrors: true,
+
+
+ labelConnector: ', ',
+
+
+
+
+
+ initComponent: function() {
+ var labels = [],
+ items = this.items,
+ item;
+
+ for (var i=0, j = items.length; i < j; i++) {
+ item = items[i];
+
+ if (!Ext.isEmpty(item.ref)){
+ item.ref = '../' + item.ref;
+ }
+
+ labels.push(item.fieldLabel);
+
+
+ Ext.applyIf(item, this.defaults);
+
+
+ if (!(i == j - 1 && this.skipLastItemMargin)) {
+ Ext.applyIf(item, {margins: this.defaultMargins});
+ }
+ }
+
+ this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
+
+
+ this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
+ return item.field;
+ });
+
+ this.fieldErrors.on({
+ scope : this,
+ add : this.updateInvalidMark,
+ remove : this.updateInvalidMark,
+ replace: this.updateInvalidMark
+ });
+
+ Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
+
+ this.innerCt = new Ext.Container({
+ layout : 'hbox',
+ items : this.items,
+ cls : 'x-form-composite',
+ defaultMargins: '0 3 0 0',
+ ownerCt: this
+ });
+ delete this.innerCt.ownerCt;
+
+ var fields = this.innerCt.findBy(function(c) {
+ return c.isFormField;
+ }, this);
+
+
+ this.items = new Ext.util.MixedCollection();
+ this.items.addAll(fields);
+
+ },
+
+
+ onRender: function(ct, position) {
+ if (!this.el) {
+
+ var innerCt = this.innerCt;
+ innerCt.render(ct);
+ this.innerCt.ownerCt = this;
+
+ this.el = innerCt.getEl();
+
+
+
+ if (this.combineErrors) {
+ this.eachItem(function(field) {
+ Ext.apply(field, {
+ markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
+ clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
+ });
+ });
+ }
+
+
+ var l = this.el.parent().parent().child('label', true);
+ if (l) {
+ l.setAttribute('for', this.items.items[0].id);
+ }
+ }
+
+ Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
+ },
+
+
+ onFieldMarkInvalid: function(field, message) {
+ var name = field.getName(),
+ error = {
+ field: name,
+ errorName: field.fieldLabel || name,
+ error: message
+ };
+
+ this.fieldErrors.replace(name, error);
+
+ if (!field.preventMark) {
+ field.el.addClass(field.invalidClass);
+ }
+ },
+
+
+ onFieldClearInvalid: function(field) {
+ this.fieldErrors.removeKey(field.getName());
+
+ field.el.removeClass(field.invalidClass);
+ },
+
+
+ updateInvalidMark: function() {
+ var ieStrict = Ext.isIE6 && Ext.isStrict;
+
+ if (this.fieldErrors.length == 0) {
+ this.clearInvalid();
+
+
+ if (ieStrict) {
+ this.clearInvalid.defer(50, this);
+ }
+ } else {
+ var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
+
+ this.sortErrors();
+ this.markInvalid(message);
+
+
+ if (ieStrict) {
+ this.markInvalid(message);
+ }
+ }
+ },
+
+
+ validateValue: function(value, preventMark) {
+ var valid = true;
+
+ this.eachItem(function(field) {
+ if (!field.isValid(preventMark)) {
+ valid = false;
+ }
+ });
+
+ return valid;
+ },
+
+
+ buildCombinedErrorMessage: function(errors) {
+ var combined = [],
+ error;
+
+ for (var i = 0, j = errors.length; i < j; i++) {
+ error = errors[i];
+
+ combined.push(String.format("{0}: {1}", error.errorName, error.error));
+ }
+
+ return combined.join("<br />");
+ },
+
+
+ sortErrors: function() {
+ var fields = this.items;
+
+ this.fieldErrors.sort("ASC", function(a, b) {
+ var findByName = function(key) {
+ return function(field) {
+ return field.getName() == key;
+ };
+ };
+
+ var aIndex = fields.findIndexBy(findByName(a.field)),
+ bIndex = fields.findIndexBy(findByName(b.field));
+
+ return aIndex < bIndex ? -1 : 1;
+ });
+ },
+
+
+ reset: function() {
+ this.eachItem(function(item) {
+ item.reset();
+ });
+
+
+
+ (function() {
+ this.clearInvalid();
+ }).defer(50, this);
+ },
+
+
+ clearInvalidChildren: function() {
+ this.eachItem(function(item) {
+ item.clearInvalid();
+ });
+ },
+
+
+ buildLabel: function(segments) {
+ return Ext.clean(segments).join(this.labelConnector);
+ },
+
+
+ isDirty: function(){
+
+ if (this.disabled || !this.rendered) {
+ return false;
+ }
+
+ var dirty = false;
+ this.eachItem(function(item){
+ if(item.isDirty()){
+ dirty = true;
+ return false;
+ }
+ });
+ return dirty;
+ },
+
+
+ eachItem: function(fn, scope) {
+ if(this.items && this.items.each){
+ this.items.each(fn, scope || this);
+ }
+ },
+
+
+ onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
+ var innerCt = this.innerCt;
+
+ if (this.rendered && innerCt.rendered) {
+ innerCt.setSize(adjWidth, adjHeight);
+ }
+
+ Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
+ },
+
+
+ doLayout: function(shallow, force) {
+ if (this.rendered) {
+ var innerCt = this.innerCt;
+
+ innerCt.forceLayout = this.ownerCt.forceLayout;
+ innerCt.doLayout(shallow, force);
+ }
+ },
+
+
+ beforeDestroy: function(){
+ Ext.destroy(this.innerCt);
+
+ Ext.form.CompositeField.superclass.beforeDestroy.call(this);
+ },
+
+
+ setReadOnly : function(readOnly) {
+ if (readOnly == undefined) {
+ readOnly = true;
+ }
+ readOnly = !!readOnly;
+
+ if(this.rendered){
+ this.eachItem(function(item){
+ item.setReadOnly(readOnly);
+ });
+ }
+ this.readOnly = readOnly;
+ },
+
+ onShow : function() {
+ Ext.form.CompositeField.superclass.onShow.call(this);
+ this.doLayout();
+ },
+
+
+ onDisable : function(){
+ this.eachItem(function(item){
+ item.disable();
+ });
+ },
+
+
+ onEnable : function(){
+ this.eachItem(function(item){
+ item.enable();
+ });
+ }
+});
+
+Ext.reg('compositefield', Ext.form.CompositeField);
+Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
+ inputType: 'radio',
+
+
+ markInvalid : Ext.emptyFn,
+
+ clearInvalid : Ext.emptyFn,
+
+
+ getGroupValue : function(){
+ var p = this.el.up('form') || Ext.getBody();
+ var c = p.child('input[name="'+this.el.dom.name+'"]:checked', true);
+ return c ? c.value : null;
+ },
+
+
+ setValue : function(v){
+ var checkEl,
+ els,
+ radio;
+ if (typeof v == 'boolean') {
+ Ext.form.Radio.superclass.setValue.call(this, v);
+ } else if (this.rendered) {
+ checkEl = this.getCheckEl();
+ radio = checkEl.child('input[name="' + this.el.dom.name + '"][value="' + v + '"]', true);
+ if(radio){
+ Ext.getCmp(radio.id).setValue(true);
+ }
+ }
+ if(this.rendered && this.checked){
+ checkEl = checkEl || this.getCheckEl();
+ els = this.getCheckEl().select('input[name="' + this.el.dom.name + '"]');
+ els.each(function(el){
+ if(el.dom.id != this.id){
+ Ext.getCmp(el.dom.id).setValue(false);
+ }
+ }, this);
+ }
+ return this;
+ },
+
+
+ getCheckEl: function(){
+ if(this.inGroup){
+ return this.el.up('.x-form-radio-group');
+ }
+ return this.el.up('form') || Ext.getBody();
+ }
+});
+Ext.reg('radio', Ext.form.Radio);
+
+Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
+
+
+ allowBlank : true,
+
+ blankText : 'You must select one item in this group',
+
+
+ defaultType : 'radio',
+
+
+ groupCls : 'x-form-radio-group',
+
+
+
+
+ getValue : function(){
+ var out = null;
+ this.eachItem(function(item){
+ if(item.checked){
+ out = item;
+ return false;
+ }
+ });
+ return out;
+ },
+
+
+ onSetValue : function(id, value){
+ if(arguments.length > 1){
+ var f = this.getBox(id);
+ if(f){
+ f.setValue(value);
+ if(f.checked){
+ this.eachItem(function(item){
+ if (item !== f){
+ item.setValue(false);
+ }
+ });
+ }
+ }
+ }else{
+ this.setValueForItem(id);
+ }
+ },
+
+ setValueForItem : function(val){
+ val = String(val).split(',')[0];
+ this.eachItem(function(item){
+ item.setValue(val == item.inputValue);
+ });
+ },
+
+
+ fireChecked : function(){
+ if(!this.checkTask){
+ this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
+ }
+ this.checkTask.delay(10);
+ },
+
+
+ bufferChecked : function(){
+ var out = null;
+ this.eachItem(function(item){
+ if(item.checked){
+ out = item;
+ return false;
+ }
+ });
+ this.fireEvent('change', this, out);
+ },
+
+ onDestroy : function(){
+ if(this.checkTask){
+ this.checkTask.cancel();
+ this.checkTask = null;
+ }
+ Ext.form.RadioGroup.superclass.onDestroy.call(this);
+ }
+
+});
+
+Ext.reg('radiogroup', Ext.form.RadioGroup);
+
+Ext.form.Hidden = Ext.extend(Ext.form.Field, {
+
+ inputType : 'hidden',
+
+ shouldLayout: false,
+
+
+ onRender : function(){
+ Ext.form.Hidden.superclass.onRender.apply(this, arguments);
+ },
+
+
+ initEvents : function(){
+ this.originalValue = this.getValue();
+ },
+
+
+ setSize : Ext.emptyFn,
+ setWidth : Ext.emptyFn,
+ setHeight : Ext.emptyFn,
+ setPosition : Ext.emptyFn,
+ setPagePosition : Ext.emptyFn,
+ markInvalid : Ext.emptyFn,
+ clearInvalid : Ext.emptyFn
+});
+Ext.reg('hidden', Ext.form.Hidden);
+Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
+
+ constructor: function(el, config){
+ Ext.apply(this, config);
+ if(Ext.isString(this.paramOrder)){
+ this.paramOrder = this.paramOrder.split(/[\s,|]/);
+ }
+
+ this.items = new Ext.util.MixedCollection(false, function(o){
+ return o.getItemId();
+ });
+ this.addEvents(
+
+ 'beforeaction',
+
+ 'actionfailed',
+
+ 'actioncomplete'
+ );
+
+ if(el){
+ this.initEl(el);
+ }
+ Ext.form.BasicForm.superclass.constructor.call(this);
+ },
+
+
+
+
+
+
+
+
+ timeout: 30,
+
+
+
+
+ paramOrder: undefined,
+
+
+ paramsAsHash: false,
+
+
+ waitTitle: 'Please Wait...',
+
+
+ activeAction : null,
+
+
+ trackResetOnLoad : false,
+
+
+
+
+
+ initEl : function(el){
+ this.el = Ext.get(el);
+ this.id = this.el.id || Ext.id();
+ if(!this.standardSubmit){
+ this.el.on('submit', this.onSubmit, this);
+ }
+ this.el.addClass('x-form');
+ },
+
+
+ getEl: function(){
+ return this.el;
+ },
+
+
+ onSubmit : function(e){
+ e.stopEvent();
+ },
+
+
+ destroy: function(bound){
+ if(bound !== true){
+ this.items.each(function(f){
+ Ext.destroy(f);
+ });
+ Ext.destroy(this.el);
+ }
+ this.items.clear();
+ this.purgeListeners();
+ },
+
+
+ isValid : function(){
+ var valid = true;
+ this.items.each(function(f){
+ if(!f.validate()){
+ valid = false;
+ }
+ });
+ return valid;
+ },
+
+
+ isDirty : function(){
+ var dirty = false;
+ this.items.each(function(f){
+ if(f.isDirty()){
+ dirty = true;
+ return false;
+ }
+ });
+ return dirty;
+ },
+
+
+ doAction : function(action, options){
+ if(Ext.isString(action)){
+ action = new Ext.form.Action.ACTION_TYPES[action](this, options);
+ }
+ if(this.fireEvent('beforeaction', this, action) !== false){
+ this.beforeAction(action);
+ action.run.defer(100, action);
+ }
+ return this;
+ },
+
+
+ submit : function(options){
+ options = options || {};
+ if(this.standardSubmit){
+ var v = options.clientValidation === false || this.isValid();
+ if(v){
+ var el = this.el.dom;
+ if(this.url && Ext.isEmpty(el.action)){
+ el.action = this.url;
+ }
+ el.submit();
+ }
+ return v;
+ }
+ var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
+ this.doAction(submitAction, options);
+ return this;
+ },
+
+
+ load : function(options){
+ var loadAction = String.format('{0}load', this.api ? 'direct' : '');
+ this.doAction(loadAction, options);
+ return this;
+ },
+
+
+ updateRecord : function(record){
+ record.beginEdit();
+ var fs = record.fields,
+ field,
+ value;
+ fs.each(function(f){
+ field = this.findField(f.name);
+ if(field){
+ value = field.getValue();
+ if (Ext.type(value) !== false && value.getGroupValue) {
+ value = value.getGroupValue();
+ } else if ( field.eachItem ) {
+ value = [];
+ field.eachItem(function(item){
+ value.push(item.getValue());
+ });
+ }
+ record.set(f.name, value);
+ }
+ }, this);
+ record.endEdit();
+ return this;
+ },
+
+
+ loadRecord : function(record){
+ this.setValues(record.data);
+ return this;
+ },
+
+
+ beforeAction : function(action){
+
+ this.items.each(function(f){
+ if(f.isFormField && f.syncValue){
+ f.syncValue();
+ }
+ });
+ var o = action.options;
+ if(o.waitMsg){
+ if(this.waitMsgTarget === true){
+ this.el.mask(o.waitMsg, 'x-mask-loading');
+ }else if(this.waitMsgTarget){
+ this.waitMsgTarget = Ext.get(this.waitMsgTarget);
+ this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
+ }else{
+ Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
+ }
+ }
+ },
+
+
+ afterAction : function(action, success){
+ this.activeAction = null;
+ var o = action.options;
+ if(o.waitMsg){
+ if(this.waitMsgTarget === true){
+ this.el.unmask();
+ }else if(this.waitMsgTarget){
+ this.waitMsgTarget.unmask();
+ }else{
+ Ext.MessageBox.updateProgress(1);
+ Ext.MessageBox.hide();
+ }
+ }
+ if(success){
+ if(o.reset){
+ this.reset();
+ }
+ Ext.callback(o.success, o.scope, [this, action]);
+ this.fireEvent('actioncomplete', this, action);
+ }else{
+ Ext.callback(o.failure, o.scope, [this, action]);
+ this.fireEvent('actionfailed', this, action);
+ }
+ },
+
+
+ findField : function(id) {
+ var field = this.items.get(id);
+
+ if (!Ext.isObject(field)) {
+
+ var findMatchingField = function(f) {
+ if (f.isFormField) {
+ if (f.dataIndex == id || f.id == id || f.getName() == id) {
+ field = f;
+ return false;
+ } else if (f.isComposite) {
+ return f.items.each(findMatchingField);
+ } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
+ return f.eachItem(findMatchingField);
+ }
+ }
+ };
+
+ this.items.each(findMatchingField);
+ }
+ return field || null;
+ },
+
+
+
+ markInvalid : function(errors){
+ if (Ext.isArray(errors)) {
+ for(var i = 0, len = errors.length; i < len; i++){
+ var fieldError = errors[i];
+ var f = this.findField(fieldError.id);
+ if(f){
+ f.markInvalid(fieldError.msg);
+ }
+ }
+ } else {
+ var field, id;
+ for(id in errors){
+ if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
+ field.markInvalid(errors[id]);
+ }
+ }
+ }
+
+ return this;
+ },
+
+
+ setValues : function(values){
+ if(Ext.isArray(values)){
+ for(var i = 0, len = values.length; i < len; i++){
+ var v = values[i];
+ var f = this.findField(v.id);
+ if(f){
+ f.setValue(v.value);
+ if(this.trackResetOnLoad){
+ f.originalValue = f.getValue();
+ }
+ }
+ }
+ }else{
+ var field, id;
+ for(id in values){
+ if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
+ field.setValue(values[id]);
+ if(this.trackResetOnLoad){
+ field.originalValue = field.getValue();
+ }
+ }
+ }
+ }
+ return this;
+ },
+
+
+ getValues : function(asString){
+ var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
+ if(asString === true){
+ return fs;
+ }
+ return Ext.urlDecode(fs);
+ },
+
+
+ getFieldValues : function(dirtyOnly){
+ var o = {},
+ n,
+ key,
+ val;
+ this.items.each(function(f) {
+ if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
+ n = f.getName();
+ key = o[n];
+ val = f.getValue();
+
+ if(Ext.isDefined(key)){
+ if(Ext.isArray(key)){
+ o[n].push(val);
+ }else{
+ o[n] = [key, val];
+ }
+ }else{
+ o[n] = val;
+ }
+ }
+ });
+ return o;
+ },
+
+
+ clearInvalid : function(){
+ this.items.each(function(f){
+ f.clearInvalid();
+ });
+ return this;
+ },
+
+
+ reset : function(){
+ this.items.each(function(f){
+ f.reset();
+ });
+ return this;
+ },
+
+
+ add : function(){
+ this.items.addAll(Array.prototype.slice.call(arguments, 0));
+ return this;
+ },
+
+
+ remove : function(field){
+ this.items.remove(field);
+ return this;
+ },
+
+
+ cleanDestroyed : function() {
+ this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
+ },
+
+
+ render : function(){
+ this.items.each(function(f){
+ if(f.isFormField && !f.rendered && document.getElementById(f.id)){
+ f.applyToMarkup(f.id);
+ }
+ });
+ return this;
+ },
+
+
+ applyToFields : function(o){
+ this.items.each(function(f){
+ Ext.apply(f, o);
+ });
+ return this;
+ },
+
+
+ applyIfToFields : function(o){
+ this.items.each(function(f){
+ Ext.applyIf(f, o);
+ });
+ return this;
+ },
+
+ callFieldMethod : function(fnName, args){
+ args = args || [];
+ this.items.each(function(f){
+ if(Ext.isFunction(f[fnName])){
+ f[fnName].apply(f, args);
+ }
+ });
+ return this;
+ }
+});
+
+
+Ext.BasicForm = Ext.form.BasicForm;
+
+Ext.FormPanel = Ext.extend(Ext.Panel, {
+
+
+
+
+
+
+
+
+
+
+ minButtonWidth : 75,
+
+
+ labelAlign : 'left',
+
+
+ monitorValid : false,
+
+
+ monitorPoll : 200,
+
+
+ layout : 'form',
+
+
+ initComponent : function(){
+ this.form = this.createForm();
+ Ext.FormPanel.superclass.initComponent.call(this);
+
+ this.bodyCfg = {
+ tag: 'form',
+ cls: this.baseCls + '-body',
+ method : this.method || 'POST',
+ id : this.formId || Ext.id()
+ };
+ if(this.fileUpload) {
+ this.bodyCfg.enctype = 'multipart/form-data';
+ }
+ this.initItems();
+
+ this.addEvents(
+
+ 'clientvalidation'
+ );
+
+ this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
+ },
+
+
+ createForm : function(){
+ var config = Ext.applyIf({listeners: {}}, this.initialConfig);
+ return new Ext.form.BasicForm(null, config);
+ },
+
+
+ initFields : function(){
+ var f = this.form;
+ var formPanel = this;
+ var fn = function(c){
+ if(formPanel.isField(c)){
+ f.add(c);
+ }else if(c.findBy && c != formPanel){
+ formPanel.applySettings(c);
+
+ if(c.items && c.items.each){
+ c.items.each(fn, this);
+ }
+ }
+ };
+ this.items.each(fn, this);
+ },
+
+
+ applySettings: function(c){
+ var ct = c.ownerCt;
+ Ext.applyIf(c, {
+ labelAlign: ct.labelAlign,
+ labelWidth: ct.labelWidth,
+ itemCls: ct.itemCls
+ });
+ },
+
+
+ getLayoutTarget : function(){
+ return this.form.el;
+ },
+
+
+ getForm : function(){
+ return this.form;
+ },
+
+
+ onRender : function(ct, position){
+ this.initFields();
+ Ext.FormPanel.superclass.onRender.call(this, ct, position);
+ this.form.initEl(this.body);
+ },
+
+
+ beforeDestroy : function(){
+ this.stopMonitoring();
+ this.form.destroy(true);
+ Ext.FormPanel.superclass.beforeDestroy.call(this);
+ },
+
+
+ isField : function(c) {
+ return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
+ },
+
+
+ initEvents : function(){
+ Ext.FormPanel.superclass.initEvents.call(this);
+
+ this.on({
+ scope: this,
+ add: this.onAddEvent,
+ remove: this.onRemoveEvent
+ });
+ if(this.monitorValid){
+ this.startMonitoring();
+ }
+ },
+
+
+ onAdd: function(c){
+ Ext.FormPanel.superclass.onAdd.call(this, c);
+ this.processAdd(c);
+ },
+
+
+ onAddEvent: function(ct, c){
+ if(ct !== this){
+ this.processAdd(c);
+ }
+ },
+
+
+ processAdd : function(c){
+
+ if(this.isField(c)){
+ this.form.add(c);
+
+ }else if(c.findBy){
+ this.applySettings(c);
+ this.form.add.apply(this.form, c.findBy(this.isField));
+ }
+ },
+
+
+ onRemove: function(c){
+ Ext.FormPanel.superclass.onRemove.call(this, c);
+ this.processRemove(c);
+ },
+
+ onRemoveEvent: function(ct, c){
+ if(ct !== this){
+ this.processRemove(c);
+ }
+ },
+
+
+ processRemove: function(c){
+ if(!this.destroying){
+
+ if(this.isField(c)){
+ this.form.remove(c);
+
+ }else if (c.findBy){
+ Ext.each(c.findBy(this.isField), this.form.remove, this.form);
+
+ this.form.cleanDestroyed();
+ }
+ }
+ },
+
+
+ startMonitoring : function(){
+ if(!this.validTask){
+ this.validTask = new Ext.util.TaskRunner();
+ this.validTask.start({
+ run : this.bindHandler,
+ interval : this.monitorPoll || 200,
+ scope: this
+ });
+ }
+ },
+
+
+ stopMonitoring : function(){
+ if(this.validTask){
+ this.validTask.stopAll();
+ this.validTask = null;
+ }
+ },
+
+
+ load : function(){
+ this.form.load.apply(this.form, arguments);
+ },
+
+
+ onDisable : function(){
+ Ext.FormPanel.superclass.onDisable.call(this);
+ if(this.form){
+ this.form.items.each(function(){
+ this.disable();
+ });
+ }
+ },
+
+
+ onEnable : function(){
+ Ext.FormPanel.superclass.onEnable.call(this);
+ if(this.form){
+ this.form.items.each(function(){
+ this.enable();
+ });
+ }
+ },
+
+
+ bindHandler : function(){
+ var valid = true;
+ this.form.items.each(function(f){
+ if(!f.isValid(true)){
+ valid = false;
+ return false;
+ }
+ });
+ if(this.fbar){
+ var fitems = this.fbar.items.items;
+ for(var i = 0, len = fitems.length; i < len; i++){
+ var btn = fitems[i];
+ if(btn.formBind === true && btn.disabled === valid){
+ btn.setDisabled(!valid);
+ }
+ }
+ }
+ this.fireEvent('clientvalidation', this, valid);
+ }
+});
+Ext.reg('form', Ext.FormPanel);
+
+Ext.form.FormPanel = Ext.FormPanel;
+
+Ext.form.FieldSet = Ext.extend(Ext.Panel, {
+
+
+
+
+
+
+ baseCls : 'x-fieldset',
+
+ layout : 'form',
+
+ animCollapse : false,
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ this.el = document.createElement('fieldset');
+ this.el.id = this.id;
+ if (this.title || this.header || this.checkboxToggle) {
+ this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
+ }
+ }
+
+ Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
+
+ if(this.checkboxToggle){
+ var o = typeof this.checkboxToggle == 'object' ?
+ this.checkboxToggle :
+ {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
+ this.checkbox = this.header.insertFirst(o);
+ this.checkbox.dom.checked = !this.collapsed;
+ this.mon(this.checkbox, 'click', this.onCheckClick, this);
+ }
+ },
+
+
+ onCollapse : function(doAnim, animArg){
+ if(this.checkbox){
+ this.checkbox.dom.checked = false;
+ }
+ Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
+
+ },
+
+
+ onExpand : function(doAnim, animArg){
+ if(this.checkbox){
+ this.checkbox.dom.checked = true;
+ }
+ Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
+ },
+
+
+ onCheckClick : function(){
+ this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+});
+Ext.reg('fieldset', Ext.form.FieldSet);
+
+Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
+
+ enableFormat : true,
+
+ enableFontSize : true,
+
+ enableColors : true,
+
+ enableAlignments : true,
+
+ enableLists : true,
+
+ enableSourceEdit : true,
+
+ enableLinks : true,
+
+ enableFont : true,
+
+ createLinkText : 'Please enter the URL for the link:',
+
+ defaultLinkValue : 'http:/'+'/',
+
+ fontFamilies : [
+ 'Arial',
+ 'Courier New',
+ 'Tahoma',
+ 'Times New Roman',
+ 'Verdana'
+ ],
+ defaultFont: 'tahoma',
+
+ defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',
+
+
+ actionMode: 'wrap',
+ validationEvent : false,
+ deferHeight: true,
+ initialized : false,
+ activated : false,
+ sourceEditMode : false,
+ onFocus : Ext.emptyFn,
+ iframePad:3,
+ hideMode:'offsets',
+ defaultAutoCreate : {
+ tag: "textarea",
+ style:"width:500px;height:300px;",
+ autocomplete: "off"
+ },
+
+
+ initComponent : function(){
+ this.addEvents(
+
+ 'initialize',
+
+ 'activate',
+
+ 'beforesync',
+
+ 'beforepush',
+
+ 'sync',
+
+ 'push',
+
+ 'editmodechange'
+ );
+ Ext.form.HtmlEditor.superclass.initComponent.call(this);
+ },
+
+
+ createFontOptions : function(){
+ var buf = [], fs = this.fontFamilies, ff, lc;
+ for(var i = 0, len = fs.length; i< len; i++){
+ ff = fs[i];
+ lc = ff.toLowerCase();
+ buf.push(
+ '<option value="',lc,'" style="font-family:',ff,';"',
+ (this.defaultFont == lc ? ' selected="true">' : '>'),
+ ff,
+ '</option>'
+ );
+ }
+ return buf.join('');
+ },
+
+
+ createToolbar : function(editor){
+ var items = [];
+ var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
+
+
+ function btn(id, toggle, handler){
+ return {
+ itemId : id,
+ cls : 'x-btn-icon',
+ iconCls: 'x-edit-'+id,
+ enableToggle:toggle !== false,
+ scope: editor,
+ handler:handler||editor.relayBtnCmd,
+ clickEvent:'mousedown',
+ tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
+ overflowText: editor.buttonTips[id].title || undefined,
+ tabIndex:-1
+ };
+ }
+
+
+ if(this.enableFont && !Ext.isSafari2){
+ var fontSelectItem = new Ext.Toolbar.Item({
+ autoEl: {
+ tag:'select',
+ cls:'x-font-select',
+ html: this.createFontOptions()
+ }
+ });
+
+ items.push(
+ fontSelectItem,
+ '-'
+ );
+ }
+
+ if(this.enableFormat){
+ items.push(
+ btn('bold'),
+ btn('italic'),
+ btn('underline')
+ );
+ }
+
+ if(this.enableFontSize){
+ items.push(
+ '-',
+ btn('increasefontsize', false, this.adjustFont),
+ btn('decreasefontsize', false, this.adjustFont)
+ );
+ }
+
+ if(this.enableColors){
+ items.push(
+ '-', {
+ itemId:'forecolor',
+ cls:'x-btn-icon',
+ iconCls: 'x-edit-forecolor',
+ clickEvent:'mousedown',
+ tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
+ tabIndex:-1,
+ menu : new Ext.menu.ColorMenu({
+ allowReselect: true,
+ focus: Ext.emptyFn,
+ value:'000000',
+ plain:true,
+ listeners: {
+ scope: this,
+ select: function(cp, color){
+ this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
+ this.deferFocus();
+ }
+ },
+ clickEvent:'mousedown'
+ })
+ }, {
+ itemId:'backcolor',
+ cls:'x-btn-icon',
+ iconCls: 'x-edit-backcolor',
+ clickEvent:'mousedown',
+ tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
+ tabIndex:-1,
+ menu : new Ext.menu.ColorMenu({
+ focus: Ext.emptyFn,
+ value:'FFFFFF',
+ plain:true,
+ allowReselect: true,
+ listeners: {
+ scope: this,
+ select: function(cp, color){
+ if(Ext.isGecko){
+ this.execCmd('useCSS', false);
+ this.execCmd('hilitecolor', color);
+ this.execCmd('useCSS', true);
+ this.deferFocus();
+ }else{
+ this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
+ this.deferFocus();
+ }
+ }
+ },
+ clickEvent:'mousedown'
+ })
+ }
+ );
+ }
+
+ if(this.enableAlignments){
+ items.push(
+ '-',
+ btn('justifyleft'),
+ btn('justifycenter'),
+ btn('justifyright')
+ );
+ }
+
+ if(!Ext.isSafari2){
+ if(this.enableLinks){
+ items.push(
+ '-',
+ btn('createlink', false, this.createLink)
+ );
+ }
+
+ if(this.enableLists){
+ items.push(
+ '-',
+ btn('insertorderedlist'),
+ btn('insertunorderedlist')
+ );
+ }
+ if(this.enableSourceEdit){
+ items.push(
+ '-',
+ btn('sourceedit', true, function(btn){
+ this.toggleSourceEdit(!this.sourceEditMode);
+ })
+ );
+ }
+ }
+
+
+ var tb = new Ext.Toolbar({
+ renderTo: this.wrap.dom.firstChild,
+ items: items
+ });
+
+ if (fontSelectItem) {
+ this.fontSelect = fontSelectItem.el;
+
+ this.mon(this.fontSelect, 'change', function(){
+ var font = this.fontSelect.dom.value;
+ this.relayCmd('fontname', font);
+ this.deferFocus();
+ }, this);
+ }
+
+
+ this.mon(tb.el, 'click', function(e){
+ e.preventDefault();
+ });
+
+ this.tb = tb;
+ this.tb.doLayout();
+ },
+
+ onDisable: function(){
+ this.wrap.mask();
+ Ext.form.HtmlEditor.superclass.onDisable.call(this);
+ },
+
+ onEnable: function(){
+ this.wrap.unmask();
+ Ext.form.HtmlEditor.superclass.onEnable.call(this);
+ },
+
+ setReadOnly: function(readOnly){
+
+ Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
+ if(this.initialized){
+ if(Ext.isIE){
+ this.getEditorBody().contentEditable = !readOnly;
+ }else{
+ this.setDesignMode(!readOnly);
+ }
+ var bd = this.getEditorBody();
+ if(bd){
+ bd.style.cursor = this.readOnly ? 'default' : 'text';
+ }
+ this.disableItems(readOnly);
+ }
+ },
+
+
+ getDocMarkup : function(){
+ var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
+ return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
+ },
+
+
+ getEditorBody : function(){
+ var doc = this.getDoc();
+ return doc.body || doc.documentElement;
+ },
+
+
+ getDoc : function(){
+ return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
+ },
+
+
+ getWin : function(){
+ return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
+ },
+
+
+ onRender : function(ct, position){
+ Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
+ this.el.dom.style.border = '0 none';
+ this.el.dom.setAttribute('tabIndex', -1);
+ this.el.addClass('x-hidden');
+ if(Ext.isIE){
+ this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
+ }
+ this.wrap = this.el.wrap({
+ cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
+ });
+
+ this.createToolbar(this);
+
+ this.disableItems(true);
+
+ this.tb.doLayout();
+
+ this.createIFrame();
+
+ if(!this.width){
+ var sz = this.el.getSize();
+ this.setSize(sz.width, this.height || sz.height);
+ }
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+
+ createIFrame: function(){
+ var iframe = document.createElement('iframe');
+ iframe.name = Ext.id();
+ iframe.frameBorder = '0';
+ iframe.style.overflow = 'auto';
+ iframe.src = Ext.SSL_SECURE_URL;
+
+ this.wrap.dom.appendChild(iframe);
+ this.iframe = iframe;
+
+ this.monitorTask = Ext.TaskMgr.start({
+ run: this.checkDesignMode,
+ scope: this,
+ interval:100
+ });
+ },
+
+ initFrame : function(){
+ Ext.TaskMgr.stop(this.monitorTask);
+ var doc = this.getDoc();
+ this.win = this.getWin();
+
+ doc.open();
+ doc.write(this.getDocMarkup());
+ doc.close();
+
+ this.readyTask = {
+ run : function(){
+ var doc = this.getDoc();
+ if(doc.body || doc.readyState == 'complete'){
+ Ext.TaskMgr.stop(this.readyTask);
+ this.setDesignMode(true);
+ this.initEditor.defer(10, this);
+ }
+ },
+ interval : 10,
+ duration:10000,
+ scope: this
+ };
+ Ext.TaskMgr.start(this.readyTask);
+ },
+
+
+ checkDesignMode : function(){
+ if(this.wrap && this.wrap.dom.offsetWidth){
+ var doc = this.getDoc();
+ if(!doc){
+ return;
+ }
+ if(!doc.editorInitialized || this.getDesignMode() != 'on'){
+ this.initFrame();
+ }
+ }
+ },
+
+
+ setDesignMode : function(mode){
+ var doc = this.getDoc();
+ if (doc) {
+ if(this.readOnly){
+ mode = false;
+ }
+ doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
+ }
+
+ },
+
+
+ getDesignMode : function(){
+ var doc = this.getDoc();
+ if(!doc){ return ''; }
+ return String(doc.designMode).toLowerCase();
+
+ },
+
+ disableItems: function(disabled){
+ if(this.fontSelect){
+ this.fontSelect.dom.disabled = disabled;
+ }
+ this.tb.items.each(function(item){
+ if(item.getItemId() != 'sourceedit'){
+ item.setDisabled(disabled);
+ }
+ });
+ },
+
+
+ onResize : function(w, h){
+ Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
+ if(this.el && this.iframe){
+ if(Ext.isNumber(w)){
+ var aw = w - this.wrap.getFrameWidth('lr');
+ this.el.setWidth(aw);
+ this.tb.setWidth(aw);
+ this.iframe.style.width = Math.max(aw, 0) + 'px';
+ }
+ if(Ext.isNumber(h)){
+ var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
+ this.el.setHeight(ah);
+ this.iframe.style.height = Math.max(ah, 0) + 'px';
+ var bd = this.getEditorBody();
+ if(bd){
+ bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
+ }
+ }
+ }
+ },
+
+
+ toggleSourceEdit : function(sourceEditMode){
+ var iframeHeight,
+ elHeight;
+
+ if (sourceEditMode === undefined) {
+ sourceEditMode = !this.sourceEditMode;
+ }
+ this.sourceEditMode = sourceEditMode === true;
+ var btn = this.tb.getComponent('sourceedit');
+
+ if (btn.pressed !== this.sourceEditMode) {
+ btn.toggle(this.sourceEditMode);
+ if (!btn.xtbHidden) {
+ return;
+ }
+ }
+ if (this.sourceEditMode) {
+
+ this.previousSize = this.getSize();
+
+ iframeHeight = Ext.get(this.iframe).getHeight();
+
+ this.disableItems(true);
+ this.syncValue();
+ this.iframe.className = 'x-hidden';
+ this.el.removeClass('x-hidden');
+ this.el.dom.removeAttribute('tabIndex');
+ this.el.focus();
+ this.el.dom.style.height = iframeHeight + 'px';
+ }
+ else {
+ elHeight = parseInt(this.el.dom.style.height, 10);
+ if (this.initialized) {
+ this.disableItems(this.readOnly);
+ }
+ this.pushValue();
+ this.iframe.className = '';
+ this.el.addClass('x-hidden');
+ this.el.dom.setAttribute('tabIndex', -1);
+ this.deferFocus();
+
+ this.setSize(this.previousSize);
+ delete this.previousSize;
+ this.iframe.style.height = elHeight + 'px';
+ }
+ this.fireEvent('editmodechange', this, this.sourceEditMode);
+ },
+
+
+ createLink : function() {
+ var url = prompt(this.createLinkText, this.defaultLinkValue);
+ if(url && url != 'http:/'+'/'){
+ this.relayCmd('createlink', url);
+ }
+ },
+
+
+ initEvents : function(){
+ this.originalValue = this.getValue();
+ },
+
+
+ markInvalid : Ext.emptyFn,
+
+
+ clearInvalid : Ext.emptyFn,
+
+
+ setValue : function(v){
+ Ext.form.HtmlEditor.superclass.setValue.call(this, v);
+ this.pushValue();
+ return this;
+ },
+
+
+ cleanHtml: function(html) {
+ html = String(html);
+ if(Ext.isWebKit){
+ html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
+ }
+
+
+ if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
+ html = html.substring(1);
+ }
+ return html;
+ },
+
+
+ syncValue : function(){
+ if(this.initialized){
+ var bd = this.getEditorBody();
+ var html = bd.innerHTML;
+ if(Ext.isWebKit){
+ var bs = bd.getAttribute('style');
+ var m = bs.match(/text-align:(.*?);/i);
+ if(m && m[1]){
+ html = '<div style="'+m[0]+'">' + html + '</div>';
+ }
+ }
+ html = this.cleanHtml(html);
+ if(this.fireEvent('beforesync', this, html) !== false){
+ this.el.dom.value = html;
+ this.fireEvent('sync', this, html);
+ }
+ }
+ },
+
+
+ getValue : function() {
+ this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
+ return Ext.form.HtmlEditor.superclass.getValue.call(this);
+ },
+
+
+ pushValue : function(){
+ if(this.initialized){
+ var v = this.el.dom.value;
+ if(!this.activated && v.length < 1){
+ v = this.defaultValue;
+ }
+ if(this.fireEvent('beforepush', this, v) !== false){
+ this.getEditorBody().innerHTML = v;
+ if(Ext.isGecko){
+
+ this.setDesignMode(false);
+ this.setDesignMode(true);
+ }
+ this.fireEvent('push', this, v);
+ }
+
+ }
+ },
+
+
+ deferFocus : function(){
+ this.focus.defer(10, this);
+ },
+
+
+ focus : function(){
+ if(this.win && !this.sourceEditMode){
+ this.win.focus();
+ }else{
+ this.el.focus();
+ }
+ },
+
+
+ initEditor : function(){
+
+ try{
+ var dbody = this.getEditorBody(),
+ ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
+ doc,
+ fn;
+
+ ss['background-attachment'] = 'fixed';
+ dbody.bgProperties = 'fixed';
+
+ Ext.DomHelper.applyStyles(dbody, ss);
+
+ doc = this.getDoc();
+
+ if(doc){
+ try{
+ Ext.EventManager.removeAll(doc);
+ }catch(e){}
+ }
+
+
+ fn = this.onEditorEvent.createDelegate(this);
+ Ext.EventManager.on(doc, {
+ mousedown: fn,
+ dblclick: fn,
+ click: fn,
+ keyup: fn,
+ buffer:100
+ });
+
+ if(Ext.isGecko){
+ Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
+ }
+ if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
+ Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
+ }
+ doc.editorInitialized = true;
+ this.initialized = true;
+ this.pushValue();
+ this.setReadOnly(this.readOnly);
+ this.fireEvent('initialize', this);
+ }catch(e){}
+ },
+
+
+ beforeDestroy : function(){
+ if(this.monitorTask){
+ Ext.TaskMgr.stop(this.monitorTask);
+ }
+ if(this.readyTask){
+ Ext.TaskMgr.stop(this.readyTask);
+ }
+ if(this.rendered){
+ Ext.destroy(this.tb);
+ var doc = this.getDoc();
+ Ext.EventManager.removeFromSpecialCache(doc);
+ if(doc){
+ try{
+ Ext.EventManager.removeAll(doc);
+ for (var prop in doc){
+ delete doc[prop];
+ }
+ }catch(e){}
+ }
+ if(this.wrap){
+ this.wrap.dom.innerHTML = '';
+ this.wrap.remove();
+ }
+ }
+ Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
+ },
+
+
+ onFirstFocus : function(){
+ this.activated = true;
+ this.disableItems(this.readOnly);
+ if(Ext.isGecko){
+ this.win.focus();
+ var s = this.win.getSelection();
+ if(!s.focusNode || s.focusNode.nodeType != 3){
+ var r = s.getRangeAt(0);
+ r.selectNodeContents(this.getEditorBody());
+ r.collapse(true);
+ this.deferFocus();
+ }
+ try{
+ this.execCmd('useCSS', true);
+ this.execCmd('styleWithCSS', false);
+ }catch(e){}
+ }
+ this.fireEvent('activate', this);
+ },
+
+
+ adjustFont: function(btn){
+ var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
+ doc = this.getDoc(),
+ v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
+ if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
+
+
+ if(v <= 10){
+ v = 1 + adjust;
+ }else if(v <= 13){
+ v = 2 + adjust;
+ }else if(v <= 16){
+ v = 3 + adjust;
+ }else if(v <= 18){
+ v = 4 + adjust;
+ }else if(v <= 24){
+ v = 5 + adjust;
+ }else {
+ v = 6 + adjust;
+ }
+ v = v.constrain(1, 6);
+ }else{
+ if(Ext.isSafari){
+ adjust *= 2;
+ }
+ v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
+ }
+ this.execCmd('FontSize', v);
+ },
+
+
+ onEditorEvent : function(e){
+ this.updateToolbar();
+ },
+
+
+
+ updateToolbar: function(){
+
+ if(this.readOnly){
+ return;
+ }
+
+ if(!this.activated){
+ this.onFirstFocus();
+ return;
+ }
+
+ var btns = this.tb.items.map,
+ doc = this.getDoc();
+
+ if(this.enableFont && !Ext.isSafari2){
+ var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
+ if(name != this.fontSelect.dom.value){
+ this.fontSelect.dom.value = name;
+ }
+ }
+ if(this.enableFormat){
+ btns.bold.toggle(doc.queryCommandState('bold'));
+ btns.italic.toggle(doc.queryCommandState('italic'));
+ btns.underline.toggle(doc.queryCommandState('underline'));
+ }
+ if(this.enableAlignments){
+ btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
+ btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
+ btns.justifyright.toggle(doc.queryCommandState('justifyright'));
+ }
+ if(!Ext.isSafari2 && this.enableLists){
+ btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
+ btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
+ }
+
+ Ext.menu.MenuMgr.hideAll();
+
+ this.syncValue();
+ },
+
+
+ relayBtnCmd : function(btn){
+ this.relayCmd(btn.getItemId());
+ },
+
+
+ relayCmd : function(cmd, value){
+ (function(){
+ this.focus();
+ this.execCmd(cmd, value);
+ this.updateToolbar();
+ }).defer(10, this);
+ },
+
+
+ execCmd : function(cmd, value){
+ var doc = this.getDoc();
+ doc.execCommand(cmd, false, value === undefined ? null : value);
+ this.syncValue();
+ },
+
+
+ applyCommand : function(e){
+ if(e.ctrlKey){
+ var c = e.getCharCode(), cmd;
+ if(c > 0){
+ c = String.fromCharCode(c);
+ switch(c){
+ case 'b':
+ cmd = 'bold';
+ break;
+ case 'i':
+ cmd = 'italic';
+ break;
+ case 'u':
+ cmd = 'underline';
+ break;
+ }
+ if(cmd){
+ this.win.focus();
+ this.execCmd(cmd);
+ this.deferFocus();
+ e.preventDefault();
+ }
+ }
+ }
+ },
+
+
+ insertAtCursor : function(text){
+ if(!this.activated){
+ return;
+ }
+ if(Ext.isIE){
+ this.win.focus();
+ var doc = this.getDoc(),
+ r = doc.selection.createRange();
+ if(r){
+ r.pasteHTML(text);
+ this.syncValue();
+ this.deferFocus();
+ }
+ }else{
+ this.win.focus();
+ this.execCmd('InsertHTML', text);
+ this.deferFocus();
+ }
+ },
+
+
+ fixKeys : function(){
+ if(Ext.isIE){
+ return function(e){
+ var k = e.getKey(),
+ doc = this.getDoc(),
+ r;
+ if(k == e.TAB){
+ e.stopEvent();
+ r = doc.selection.createRange();
+ if(r){
+ r.collapse(true);
+ r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
+ this.deferFocus();
+ }
+ }else if(k == e.ENTER){
+ r = doc.selection.createRange();
+ if(r){
+ var target = r.parentElement();
+ if(!target || target.tagName.toLowerCase() != 'li'){
+ e.stopEvent();
+ r.pasteHTML('<br />');
+ r.collapse(false);
+ r.select();
+ }
+ }
+ }
+ };
+ }else if(Ext.isOpera){
+ return function(e){
+ var k = e.getKey();
+ if(k == e.TAB){
+ e.stopEvent();
+ this.win.focus();
+ this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
+ this.deferFocus();
+ }
+ };
+ }else if(Ext.isWebKit){
+ return function(e){
+ var k = e.getKey();
+ if(k == e.TAB){
+ e.stopEvent();
+ this.execCmd('InsertText','\t');
+ this.deferFocus();
+ }else if(k == e.ENTER){
+ e.stopEvent();
+ this.execCmd('InsertHtml','<br /><br />');
+ this.deferFocus();
+ }
+ };
+ }
+ }(),
+
+
+ getToolbar : function(){
+ return this.tb;
+ },
+
+
+ buttonTips : {
+ bold : {
+ title: 'Bold (Ctrl+B)',
+ text: 'Make the selected text bold.',
+ cls: 'x-html-editor-tip'
+ },
+ italic : {
+ title: 'Italic (Ctrl+I)',
+ text: 'Make the selected text italic.',
+ cls: 'x-html-editor-tip'
+ },
+ underline : {
+ title: 'Underline (Ctrl+U)',
+ text: 'Underline the selected text.',
+ cls: 'x-html-editor-tip'
+ },
+ increasefontsize : {
+ title: 'Grow Text',
+ text: 'Increase the font size.',
+ cls: 'x-html-editor-tip'
+ },
+ decreasefontsize : {
+ title: 'Shrink Text',
+ text: 'Decrease the font size.',
+ cls: 'x-html-editor-tip'
+ },
+ backcolor : {
+ title: 'Text Highlight Color',
+ text: 'Change the background color of the selected text.',
+ cls: 'x-html-editor-tip'
+ },
+ forecolor : {
+ title: 'Font Color',
+ text: 'Change the color of the selected text.',
+ cls: 'x-html-editor-tip'
+ },
+ justifyleft : {
+ title: 'Align Text Left',
+ text: 'Align text to the left.',
+ cls: 'x-html-editor-tip'
+ },
+ justifycenter : {
+ title: 'Center Text',
+ text: 'Center text in the editor.',
+ cls: 'x-html-editor-tip'
+ },
+ justifyright : {
+ title: 'Align Text Right',
+ text: 'Align text to the right.',
+ cls: 'x-html-editor-tip'
+ },
+ insertunorderedlist : {
+ title: 'Bullet List',
+ text: 'Start a bulleted list.',
+ cls: 'x-html-editor-tip'
+ },
+ insertorderedlist : {
+ title: 'Numbered List',
+ text: 'Start a numbered list.',
+ cls: 'x-html-editor-tip'
+ },
+ createlink : {
+ title: 'Hyperlink',
+ text: 'Make the selected text a hyperlink.',
+ cls: 'x-html-editor-tip'
+ },
+ sourceedit : {
+ title: 'Source Edit',
+ text: 'Switch to source editing mode.',
+ cls: 'x-html-editor-tip'
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+});
+Ext.reg('htmleditor', Ext.form.HtmlEditor);
+
+Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
+
+ minValue : undefined,
+
+ maxValue : undefined,
+
+ minText : "The time in this field must be equal to or after {0}",
+
+ maxText : "The time in this field must be equal to or before {0}",
+
+ invalidText : "{0} is not a valid time",
+
+ format : "g:i A",
+
+ altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
+
+ increment: 15,
+
+
+ mode: 'local',
+
+ triggerAction: 'all',
+
+ typeAhead: false,
+
+
+
+
+ initDate: '1/1/2008',
+
+ initDateFormat: 'j/n/Y',
+
+
+ initComponent : function(){
+ if(Ext.isDefined(this.minValue)){
+ this.setMinValue(this.minValue, true);
+ }
+ if(Ext.isDefined(this.maxValue)){
+ this.setMaxValue(this.maxValue, true);
+ }
+ if(!this.store){
+ this.generateStore(true);
+ }
+ Ext.form.TimeField.superclass.initComponent.call(this);
+ },
+
+
+ setMinValue: function(value, initial){
+ this.setLimit(value, true, initial);
+ return this;
+ },
+
+
+ setMaxValue: function(value, initial){
+ this.setLimit(value, false, initial);
+ return this;
+ },
+
+
+ generateStore: function(initial){
+ var min = this.minValue || new Date(this.initDate).clearTime(),
+ max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
+ times = [];
+
+ while(min <= max){
+ times.push(min.dateFormat(this.format));
+ min = min.add('mi', this.increment);
+ }
+ this.bindStore(times, initial);
+ },
+
+
+ setLimit: function(value, isMin, initial){
+ var d;
+ if(Ext.isString(value)){
+ d = this.parseDate(value);
+ }else if(Ext.isDate(value)){
+ d = value;
+ }
+ if(d){
+ var val = new Date(this.initDate).clearTime();
+ val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
+ this[isMin ? 'minValue' : 'maxValue'] = val;
+ if(!initial){
+ this.generateStore();
+ }
+ }
+ },
+
+
+ getValue : function(){
+ var v = Ext.form.TimeField.superclass.getValue.call(this);
+ return this.formatDate(this.parseDate(v)) || '';
+ },
+
+
+ setValue : function(value){
+ return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
+ },
+
+
+ validateValue : Ext.form.DateField.prototype.validateValue,
+
+ formatDate : Ext.form.DateField.prototype.formatDate,
+
+ parseDate: function(value) {
+ if (!value || Ext.isDate(value)) {
+ return value;
+ }
+
+ var id = this.initDate + ' ',
+ idf = this.initDateFormat + ' ',
+ v = Date.parseDate(id + value, idf + this.format),
+ af = this.altFormats;
+
+ if (!v && af) {
+ if (!this.altFormatsArray) {
+ this.altFormatsArray = af.split("|");
+ }
+ for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
+ v = Date.parseDate(id + value, idf + afa[i]);
+ }
+ }
+
+ return v;
+ }
+});
+Ext.reg('timefield', Ext.form.TimeField);
+Ext.form.SliderField = Ext.extend(Ext.form.Field, {
+
+
+ useTips : true,
+
+
+ tipText : null,
+
+
+ actionMode: 'wrap',
+
+
+ initComponent : function() {
+ var cfg = Ext.copyTo({
+ id: this.id + '-slider'
+ }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
+
+
+ if (this.useTips) {
+ var plug = this.tipText ? {getText: this.tipText} : {};
+ cfg.plugins = [new Ext.slider.Tip(plug)];
+ }
+ this.slider = new Ext.Slider(cfg);
+ Ext.form.SliderField.superclass.initComponent.call(this);
+ },
+
+
+ onRender : function(ct, position){
+ this.autoCreate = {
+ id: this.id,
+ name: this.name,
+ type: 'hidden',
+ tag: 'input'
+ };
+ Ext.form.SliderField.superclass.onRender.call(this, ct, position);
+ this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
+ this.resizeEl = this.positionEl = this.wrap;
+ this.slider.render(this.wrap);
+ },
+
+
+ onResize : function(w, h, aw, ah){
+ Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
+ this.slider.setSize(w, h);
+ },
+
+
+ initEvents : function(){
+ Ext.form.SliderField.superclass.initEvents.call(this);
+ this.slider.on('change', this.onChange, this);
+ },
+
+
+ onChange : function(slider, v){
+ this.setValue(v, undefined, true);
+ },
+
+
+ onEnable : function(){
+ Ext.form.SliderField.superclass.onEnable.call(this);
+ this.slider.enable();
+ },
+
+
+ onDisable : function(){
+ Ext.form.SliderField.superclass.onDisable.call(this);
+ this.slider.disable();
+ },
+
+
+ beforeDestroy : function(){
+ Ext.destroy(this.slider);
+ Ext.form.SliderField.superclass.beforeDestroy.call(this);
+ },
+
+
+ alignErrorIcon : function(){
+ this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
+ },
+
+
+ setMinValue : function(v){
+ this.slider.setMinValue(v);
+ return this;
+ },
+
+
+ setMaxValue : function(v){
+ this.slider.setMaxValue(v);
+ return this;
+ },
+
+
+ setValue : function(v, animate, silent){
+
+
+ if(!silent){
+ this.slider.setValue(v, animate);
+ }
+ return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
+ },
+
+
+ getValue : function(){
+ return this.slider.getValue();
+ }
+});
+
+Ext.reg('sliderfield', Ext.form.SliderField);
+Ext.form.Label = Ext.extend(Ext.BoxComponent, {
+
+
+
+
+
+ onRender : function(ct, position){
+ if(!this.el){
+ this.el = document.createElement('label');
+ this.el.id = this.getId();
+ this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
+ if(this.forId){
+ this.el.setAttribute('for', this.forId);
+ }
+ }
+ Ext.form.Label.superclass.onRender.call(this, ct, position);
+ },
+
+
+ setText : function(t, encode){
+ var e = encode === false;
+ this[!e ? 'text' : 'html'] = t;
+ delete this[e ? 'text' : 'html'];
+ if(this.rendered){
+ this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
+ }
+ return this;
+ }
+});
+
+Ext.reg('label', Ext.form.Label);
+Ext.form.Action = function(form, options){
+ this.form = form;
+ this.options = options || {};
+};
+
+
+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',
+
+
+
+
+
+ run : function(options){
+
+ },
+
+
+ success : function(response){
+
+ },
+
+
+ handleResponse : function(response){
+
+ },
+
+
+ failure : function(response){
+ this.response = response;
+ this.failureType = Ext.form.Action.CONNECT_FAILURE;
+ this.form.afterAction(this, false);
+ },
+
+
+
+
+ processResponse : function(response){
+ this.response = response;
+ if(!response.responseText && !response.responseXML){
+ return true;
+ }
+ this.result = this.handleResponse(response);
+ return this.result;
+ },
+
+ decodeResponse: function(response) {
+ try {
+ return Ext.decode(response.responseText);
+ } catch(e) {
+ return false;
+ }
+ },
+
+
+ getUrl : function(appendParams){
+ var url = this.options.url || this.form.url || this.form.el.dom.action;
+ if(appendParams){
+ var p = this.getParams();
+ if(p){
+ url = Ext.urlAppend(url, p);
+ }
+ }
+ return url;
+ },
+
+
+ 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(opts){
+ var opts = opts || {};
+ return {
+ success: this.success,
+ failure: this.failure,
+ scope: this,
+ timeout: (opts.timeout*1000) || (this.form.timeout*1000),
+ upload: this.form.fileUpload ? this.success : undefined
+ };
+ }
+};
+
+
+Ext.form.Action.Submit = function(form, options){
+ Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
+};
+
+Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
+
+
+ type : 'submit',
+
+
+ run : function(){
+ var o = this.options,
+ method = this.getMethod(),
+ isGet = method == 'GET';
+ if(o.clientValidation === false || this.form.isValid()){
+ if (o.submitEmptyText === false) {
+ var fields = this.form.items,
+ emptyFields = [],
+ setupEmptyFields = function(f){
+ if (f.el.getValue() == f.emptyText) {
+ emptyFields.push(f);
+ f.el.dom.value = "";
+ }
+ if(f.isComposite && f.rendered){
+ f.items.each(setupEmptyFields);
+ }
+ };
+
+ fields.each(setupEmptyFields);
+ }
+ Ext.Ajax.request(Ext.apply(this.createCallback(o), {
+ form:this.form.el.dom,
+ url:this.getUrl(isGet),
+ method: method,
+ headers: o.headers,
+ params:!isGet ? this.getParams() : null,
+ isUpload: this.form.fileUpload
+ }));
+ if (o.submitEmptyText === false) {
+ Ext.each(emptyFields, function(f) {
+ if (f.applyEmptyText) {
+ f.applyEmptyText();
+ }
+ });
+ }
+ }else if (o.clientValidation !== false){
+ this.failureType = Ext.form.Action.CLIENT_INVALID;
+ this.form.afterAction(this, false);
+ }
+ },
+
+
+ success : function(response){
+ var result = this.processResponse(response);
+ if(result === true || result.success){
+ this.form.afterAction(this, true);
+ return;
+ }
+ if(result.errors){
+ this.form.markInvalid(result.errors);
+ }
+ this.failureType = Ext.form.Action.SERVER_INVALID;
+ this.form.afterAction(this, false);
+ },
+
+
+ handleResponse : function(response){
+ if(this.form.errorReader){
+ var rs = this.form.errorReader.read(response);
+ var errors = [];
+ if(rs.records){
+ for(var i = 0, len = rs.records.length; i < len; i++) {
+ var r = rs.records[i];
+ errors[i] = r.data;
+ }
+ }
+ if(errors.length < 1){
+ errors = null;
+ }
+ return {
+ success : rs.success,
+ errors : errors
+ };
+ }
+ return this.decodeResponse(response);
+ }
+});
+
+
+
+Ext.form.Action.Load = function(form, options){
+ Ext.form.Action.Load.superclass.constructor.call(this, form, options);
+ this.reader = this.form.reader;
+};
+
+Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
+
+ type : 'load',
+
+
+ run : function(){
+ Ext.Ajax.request(Ext.apply(
+ this.createCallback(this.options), {
+ method:this.getMethod(),
+ url:this.getUrl(false),
+ headers: this.options.headers,
+ params:this.getParams()
+ }));
+ },
+
+
+ success : function(response){
+ var result = this.processResponse(response);
+ if(result === true || !result.success || !result.data){
+ this.failureType = Ext.form.Action.LOAD_FAILURE;
+ this.form.afterAction(this, false);
+ return;
+ }
+ this.form.clearInvalid();
+ this.form.setValues(result.data);
+ this.form.afterAction(this, true);
+ },
+
+
+ handleResponse : function(response){
+ if(this.form.reader){
+ var rs = this.form.reader.read(response);
+ var data = rs.records && rs.records[0] ? rs.records[0].data : null;
+ return {
+ success : rs.success,
+ data : data
+ };
+ }
+ return this.decodeResponse(response);
+ }
+});
+
+
+
+
+Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
+ constructor: function(form, opts) {
+ Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
+ },
+ type : 'directload',
+
+ run : function(){
+ var args = this.getParams();
+ args.push(this.success, this);
+ this.form.api.load.apply(window, args);
+ },
+
+ getParams : function() {
+ var buf = [], o = {};
+ var bp = this.form.baseParams;
+ var p = this.options.params;
+ Ext.apply(o, p, bp);
+ var paramOrder = this.form.paramOrder;
+ if(paramOrder){
+ for(var i = 0, len = paramOrder.length; i < len; i++){
+ buf.push(o[paramOrder[i]]);
+ }
+ }else if(this.form.paramsAsHash){
+ buf.push(o);
+ }
+ return buf;
+ },
+
+
+
+ processResponse : function(result) {
+ this.result = result;
+ return result;
+ },
+
+ success : function(response, trans){
+ if(trans.type == Ext.Direct.exceptions.SERVER){
+ response = {};
+ }
+ Ext.form.Action.DirectLoad.superclass.success.call(this, response);
+ }
+});
+
+
+Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
+ constructor : function(form, opts) {
+ Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
+ },
+ type : 'directsubmit',
+
+ run : function(){
+ var o = this.options;
+ if(o.clientValidation === false || this.form.isValid()){
+
+
+ this.success.params = this.getParams();
+ this.form.api.submit(this.form.el.dom, this.success, this);
+ }else if (o.clientValidation !== false){
+ this.failureType = Ext.form.Action.CLIENT_INVALID;
+ this.form.afterAction(this, false);
+ }
+ },
+
+ getParams : function() {
+ var o = {};
+ var bp = this.form.baseParams;
+ var p = this.options.params;
+ Ext.apply(o, p, bp);
+ return o;
+ },
+
+
+
+ processResponse : function(result) {
+ this.result = result;
+ return result;
+ },
+
+ success : function(response, trans){
+ if(trans.type == Ext.Direct.exceptions.SERVER){
+ response = {};
+ }
+ Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
+ }
+});
+
+Ext.form.Action.ACTION_TYPES = {
+ 'load' : Ext.form.Action.Load,
+ 'submit' : Ext.form.Action.Submit,
+ 'directload' : Ext.form.Action.DirectLoad,
+ 'directsubmit' : Ext.form.Action.DirectSubmit
+};
+
+Ext.form.VTypes = function(){
+
+ var alpha = /^[a-zA-Z_]+$/,
+ alphanum = /^[a-zA-Z0-9_]+$/,
+ email = /^(\w+)([\-+.\'][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
+ url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+
+
+ return {
+
+ 'email' : function(v){
+ return email.test(v);
+ },
+
+ 'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
+
+ 'emailMask' : /[a-z0-9_\.\-\+\'@]/i,
+
+ /**
+ * The function used to validate URLs
+ * @param {String} value The URL
+ * @return {Boolean} true if the RegExp test passed, and false if not.
+ */
+ 'url' : function(v){
+ return url.test(v);
+ },
+ /**
+ * The error text to display when the url validation function returns false. Defaults to:
+ * <tt>'This field should be a URL in the format "http:/'+'/www.example.com"'</tt>
+ * @type String
+ */
+ 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
+
+ /**
+ * The function used to validate alpha values
+ * @param {String} value The value
+ * @return {Boolean} true if the RegExp test passed, and false if not.
+ */
+ 'alpha' : function(v){
+ return alpha.test(v);
+ },
+ /**
+ * The error text to display when the alpha validation function returns false. Defaults to:
+ * <tt>'This field should only contain letters and _'</tt>
+ * @type String
+ */
+ 'alphaText' : 'This field should only contain letters and _',
+ /**
+ * The keystroke filter mask to be applied on alpha input. Defaults to:
+ * <tt>/[a-z_]/i</tt>
+ * @type RegExp
+ */
+ 'alphaMask' : /[a-z_]/i,
+
+ /**
+ * The function used to validate alphanumeric values
+ * @param {String} value The value
+ * @return {Boolean} true if the RegExp test passed, and false if not.
+ */
+ 'alphanum' : function(v){
+ return alphanum.test(v);
+ },
+ /**
+ * The error text to display when the alphanumeric validation function returns false. Defaults to:
+ * <tt>'This field should only contain letters, numbers and _'</tt>
+ * @type String
+ */
+ 'alphanumText' : 'This field should only contain letters, numbers and _',
+ /**
+ * The keystroke filter mask to be applied on alphanumeric input. Defaults to:
+ * <tt>/[a-z0-9_]/i</tt>
+ * @type RegExp
+ */
+ 'alphanumMask' : /[a-z0-9_]/i
+ };
+}();
+/**
+ * @class Ext.grid.GridPanel
+ * @extends Ext.Panel
+ * <p>This class represents the primary interface of a component based grid control to represent data
+ * in a tabular format of rows and columns. The GridPanel is composed of the following:</p>
+ * <div class="mdetail-params"><ul>
+ * <li><b>{@link Ext.data.Store Store}</b> : The Model holding the data records (rows)
+ * <div class="sub-desc"></div></li>
+ * <li><b>{@link Ext.grid.ColumnModel Column model}</b> : Column makeup
+ * <div class="sub-desc"></div></li>
+ * <li><b>{@link Ext.grid.GridView View}</b> : Encapsulates the user interface
+ * <div class="sub-desc"></div></li>
+ * <li><b>{@link Ext.grid.AbstractSelectionModel selection model}</b> : Selection behavior
+ * <div class="sub-desc"></div></li>
+ * </ul></div>
+ * <p>Example usage:</p>
+ * <pre><code>
+var grid = new Ext.grid.GridPanel({
+ {@link #store}: new {@link Ext.data.Store}({
+ {@link Ext.data.Store#autoDestroy autoDestroy}: true,
+ {@link Ext.data.Store#reader reader}: reader,
+ {@link Ext.data.Store#data data}: xg.dummyData
+ }),
+ {@link #colModel}: new {@link Ext.grid.ColumnModel}({
+ {@link Ext.grid.ColumnModel#defaults defaults}: {
+ width: 120,
+ sortable: true
+ },
+ {@link Ext.grid.ColumnModel#columns columns}: [
+ {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
+ {header: 'Price', renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
+ {header: 'Change', dataIndex: 'change'},
+ {header: '% Change', dataIndex: 'pctChange'},
+ // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
+ {
+ header: 'Last Updated', width: 135, dataIndex: 'lastChange',
+ xtype: 'datecolumn', format: 'M d, Y'
+ }
+ ]
+ }),
+ {@link #viewConfig}: {
+ {@link Ext.grid.GridView#forceFit forceFit}: true,
+
+// Return CSS class to apply to rows depending upon data values
+ {@link Ext.grid.GridView#getRowClass getRowClass}: function(record, index) {
+ var c = record.{@link Ext.data.Record#get get}('change');
+ if (c < 0) {
+ return 'price-fall';
+ } else if (c > 0) {
+ return 'price-rise';
+ }
+ }
+ },
+ {@link #sm}: new Ext.grid.RowSelectionModel({singleSelect:true}),
+ width: 600,
+ height: 300,
+ frame: true,
+ title: 'Framed with Row Selection and Horizontal Scrolling',
+ iconCls: 'icon-grid'
+});
+ * </code></pre>
+ * <p><b><u>Notes:</u></b></p>
+ * <div class="mdetail-params"><ul>
+ * <li>Although this class inherits many configuration options from base classes, some of them
+ * (such as autoScroll, autoWidth, layout, items, etc) are not used by this class, and will
+ * have no effect.</li>
+ * <li>A grid <b>requires</b> a width in which to scroll its columns, and a height in which to
+ * scroll its rows. These dimensions can either be set explicitly through the
+ * <tt>{@link Ext.BoxComponent#height height}</tt> and <tt>{@link Ext.BoxComponent#width width}</tt>
+ * configuration options or implicitly set by using the grid as a child item of a
+ * {@link Ext.Container Container} which will have a {@link Ext.Container#layout layout manager}
+ * provide the sizing of its child items (for example the Container of the Grid may specify
+ * <tt>{@link Ext.Container#layout layout}:'fit'</tt>).</li>
+ * <li>To access the data in a Grid, it is necessary to use the data model encapsulated
+ * by the {@link #store Store}. See the {@link #cellclick} event for more details.</li>
+ * </ul></div>
+ * @constructor
+ * @param {Object} config The config object
+ * @xtype grid
+ */
+Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
+ /**
+ * @cfg {String} autoExpandColumn
+ * <p>The <tt>{@link Ext.grid.Column#id id}</tt> of a {@link Ext.grid.Column column} in
+ * this grid that should expand to fill unused space. This value specified here can not
+ * be <tt>0</tt>.</p>
+ * <br><p><b>Note</b>: If the Grid's {@link Ext.grid.GridView view} is configured with
+ * <tt>{@link Ext.grid.GridView#forceFit forceFit}=true</tt> the <tt>autoExpandColumn</tt>
+ * is ignored. See {@link Ext.grid.Column}.<tt>{@link Ext.grid.Column#width width}</tt>
+ * for additional details.</p>
+ * <p>See <tt>{@link #autoExpandMax}</tt> and <tt>{@link #autoExpandMin}</tt> also.</p>
+ */
+ autoExpandColumn : false,
+
+
+ autoExpandMax : 1000,
+
+
+ autoExpandMin : 50,
+
+
+ columnLines : false,
+
+
+
+
+
+
+ ddText : '{0} selected row{1}',
+
+
+
+
+ deferRowRender : true,
+
+
+
+
+ enableColumnHide : true,
+
+
+ enableColumnMove : true,
+
+
+ enableDragDrop : false,
+
+
+ enableHdMenu : true,
+
+
+
+ loadMask : false,
+
+
+
+ minColumnWidth : 25,
+
+
+
+
+
+ stripeRows : false,
+
+
+ trackMouseOver : true,
+
+
+ stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
+
+
+ view : null,
+
+
+ bubbleEvents: [],
+
+
+
+
+ rendered : false,
+
+
+ viewReady : false,
+
+
+ initComponent : function() {
+ Ext.grid.GridPanel.superclass.initComponent.call(this);
+
+ if (this.columnLines) {
+ this.cls = (this.cls || '') + ' x-grid-with-col-lines';
+ }
+
+
+ this.autoScroll = false;
+ this.autoWidth = false;
+
+ if(Ext.isArray(this.columns)){
+ this.colModel = new Ext.grid.ColumnModel(this.columns);
+ delete this.columns;
+ }
+
+
+ if(this.ds){
+ this.store = 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;
+ }
+ this.store = Ext.StoreMgr.lookup(this.store);
+
+ this.addEvents(
+
+
+ 'click',
+
+ 'dblclick',
+
+ 'contextmenu',
+
+ 'mousedown',
+
+ 'mouseup',
+
+ 'mouseover',
+
+ 'mouseout',
+
+ 'keypress',
+
+ 'keydown',
+
+
+
+ 'cellmousedown',
+
+ 'rowmousedown',
+
+ 'headermousedown',
+
+
+ 'groupmousedown',
+
+
+ 'rowbodymousedown',
+
+
+ 'containermousedown',
+
+
+ 'cellclick',
+
+ 'celldblclick',
+
+ 'rowclick',
+
+ 'rowdblclick',
+
+ 'headerclick',
+
+ 'headerdblclick',
+
+ 'groupclick',
+
+ 'groupdblclick',
+
+ 'containerclick',
+
+ 'containerdblclick',
+
+
+ 'rowbodyclick',
+
+ 'rowbodydblclick',
+
+
+ 'rowcontextmenu',
+
+ 'cellcontextmenu',
+
+ 'headercontextmenu',
+
+ 'groupcontextmenu',
+
+ 'containercontextmenu',
+
+ 'rowbodycontextmenu',
+
+ 'bodyscroll',
+
+ 'columnresize',
+
+ 'columnmove',
+
+ 'sortchange',
+
+ 'groupchange',
+
+ 'reconfigure',
+
+ 'viewready'
+ );
+ },
+
+
+ onRender : function(ct, position){
+ Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
+
+ var c = this.getGridEl();
+
+ this.el.addClass('x-grid-panel');
+
+ this.mon(c, {
+ scope: this,
+ mousedown: this.onMouseDown,
+ click: this.onClick,
+ dblclick: this.onDblClick,
+ contextmenu: this.onContextMenu
+ });
+
+ this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
+
+ var view = this.getView();
+ view.init(this);
+ view.render();
+ this.getSelectionModel().init(this);
+ },
+
+
+ initEvents : function(){
+ Ext.grid.GridPanel.superclass.initEvents.call(this);
+
+ if(this.loadMask){
+ this.loadMask = new Ext.LoadMask(this.bwrap,
+ Ext.apply({store:this.store}, this.loadMask));
+ }
+ },
+
+ initStateEvents : function(){
+ Ext.grid.GridPanel.superclass.initStateEvents.call(this);
+ this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
+ },
+
+ applyState : function(state){
+ var cm = this.colModel,
+ cs = state.columns,
+ store = this.store,
+ s,
+ c,
+ colIndex;
+
+ if(cs){
+ for(var i = 0, len = cs.length; i < len; i++){
+ s = cs[i];
+ c = cm.getColumnById(s.id);
+ if(c){
+ colIndex = cm.getIndexById(s.id);
+ cm.setState(colIndex, {
+ hidden: s.hidden,
+ width: s.width,
+ sortable: c.sortable,
+ editable: c.editable
+ });
+ if(colIndex != i){
+ cm.moveColumn(colIndex, i);
+ }
+ }
+ }
+ }
+ if(store){
+ s = state.sort;
+ if(s){
+ store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
+ }
+ s = state.group;
+ if(store.groupBy){
+ if(s){
+ store.groupBy(s);
+ }else{
+ store.clearGrouping();
+ }
+ }
+
+ }
+ var o = Ext.apply({}, state);
+ delete o.columns;
+ delete o.sort;
+ Ext.grid.GridPanel.superclass.applyState.call(this, o);
+ },
+
+ getState : function(){
+ var o = {columns: []},
+ store = this.store,
+ ss,
+ gs;
+
+ for(var i = 0, c; (c = this.colModel.config[i]); i++){
+ o.columns[i] = {
+ id: c.id,
+ width: c.width
+ };
+ if(c.hidden){
+ o.columns[i].hidden = true;
+ }
+ }
+ if(store){
+ ss = store.getSortState();
+ if(ss){
+ o.sort = ss;
+ }
+ if(store.getGroupState){
+ gs = store.getGroupState();
+ if(gs){
+ o.group = gs;
+ }
+ }
+ }
+ return o;
+ },
+
+
+ afterRender : function(){
+ Ext.grid.GridPanel.superclass.afterRender.call(this);
+ var v = this.view;
+ this.on('bodyresize', v.layout, v);
+ v.layout(true);
+ if(this.deferRowRender){
+ if (!this.deferRowRenderTask){
+ this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
+ }
+ this.deferRowRenderTask.delay(10);
+ }else{
+ v.afterRender();
+ }
+ this.viewReady = true;
+ },
+
+
+ reconfigure : function(store, colModel){
+ var rendered = this.rendered;
+ if(rendered){
+ if(this.loadMask){
+ this.loadMask.destroy();
+ this.loadMask = new Ext.LoadMask(this.bwrap,
+ Ext.apply({}, {store:store}, this.initialConfig.loadMask));
+ }
+ }
+ if(this.view){
+ this.view.initData(store, colModel);
+ }
+ this.store = store;
+ this.colModel = colModel;
+ if(rendered){
+ this.view.refresh(true);
+ }
+ this.fireEvent('reconfigure', this, store, colModel);
+ },
+
+
+ onDestroy : function(){
+ if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
+ this.deferRowRenderTask.cancel();
+ }
+ if(this.rendered){
+ Ext.destroy(this.view, this.loadMask);
+ }else if(this.store && this.store.autoDestroy){
+ this.store.destroy();
+ }
+ Ext.destroy(this.colModel, this.selModel);
+ this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
+ Ext.grid.GridPanel.superclass.onDestroy.call(this);
+ },
+
+
+ processEvent : function(name, e){
+ this.view.processEvent(name, e);
+ },
+
+
+ onClick : function(e){
+ this.processEvent('click', e);
+ },
+
+
+ onMouseDown : function(e){
+ this.processEvent('mousedown', e);
+ },
+
+
+ onContextMenu : function(e, t){
+ this.processEvent('contextmenu', e);
+ },
+
+
+ onDblClick : function(e){
+ this.processEvent('dblclick', e);
+ },
+
+
+ walkCells : function(row, col, step, fn, scope){
+ var cm = this.colModel,
+ clen = cm.getColumnCount(),
+ ds = this.store,
+ rlen = ds.getCount(),
+ first = true;
+
+ if(step < 0){
+ if(col < 0){
+ row--;
+ first = false;
+ }
+ while(row >= 0){
+ if(!first){
+ col = clen-1;
+ }
+ first = false;
+ while(col >= 0){
+ if(fn.call(scope || this, row, col, cm) === true){
+ return [row, col];
+ }
+ col--;
+ }
+ row--;
+ }
+ } else {
+ if(col >= clen){
+ row++;
+ first = false;
+ }
+ while(row < rlen){
+ if(!first){
+ col = 0;
+ }
+ first = false;
+ while(col < clen){
+ if(fn.call(scope || this, row, col, cm) === true){
+ return [row, col];
+ }
+ col++;
+ }
+ row++;
+ }
+ }
+ return null;
+ },
+
+
+ getGridEl : function(){
+ return this.body;
+ },
+
+
+ stopEditing : Ext.emptyFn,
+
+
+ getSelectionModel : function(){
+ if(!this.selModel){
+ this.selModel = new Ext.grid.RowSelectionModel(
+ this.disableSelection ? {selectRow: Ext.emptyFn} : null);
+ }
+ return this.selModel;
+ },
+
+
+ getStore : function(){
+ return this.store;
+ },
+
+
+ getColumnModel : function(){
+ return this.colModel;
+ },
+
+
+ getView : function() {
+ if (!this.view) {
+ this.view = new Ext.grid.GridView(this.viewConfig);
+ }
+
+ return this.view;
+ },
+
+ getDragDropText : function(){
+ var count = this.selModel.getCount ? this.selModel.getCount() : 1;
+ return String.format(this.ddText, count, count == 1 ? '' : 's');
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+});
+Ext.reg('grid', Ext.grid.GridPanel);
+Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {
+
+
+ aggregator: 'sum',
+
+
+ renderer: undefined,
+
+
+
+
+
+
+
+
+ initComponent: function() {
+ Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);
+
+ this.initAxes();
+
+
+ this.enableColumnResize = false;
+
+ this.viewConfig = Ext.apply(this.viewConfig || {}, {
+ forceFit: true
+ });
+
+
+
+ this.colModel = new Ext.grid.ColumnModel({});
+ },
+
+
+ getAggregator: function() {
+ if (typeof this.aggregator == 'string') {
+ return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
+ } else {
+ return this.aggregator;
+ }
+ },
+
+
+ setAggregator: function(aggregator) {
+ this.aggregator = aggregator;
+ },
+
+
+ setMeasure: function(measure) {
+ this.measure = measure;
+ },
+
+
+ setLeftAxis: function(axis, refresh) {
+
+ this.leftAxis = axis;
+
+ if (refresh) {
+ this.view.refresh();
+ }
+ },
+
+
+ setTopAxis: function(axis, refresh) {
+
+ this.topAxis = axis;
+
+ if (refresh) {
+ this.view.refresh();
+ }
+ },
+
+
+ initAxes: function() {
+ var PivotAxis = Ext.grid.PivotAxis;
+
+ if (!(this.leftAxis instanceof PivotAxis)) {
+ this.setLeftAxis(new PivotAxis({
+ orientation: 'vertical',
+ dimensions : this.leftAxis || [],
+ store : this.store
+ }));
+ };
+
+ if (!(this.topAxis instanceof PivotAxis)) {
+ this.setTopAxis(new PivotAxis({
+ orientation: 'horizontal',
+ dimensions : this.topAxis || [],
+ store : this.store
+ }));
+ };
+ },
+
+
+ extractData: function() {
+ var records = this.store.data.items,
+ recCount = records.length,
+ cells = [],
+ record, i, j, k;
+
+ if (recCount == 0) {
+ return [];
+ }
+
+ var leftTuples = this.leftAxis.getTuples(),
+ leftCount = leftTuples.length,
+ topTuples = this.topAxis.getTuples(),
+ topCount = topTuples.length,
+ aggregator = this.getAggregator();
+
+ for (i = 0; i < recCount; i++) {
+ record = records[i];
+
+ for (j = 0; j < leftCount; j++) {
+ cells[j] = cells[j] || [];
+
+ if (leftTuples[j].matcher(record) === true) {
+ for (k = 0; k < topCount; k++) {
+ cells[j][k] = cells[j][k] || [];
+
+ if (topTuples[k].matcher(record)) {
+ cells[j][k].push(record);
+ }
+ }
+ }
+ }
+ }
+
+ var rowCount = cells.length,
+ colCount, row;
+
+ for (i = 0; i < rowCount; i++) {
+ row = cells[i];
+ colCount = row.length;
+
+ for (j = 0; j < colCount; j++) {
+ cells[i][j] = aggregator(cells[i][j], this.measure);
+ }
+ }
+
+ return cells;
+ },
+
+
+ getView: function() {
+ if (!this.view) {
+ this.view = new Ext.grid.PivotGridView(this.viewConfig);
+ }
+
+ return this.view;
+ }
+});
+
+Ext.reg('pivotgrid', Ext.grid.PivotGrid);
+
+
+Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();
+
+Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
+ var length = records.length,
+ total = 0,
+ i;
+
+ for (i = 0; i < length; i++) {
+ total += records[i].get(measure);
+ }
+
+ return total;
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
+ var length = records.length,
+ total = 0,
+ i;
+
+ for (i = 0; i < length; i++) {
+ total += records[i].get(measure);
+ }
+
+ return (total / length) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
+ var data = [],
+ length = records.length,
+ i;
+
+ for (i = 0; i < length; i++) {
+ data.push(records[i].get(measure));
+ }
+
+ return Math.min.apply(this, data) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
+ var data = [],
+ length = records.length,
+ i;
+
+ for (i = 0; i < length; i++) {
+ data.push(records[i].get(measure));
+ }
+
+ return Math.max.apply(this, data) || 'n/a';
+});
+
+Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
+ return records.length;
+});
+Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
+
+
+
+
+
+
+
+
+
+
+
+ deferEmptyText : true,
+
+
+ scrollOffset : undefined,
+
+
+ autoFill : false,
+
+
+ forceFit : false,
+
+
+ sortClasses : ['sort-asc', 'sort-desc'],
+
+
+ sortAscText : 'Sort Ascending',
+
+
+ sortDescText : 'Sort Descending',
+
+
+ hideSortIcons: false,
+
+
+ columnsText : 'Columns',
+
+
+ selectedRowClass : 'x-grid3-row-selected',
+
+
+ borderWidth : 2,
+ tdClass : 'x-grid3-cell',
+ hdCls : 'x-grid3-hd',
+
+
+
+ markDirty : true,
+
+
+ cellSelectorDepth : 4,
+
+
+ rowSelectorDepth : 10,
+
+
+ rowBodySelectorDepth : 10,
+
+
+ cellSelector : 'td.x-grid3-cell',
+
+
+ rowSelector : 'div.x-grid3-row',
+
+
+ rowBodySelector : 'div.x-grid3-row-body',
+
+
+ firstRowCls: 'x-grid3-row-first',
+ lastRowCls: 'x-grid3-row-last',
+ rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
+
+
+ headerMenuOpenCls: 'x-grid3-hd-menu-open',
+
+
+ rowOverCls: 'x-grid3-row-over',
+
+ constructor : function(config) {
+ Ext.apply(this, config);
+
+
+ this.addEvents(
+
+ 'beforerowremoved',
+
+
+ 'beforerowsinserted',
+
+
+ 'beforerefresh',
+
+
+ 'rowremoved',
+
+
+ 'rowsinserted',
+
+
+ 'rowupdated',
+
+
+ 'refresh'
+ );
+
+ Ext.grid.GridView.superclass.constructor.call(this);
+ },
+
+
+
+
+ masterTpl: new Ext.Template(
+ '<div class="x-grid3" hidefocus="true">',
+ '<div class="x-grid3-viewport">',
+ '<div class="x-grid3-header">',
+ '<div class="x-grid3-header-inner">',
+ '<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
+ '</div>',
+ '<div class="x-clear"></div>',
+ '</div>',
+ '<div class="x-grid3-scroller">',
+ '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
+ '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
+ '</div>',
+ '</div>',
+ '<div class="x-grid3-resize-marker">&#160;</div>',
+ '<div class="x-grid3-resize-proxy">&#160;</div>',
+ '</div>'
+ ),
+
+
+ headerTpl: new Ext.Template(
+ '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+ '<thead>',
+ '<tr class="x-grid3-hd-row">{cells}</tr>',
+ '</thead>',
+ '</table>'
+ ),
+
+
+ bodyTpl: new Ext.Template('{rows}'),
+
+
+ cellTpl: new Ext.Template(
+ '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
+ '<div class="x-grid3-cell-inner x-grid3-col-{id} x-unselectable" unselectable="on" {attr}>{value}</div>',
+ '</td>'
+ ),
+
+
+ initTemplates : function() {
+ var templates = this.templates || {},
+ template, name,
+
+ headerCellTpl = new Ext.Template(
+ '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
+ '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
+ this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
+ '{value}',
+ '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
+ '</div>',
+ '</td>'
+ ),
+
+ rowBodyText = [
+ '<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
+ '<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
+ '<div class="x-grid3-row-body">{body}</div>',
+ '</td>',
+ '</tr>'
+ ].join(""),
+
+ innerText = [
+ '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+ '<tbody>',
+ '<tr>{cells}</tr>',
+ this.enableRowBody ? rowBodyText : '',
+ '</tbody>',
+ '</table>'
+ ].join("");
+
+ Ext.applyIf(templates, {
+ hcell : headerCellTpl,
+ cell : this.cellTpl,
+ body : this.bodyTpl,
+ header : this.headerTpl,
+ master : this.masterTpl,
+ row : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
+ rowInner: new Ext.Template(innerText)
+ });
+
+ for (name in templates) {
+ template = templates[name];
+
+ if (template && Ext.isFunction(template.compile) && !template.compiled) {
+ template.disableFormats = true;
+ template.compile();
+ }
+ }
+
+ this.templates = templates;
+ this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
+ },
+
+
+ fly : function(el) {
+ if (!this._flyweight) {
+ this._flyweight = new Ext.Element.Flyweight(document.body);
+ }
+ this._flyweight.dom = el;
+ return this._flyweight;
+ },
+
+
+ getEditorParent : function() {
+ return this.scroller.dom;
+ },
+
+
+ initElements : function() {
+ var Element = Ext.Element,
+ el = Ext.get(this.grid.getGridEl().dom.firstChild),
+ mainWrap = new Element(el.child('div.x-grid3-viewport')),
+ mainHd = new Element(mainWrap.child('div.x-grid3-header')),
+ scroller = new Element(mainWrap.child('div.x-grid3-scroller'));
+
+ if (this.grid.hideHeaders) {
+ mainHd.setDisplayed(false);
+ }
+
+ if (this.forceFit) {
+ scroller.setStyle('overflow-x', 'hidden');
+ }
+
+
+
+ Ext.apply(this, {
+ el : el,
+ mainWrap: mainWrap,
+ scroller: scroller,
+ mainHd : mainHd,
+ innerHd : mainHd.child('div.x-grid3-header-inner').dom,
+ mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
+ focusEl : new Element(Element.fly(scroller).child('a')),
+
+ resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
+ resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
+ });
+
+ this.focusEl.swallowEvent('click', true);
+ },
+
+
+ getRows : function() {
+ return this.hasRows() ? this.mainBody.dom.childNodes : [];
+ },
+
+
+
+
+ findCell : function(el) {
+ if (!el) {
+ return false;
+ }
+ return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
+ },
+
+
+ findCellIndex : function(el, requiredCls) {
+ var cell = this.findCell(el),
+ hasCls;
+
+ if (cell) {
+ hasCls = this.fly(cell).hasClass(requiredCls);
+ if (!requiredCls || hasCls) {
+ return this.getCellIndex(cell);
+ }
+ }
+ return false;
+ },
+
+
+ getCellIndex : function(el) {
+ if (el) {
+ var match = el.className.match(this.colRe);
+
+ if (match && match[1]) {
+ return this.cm.getIndexById(match[1]);
+ }
+ }
+ return false;
+ },
+
+
+ findHeaderCell : function(el) {
+ var cell = this.findCell(el);
+ return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
+ },
+
+
+ findHeaderIndex : function(el){
+ return this.findCellIndex(el, this.hdCls);
+ },
+
+
+ findRow : function(el) {
+ if (!el) {
+ return false;
+ }
+ return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
+ },
+
+
+ findRowIndex : function(el) {
+ var row = this.findRow(el);
+ return row ? row.rowIndex : false;
+ },
+
+
+ findRowBody : function(el) {
+ if (!el) {
+ return false;
+ }
+
+ return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
+ },
+
+
+
+
+ getRow : function(row) {
+ return this.getRows()[row];
+ },
+
+
+ getCell : function(row, col) {
+ return Ext.fly(this.getRow(row)).query(this.cellSelector)[col];
+ },
+
+
+ getHeaderCell : function(index) {
+ return this.mainHd.dom.getElementsByTagName('td')[index];
+ },
+
+
+
+
+ addRowClass : function(rowId, cls) {
+ var row = this.getRow(rowId);
+ if (row) {
+ this.fly(row).addClass(cls);
+ }
+ },
+
+
+ removeRowClass : function(row, cls) {
+ var r = this.getRow(row);
+ if(r){
+ this.fly(r).removeClass(cls);
+ }
+ },
+
+
+ removeRow : function(row) {
+ Ext.removeNode(this.getRow(row));
+ this.syncFocusEl(row);
+ },
+
+
+ removeRows : function(firstRow, lastRow) {
+ var bd = this.mainBody.dom,
+ rowIndex;
+
+ for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
+ Ext.removeNode(bd.childNodes[firstRow]);
+ }
+
+ this.syncFocusEl(firstRow);
+ },
+
+
+
+
+ getScrollState : function() {
+ var sb = this.scroller.dom;
+
+ return {
+ left: sb.scrollLeft,
+ top : sb.scrollTop
+ };
+ },
+
+
+ restoreScroll : function(state) {
+ var sb = this.scroller.dom;
+ sb.scrollLeft = state.left;
+ sb.scrollTop = state.top;
+ },
+
+
+ scrollToTop : function() {
+ var dom = this.scroller.dom;
+
+ dom.scrollTop = 0;
+ dom.scrollLeft = 0;
+ },
+
+
+ syncScroll : function() {
+ this.syncHeaderScroll();
+ var mb = this.scroller.dom;
+ this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
+ },
+
+
+ syncHeaderScroll : function() {
+ var innerHd = this.innerHd,
+ scrollLeft = this.scroller.dom.scrollLeft;
+
+ innerHd.scrollLeft = scrollLeft;
+ innerHd.scrollLeft = scrollLeft;
+ },
+
+
+ updateSortIcon : function(col, dir) {
+ var sortClasses = this.sortClasses,
+ sortClass = sortClasses[dir == "DESC" ? 1 : 0],
+ headers = this.mainHd.select('td').removeClass(sortClasses);
+
+ headers.item(col).addClass(sortClass);
+ },
+
+
+ updateAllColumnWidths : function() {
+ var totalWidth = this.getTotalWidth(),
+ colCount = this.cm.getColumnCount(),
+ rows = this.getRows(),
+ rowCount = rows.length,
+ widths = [],
+ row, rowFirstChild, trow, i, j;
+
+ for (i = 0; i < colCount; i++) {
+ widths[i] = this.getColumnWidth(i);
+ this.getHeaderCell(i).style.width = widths[i];
+ }
+
+ this.updateHeaderWidth();
+
+ for (i = 0; i < rowCount; i++) {
+ row = rows[i];
+ row.style.width = totalWidth;
+ rowFirstChild = row.firstChild;
+
+ if (rowFirstChild) {
+ rowFirstChild.style.width = totalWidth;
+ trow = rowFirstChild.rows[0];
+
+ for (j = 0; j < colCount; j++) {
+ trow.childNodes[j].style.width = widths[j];
+ }
+ }
+ }
+
+ this.onAllColumnWidthsUpdated(widths, totalWidth);
+ },
+
+
+ updateColumnWidth : function(column, width) {
+ var columnWidth = this.getColumnWidth(column),
+ totalWidth = this.getTotalWidth(),
+ headerCell = this.getHeaderCell(column),
+ nodes = this.getRows(),
+ nodeCount = nodes.length,
+ row, i, firstChild;
+
+ this.updateHeaderWidth();
+ headerCell.style.width = columnWidth;
+
+ for (i = 0; i < nodeCount; i++) {
+ row = nodes[i];
+ firstChild = row.firstChild;
+
+ row.style.width = totalWidth;
+ if (firstChild) {
+ firstChild.style.width = totalWidth;
+ firstChild.rows[0].childNodes[column].style.width = columnWidth;
+ }
+ }
+
+ this.onColumnWidthUpdated(column, columnWidth, totalWidth);
+ },
+
+
+ updateColumnHidden : function(col, hidden) {
+ var totalWidth = this.getTotalWidth(),
+ display = hidden ? 'none' : '',
+ headerCell = this.getHeaderCell(col),
+ nodes = this.getRows(),
+ nodeCount = nodes.length,
+ row, rowFirstChild, i;
+
+ this.updateHeaderWidth();
+ headerCell.style.display = display;
+
+ for (i = 0; i < nodeCount; i++) {
+ row = nodes[i];
+ row.style.width = totalWidth;
+ rowFirstChild = row.firstChild;
+
+ if (rowFirstChild) {
+ rowFirstChild.style.width = totalWidth;
+ rowFirstChild.rows[0].childNodes[col].style.display = display;
+ }
+ }
+
+ this.onColumnHiddenUpdated(col, hidden, totalWidth);
+ delete this.lastViewWidth;
+ this.layout();
+ },
+
+
+ doRender : function(columns, records, store, startRow, colCount, stripe) {
+ var templates = this.templates,
+ cellTemplate = templates.cell,
+ rowTemplate = templates.row,
+ last = colCount - 1,
+ tstyle = 'width:' + this.getTotalWidth() + ';',
+
+ rowBuffer = [],
+ colBuffer = [],
+ rowParams = {tstyle: tstyle},
+ meta = {},
+ len = records.length,
+ alt,
+ column,
+ record, i, j, rowIndex;
+
+
+ for (j = 0; j < len; j++) {
+ record = records[j];
+ colBuffer = [];
+
+ rowIndex = j + startRow;
+
+
+ for (i = 0; i < colCount; i++) {
+ column = columns[i];
+
+ meta.id = column.id;
+ meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
+ meta.attr = meta.cellAttr = '';
+ meta.style = column.style;
+ meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
+
+ if (Ext.isEmpty(meta.value)) {
+ meta.value = '&#160;';
+ }
+
+ if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
+ meta.css += ' x-grid3-dirty-cell';
+ }
+
+ colBuffer[colBuffer.length] = cellTemplate.apply(meta);
+ }
+
+ alt = [];
+
+ if (stripe && ((rowIndex + 1) % 2 === 0)) {
+ alt[0] = 'x-grid3-row-alt';
+ }
+
+ if (record.dirty) {
+ alt[1] = ' x-grid3-dirty-row';
+ }
+
+ rowParams.cols = colCount;
+
+ if (this.getRowClass) {
+ alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
+ }
+
+ rowParams.alt = alt.join(' ');
+ rowParams.cells = colBuffer.join('');
+
+ rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
+ }
+
+ return rowBuffer.join('');
+ },
+
+
+ processRows : function(startRow, skipStripe) {
+ if (!this.ds || this.ds.getCount() < 1) {
+ return;
+ }
+
+ var rows = this.getRows(),
+ length = rows.length,
+ row, i;
+
+ skipStripe = skipStripe || !this.grid.stripeRows;
+ startRow = startRow || 0;
+
+ for (i = 0; i < length; i++) {
+ row = rows[i];
+ if (row) {
+ row.rowIndex = i;
+ if (!skipStripe) {
+ row.className = row.className.replace(this.rowClsRe, ' ');
+ if ((i + 1) % 2 === 0){
+ row.className += ' x-grid3-row-alt';
+ }
+ }
+ }
+ }
+
+
+ if (startRow === 0) {
+ Ext.fly(rows[0]).addClass(this.firstRowCls);
+ }
+
+ Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
+ },
+
+
+ afterRender : function() {
+ if (!this.ds || !this.cm) {
+ return;
+ }
+
+ this.mainBody.dom.innerHTML = this.renderBody() || '&#160;';
+ this.processRows(0, true);
+
+ if (this.deferEmptyText !== true) {
+ this.applyEmptyText();
+ }
+
+ this.grid.fireEvent('viewready', this.grid);
+ },
+
+
+ afterRenderUI: function() {
+ var grid = this.grid;
+
+ this.initElements();
+
+
+ Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
+
+ this.mainHd.on({
+ scope : this,
+ mouseover: this.handleHdOver,
+ mouseout : this.handleHdOut,
+ mousemove: this.handleHdMove
+ });
+
+ this.scroller.on('scroll', this.syncScroll, this);
+
+ if (grid.enableColumnResize !== false) {
+ this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
+ }
+
+ if (grid.enableColumnMove) {
+ this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
+ this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
+ }
+
+ if (grid.enableHdMenu !== false) {
+ this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'});
+ this.hmenu.add(
+ {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
+ {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
+ );
+
+ if (grid.enableColumnHide !== false) {
+ this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'});
+ this.colMenu.on({
+ scope : this,
+ beforeshow: this.beforeColMenuShow,
+ itemclick : this.handleHdMenuClick
+ });
+ this.hmenu.add({
+ itemId: 'sortSep',
+ xtype: 'menuseparator'
+ }, {
+ itemId:'columns',
+ hideOnClick: false,
+ text: this.columnsText,
+ menu: this.colMenu,
+ iconCls: 'x-cols-icon'
+ });
+ }
+
+ this.hmenu.on('itemclick', this.handleHdMenuClick, this);
+ }
+
+ if (grid.trackMouseOver) {
+ this.mainBody.on({
+ scope : this,
+ mouseover: this.onRowOver,
+ mouseout : this.onRowOut
+ });
+ }
+
+ if (grid.enableDragDrop || grid.enableDrag) {
+ this.dragZone = new Ext.grid.GridDragZone(grid, {
+ ddGroup : grid.ddGroup || 'GridDD'
+ });
+ }
+
+ this.updateHeaderSortState();
+ },
+
+
+ renderUI : function() {
+ var templates = this.templates;
+
+ return templates.master.apply({
+ body : templates.body.apply({rows:'&#160;'}),
+ header: this.renderHeaders(),
+ ostyle: 'width:' + this.getOffsetWidth() + ';',
+ bstyle: 'width:' + this.getTotalWidth() + ';'
+ });
+ },
+
+
+ processEvent : function(name, e) {
+ var target = e.getTarget(),
+ grid = this.grid,
+ header = this.findHeaderIndex(target),
+ row, cell, col, body;
+
+ grid.fireEvent(name, e);
+
+ if (header !== false) {
+ grid.fireEvent('header' + name, grid, header, e);
+ } else {
+ row = this.findRowIndex(target);
+
+
+
+
+ if (row !== false) {
+ cell = this.findCellIndex(target);
+ if (cell !== false) {
+ col = grid.colModel.getColumnAt(cell);
+ if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
+ if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
+ grid.fireEvent('row' + name, grid, row, e);
+ }
+ }
+ } else {
+ if (grid.fireEvent('row' + name, grid, row, e) !== false) {
+ (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
+ }
+ }
+ } else {
+ grid.fireEvent('container' + name, grid, e);
+ }
+ }
+ },
+
+
+ layout : function(initial) {
+ if (!this.mainBody) {
+ return;
+ }
+
+ var grid = this.grid,
+ gridEl = grid.getGridEl(),
+ gridSize = gridEl.getSize(true),
+ gridWidth = gridSize.width,
+ gridHeight = gridSize.height,
+ scroller = this.scroller,
+ scrollStyle, headerHeight, scrollHeight;
+
+ if (gridWidth < 20 || gridHeight < 20) {
+ return;
+ }
+
+ if (grid.autoHeight) {
+ scrollStyle = scroller.dom.style;
+ scrollStyle.overflow = 'visible';
+
+ if (Ext.isWebKit) {
+ scrollStyle.position = 'static';
+ }
+ } else {
+ this.el.setSize(gridWidth, gridHeight);
+
+ headerHeight = this.mainHd.getHeight();
+ scrollHeight = gridHeight - headerHeight;
+
+ scroller.setSize(gridWidth, scrollHeight);
+
+ if (this.innerHd) {
+ this.innerHd.style.width = (gridWidth) + "px";
+ }
+ }
+
+ if (this.forceFit || (initial === true && this.autoFill)) {
+ if (this.lastViewWidth != gridWidth) {
+ this.fitColumns(false, false);
+ this.lastViewWidth = gridWidth;
+ }
+ } else {
+ this.autoExpand();
+ this.syncHeaderScroll();
+ }
+
+ this.onLayout(gridWidth, scrollHeight);
+ },
+
+
+
+ onLayout : function(vw, vh) {
+
+ },
+
+ onColumnWidthUpdated : function(col, w, tw) {
+
+ },
+
+ onAllColumnWidthsUpdated : function(ws, tw) {
+
+ },
+
+ onColumnHiddenUpdated : function(col, hidden, tw) {
+
+ },
+
+ updateColumnText : function(col, text) {
+
+ },
+
+ afterMove : function(colIndex) {
+
+ },
+
+
+
+ init : function(grid) {
+ this.grid = grid;
+
+ this.initTemplates();
+ this.initData(grid.store, grid.colModel);
+ this.initUI(grid);
+ },
+
+
+ getColumnId : function(index){
+ return this.cm.getColumnId(index);
+ },
+
+
+ getOffsetWidth : function() {
+ return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
+ },
+
+
+ getScrollOffset: function() {
+ return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
+ },
+
+
+ renderHeaders : function() {
+ var colModel = this.cm,
+ templates = this.templates,
+ headerTpl = templates.hcell,
+ properties = {},
+ colCount = colModel.getColumnCount(),
+ last = colCount - 1,
+ cells = [],
+ i, cssCls;
+
+ for (i = 0; i < colCount; i++) {
+ if (i == 0) {
+ cssCls = 'x-grid3-cell-first ';
+ } else {
+ cssCls = i == last ? 'x-grid3-cell-last ' : '';
+ }
+
+ properties = {
+ id : colModel.getColumnId(i),
+ value : colModel.getColumnHeader(i) || '',
+ style : this.getColumnStyle(i, true),
+ css : cssCls,
+ tooltip: this.getColumnTooltip(i)
+ };
+
+ if (colModel.config[i].align == 'right') {
+ properties.istyle = 'padding-right: 16px;';
+ } else {
+ delete properties.istyle;
+ }
+
+ cells[i] = headerTpl.apply(properties);
+ }
+
+ return templates.header.apply({
+ cells : cells.join(""),
+ tstyle: String.format("width: {0};", this.getTotalWidth())
+ });
+ },
+
+
+ getColumnTooltip : function(i) {
+ var tooltip = this.cm.getColumnTooltip(i);
+ if (tooltip) {
+ if (Ext.QuickTips.isEnabled()) {
+ return 'ext:qtip="' + tooltip + '"';
+ } else {
+ return 'title="' + tooltip + '"';
+ }
+ }
+
+ return '';
+ },
+
+
+ beforeUpdate : function() {
+ this.grid.stopEditing(true);
+ },
+
+
+ updateHeaders : function() {
+ this.innerHd.firstChild.innerHTML = this.renderHeaders();
+
+ this.updateHeaderWidth(false);
+ },
+
+
+ updateHeaderWidth: function(updateMain) {
+ var innerHdChild = this.innerHd.firstChild,
+ totalWidth = this.getTotalWidth();
+
+ innerHdChild.style.width = this.getOffsetWidth();
+ innerHdChild.firstChild.style.width = totalWidth;
+
+ if (updateMain !== false) {
+ this.mainBody.dom.style.width = totalWidth;
+ }
+ },
+
+
+ focusRow : function(row) {
+ this.focusCell(row, 0, false);
+ },
+
+
+ focusCell : function(row, col, hscroll) {
+ this.syncFocusEl(this.ensureVisible(row, col, hscroll));
+
+ var focusEl = this.focusEl;
+
+ if (Ext.isGecko) {
+ focusEl.focus();
+ } else {
+ focusEl.focus.defer(1, focusEl);
+ }
+ },
+
+
+ resolveCell : function(row, col, hscroll) {
+ if (!Ext.isNumber(row)) {
+ row = row.rowIndex;
+ }
+
+ if (!this.ds) {
+ return null;
+ }
+
+ if (row < 0 || row >= this.ds.getCount()) {
+ return null;
+ }
+ col = (col !== undefined ? col : 0);
+
+ var rowEl = this.getRow(row),
+ colModel = this.cm,
+ colCount = colModel.getColumnCount(),
+ cellEl;
+
+ if (!(hscroll === false && col === 0)) {
+ while (col < colCount && colModel.isHidden(col)) {
+ col++;
+ }
+
+ cellEl = this.getCell(row, col);
+ }
+
+ return {row: rowEl, cell: cellEl};
+ },
+
+
+ getResolvedXY : function(resolved) {
+ if (!resolved) {
+ return null;
+ }
+
+ var cell = resolved.cell,
+ row = resolved.row;
+
+ if (cell) {
+ return Ext.fly(cell).getXY();
+ } else {
+ return [this.el.getX(), Ext.fly(row).getY()];
+ }
+ },
+
+
+ syncFocusEl : function(row, col, hscroll) {
+ var xy = row;
+
+ if (!Ext.isArray(xy)) {
+ row = Math.min(row, Math.max(0, this.getRows().length-1));
+
+ if (isNaN(row)) {
+ return;
+ }
+
+ xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
+ }
+
+ this.focusEl.setXY(xy || this.scroller.getXY());
+ },
+
+
+ ensureVisible : function(row, col, hscroll) {
+ var resolved = this.resolveCell(row, col, hscroll);
+
+ if (!resolved || !resolved.row) {
+ return null;
+ }
+
+ var rowEl = resolved.row,
+ cellEl = resolved.cell,
+ c = this.scroller.dom,
+ p = rowEl,
+ ctop = 0,
+ stop = this.el.dom;
+
+ while (p && p != stop) {
+ ctop += p.offsetTop;
+ p = p.offsetParent;
+ }
+
+ ctop -= this.mainHd.dom.offsetHeight;
+ stop = parseInt(c.scrollTop, 10);
+
+ var cbot = ctop + rowEl.offsetHeight,
+ ch = c.clientHeight,
+ sbot = stop + ch;
+
+
+ if (ctop < stop) {
+ c.scrollTop = ctop;
+ } else if(cbot > sbot) {
+ c.scrollTop = cbot-ch;
+ }
+
+ if (hscroll !== false) {
+ var cleft = parseInt(cellEl.offsetLeft, 10),
+ cright = cleft + cellEl.offsetWidth,
+ sleft = parseInt(c.scrollLeft, 10),
+ sright = sleft + c.clientWidth;
+
+ if (cleft < sleft) {
+ c.scrollLeft = cleft;
+ } else if(cright > sright) {
+ c.scrollLeft = cright-c.clientWidth;
+ }
+ }
+
+ return this.getResolvedXY(resolved);
+ },
+
+
+ insertRows : function(dm, firstRow, lastRow, isUpdate) {
+ var last = dm.getCount() - 1;
+ if( !isUpdate && firstRow === 0 && lastRow >= last) {
+ this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
+ this.refresh();
+ this.fireEvent('rowsinserted', this, firstRow, lastRow);
+ } else {
+ if (!isUpdate) {
+ this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
+ }
+ var html = this.renderRows(firstRow, lastRow),
+ before = this.getRow(firstRow);
+ if (before) {
+ if(firstRow === 0){
+ Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
+ }
+ Ext.DomHelper.insertHtml('beforeBegin', before, html);
+ } else {
+ var r = this.getRow(last - 1);
+ if(r){
+ Ext.fly(r).removeClass(this.lastRowCls);
+ }
+ Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
+ }
+ if (!isUpdate) {
+ this.processRows(firstRow);
+ this.fireEvent('rowsinserted', this, firstRow, lastRow);
+ } else if (firstRow === 0 || firstRow >= last) {
+
+ Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
+ }
+ }
+ this.syncFocusEl(firstRow);
+ },
+
+
+ deleteRows : function(dm, firstRow, lastRow) {
+ if (dm.getRowCount() < 1) {
+ this.refresh();
+ } else {
+ this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
+
+ this.removeRows(firstRow, lastRow);
+
+ this.processRows(firstRow);
+ this.fireEvent('rowsdeleted', this, firstRow, lastRow);
+ }
+ },
+
+
+ getColumnStyle : function(colIndex, isHeader) {
+ var colModel = this.cm,
+ colConfig = colModel.config,
+ style = isHeader ? '' : colConfig[colIndex].css || '',
+ align = colConfig[colIndex].align;
+
+ style += String.format("width: {0};", this.getColumnWidth(colIndex));
+
+ if (colModel.isHidden(colIndex)) {
+ style += 'display: none; ';
+ }
+
+ if (align) {
+ style += String.format("text-align: {0};", align);
+ }
+
+ return style;
+ },
+
+
+ getColumnWidth : function(column) {
+ var columnWidth = this.cm.getColumnWidth(column),
+ borderWidth = this.borderWidth;
+
+ if (Ext.isNumber(columnWidth)) {
+ if (Ext.isBorderBox) {
+ return columnWidth + "px";
+ } else {
+ return Math.max(columnWidth - borderWidth, 0) + "px";
+ }
+ } else {
+ return columnWidth;
+ }
+ },
+
+
+ getTotalWidth : function() {
+ return this.cm.getTotalWidth() + 'px';
+ },
+
+
+ fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
+ var grid = this.grid,
+ colModel = this.cm,
+ totalColWidth = colModel.getTotalWidth(false),
+ gridWidth = this.getGridInnerWidth(),
+ extraWidth = gridWidth - totalColWidth,
+ columns = [],
+ extraCol = 0,
+ width = 0,
+ colWidth, fraction, i;
+
+
+ if (gridWidth < 20 || extraWidth === 0) {
+ return false;
+ }
+
+ var visibleColCount = colModel.getColumnCount(true),
+ totalColCount = colModel.getColumnCount(false),
+ adjCount = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);
+
+ if (adjCount === 0) {
+ adjCount = 1;
+ omitColumn = undefined;
+ }
+
+
+ for (i = 0; i < totalColCount; i++) {
+ if (!colModel.isFixed(i) && i !== omitColumn) {
+ colWidth = colModel.getColumnWidth(i);
+ columns.push(i, colWidth);
+
+ if (!colModel.isHidden(i)) {
+ extraCol = i;
+ width += colWidth;
+ }
+ }
+ }
+
+ fraction = (gridWidth - colModel.getTotalWidth()) / width;
+
+ while (columns.length) {
+ colWidth = columns.pop();
+ i = columns.pop();
+
+ colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
+ }
+
+
+ totalColWidth = colModel.getTotalWidth(false);
+
+ if (totalColWidth > gridWidth) {
+ var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
+ newWidth = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));
+
+ colModel.setColumnWidth(adjustCol, newWidth, true);
+ }
+
+ if (preventRefresh !== true) {
+ this.updateAllColumnWidths();
+ }
+
+ return true;
+ },
+
+
+ autoExpand : function(preventUpdate) {
+ var grid = this.grid,
+ colModel = this.cm,
+ gridWidth = this.getGridInnerWidth(),
+ totalColumnWidth = colModel.getTotalWidth(false),
+ autoExpandColumn = grid.autoExpandColumn;
+
+ if (!this.userResized && autoExpandColumn) {
+ if (gridWidth != totalColumnWidth) {
+
+ var colIndex = colModel.getIndexById(autoExpandColumn),
+ currentWidth = colModel.getColumnWidth(colIndex),
+ desiredWidth = gridWidth - totalColumnWidth + currentWidth,
+ newWidth = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);
+
+ if (currentWidth != newWidth) {
+ colModel.setColumnWidth(colIndex, newWidth, true);
+
+ if (preventUpdate !== true) {
+ this.updateColumnWidth(colIndex, newWidth);
+ }
+ }
+ }
+ }
+ },
+
+
+ getGridInnerWidth: function() {
+ return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
+ },
+
+
+ getColumnData : function() {
+ var columns = [],
+ colModel = this.cm,
+ colCount = colModel.getColumnCount(),
+ fields = this.ds.fields,
+ i, name;
+
+ for (i = 0; i < colCount; i++) {
+ name = colModel.getDataIndex(i);
+
+ columns[i] = {
+ name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
+ renderer: colModel.getRenderer(i),
+ scope : colModel.getRendererScope(i),
+ id : colModel.getColumnId(i),
+ style : this.getColumnStyle(i)
+ };
+ }
+
+ return columns;
+ },
+
+
+ renderRows : function(startRow, endRow) {
+ var grid = this.grid,
+ store = grid.store,
+ stripe = grid.stripeRows,
+ colModel = grid.colModel,
+ colCount = colModel.getColumnCount(),
+ rowCount = store.getCount(),
+ records;
+
+ if (rowCount < 1) {
+ return '';
+ }
+
+ startRow = startRow || 0;
+ endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
+ records = store.getRange(startRow, endRow);
+
+ return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
+ },
+
+
+ renderBody : function(){
+ var markup = this.renderRows() || '&#160;';
+ return this.templates.body.apply({rows: markup});
+ },
+
+
+ refreshRow: function(record) {
+ var store = this.ds,
+ colCount = this.cm.getColumnCount(),
+ columns = this.getColumnData(),
+ last = colCount - 1,
+ cls = ['x-grid3-row'],
+ rowParams = {
+ tstyle: String.format("width: {0};", this.getTotalWidth())
+ },
+ colBuffer = [],
+ cellTpl = this.templates.cell,
+ rowIndex, row, column, meta, css, i;
+
+ if (Ext.isNumber(record)) {
+ rowIndex = record;
+ record = store.getAt(rowIndex);
+ } else {
+ rowIndex = store.indexOf(record);
+ }
+
+
+ if (!record || rowIndex < 0) {
+ return;
+ }
+
+
+ for (i = 0; i < colCount; i++) {
+ column = columns[i];
+
+ if (i == 0) {
+ css = 'x-grid3-cell-first';
+ } else {
+ css = (i == last) ? 'x-grid3-cell-last ' : '';
+ }
+
+ meta = {
+ id : column.id,
+ style : column.style,
+ css : css,
+ attr : "",
+ cellAttr: ""
+ };
+
+ meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
+
+ if (Ext.isEmpty(meta.value)) {
+ meta.value = '&#160;';
+ }
+
+ if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
+ meta.css += ' x-grid3-dirty-cell';
+ }
+
+ colBuffer[i] = cellTpl.apply(meta);
+ }
+
+ row = this.getRow(rowIndex);
+ row.className = '';
+
+ if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
+ cls.push('x-grid3-row-alt');
+ }
+
+ if (this.getRowClass) {
+ rowParams.cols = colCount;
+ cls.push(this.getRowClass(record, rowIndex, rowParams, store));
+ }
+
+ this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
+ rowParams.cells = colBuffer.join("");
+ row.innerHTML = this.templates.rowInner.apply(rowParams);
+
+ this.fireEvent('rowupdated', this, rowIndex, record);
+ },
+
+
+ refresh : function(headersToo) {
+ this.fireEvent('beforerefresh', this);
+ this.grid.stopEditing(true);
+
+ var result = this.renderBody();
+ this.mainBody.update(result).setWidth(this.getTotalWidth());
+ if (headersToo === true) {
+ this.updateHeaders();
+ this.updateHeaderSortState();
+ }
+ this.processRows(0, true);
+ this.layout();
+ this.applyEmptyText();
+ this.fireEvent('refresh', this);
+ },
+
+
+ applyEmptyText : function() {
+ if (this.emptyText && !this.hasRows()) {
+ this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
+ }
+ },
+
+
+ updateHeaderSortState : function() {
+ var state = this.ds.getSortState();
+ if (!state) {
+ return;
+ }
+
+ if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
+ this.grid.fireEvent('sortchange', this.grid, state);
+ }
+
+ this.sortState = state;
+
+ var sortColumn = this.cm.findColumnIndex(state.field);
+ if (sortColumn != -1) {
+ var sortDir = state.direction;
+ this.updateSortIcon(sortColumn, sortDir);
+ }
+ },
+
+
+ clearHeaderSortState : function() {
+ if (!this.sortState) {
+ return;
+ }
+ this.grid.fireEvent('sortchange', this.grid, null);
+ this.mainHd.select('td').removeClass(this.sortClasses);
+ delete this.sortState;
+ },
+
+
+ destroy : function() {
+ var me = this,
+ grid = me.grid,
+ gridEl = grid.getGridEl(),
+ dragZone = me.dragZone,
+ splitZone = me.splitZone,
+ columnDrag = me.columnDrag,
+ columnDrop = me.columnDrop,
+ scrollToTopTask = me.scrollToTopTask,
+ columnDragData,
+ columnDragProxy;
+
+ if (scrollToTopTask && scrollToTopTask.cancel) {
+ scrollToTopTask.cancel();
+ }
+
+ Ext.destroyMembers(me, 'colMenu', 'hmenu');
+
+ me.initData(null, null);
+ me.purgeListeners();
+
+ Ext.fly(me.innerHd).un("click", me.handleHdDown, me);
+
+ if (grid.enableColumnMove) {
+ columnDragData = columnDrag.dragData;
+ columnDragProxy = columnDrag.proxy;
+ Ext.destroy(
+ columnDrag.el,
+ columnDragProxy.ghost,
+ columnDragProxy.el,
+ columnDrop.el,
+ columnDrop.proxyTop,
+ columnDrop.proxyBottom,
+ columnDragData.ddel,
+ columnDragData.header
+ );
+
+ if (columnDragProxy.anim) {
+ Ext.destroy(columnDragProxy.anim);
+ }
+
+ delete columnDragProxy.ghost;
+ delete columnDragData.ddel;
+ delete columnDragData.header;
+ columnDrag.destroy();
+
+ delete Ext.dd.DDM.locationCache[columnDrag.id];
+ delete columnDrag._domRef;
+
+ delete columnDrop.proxyTop;
+ delete columnDrop.proxyBottom;
+ columnDrop.destroy();
+ delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
+ delete columnDrop._domRef;
+ delete Ext.dd.DDM.ids[columnDrop.ddGroup];
+ }
+
+ if (splitZone) {
+ splitZone.destroy();
+ delete splitZone._domRef;
+ delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
+ }
+
+ Ext.fly(me.innerHd).removeAllListeners();
+ Ext.removeNode(me.innerHd);
+ delete me.innerHd;
+
+ Ext.destroy(
+ me.el,
+ me.mainWrap,
+ me.mainHd,
+ me.scroller,
+ me.mainBody,
+ me.focusEl,
+ me.resizeMarker,
+ me.resizeProxy,
+ me.activeHdBtn,
+ me._flyweight,
+ dragZone,
+ splitZone
+ );
+
+ delete grid.container;
+
+ if (dragZone) {
+ dragZone.destroy();
+ }
+
+ Ext.dd.DDM.currentTarget = null;
+ delete Ext.dd.DDM.locationCache[gridEl.id];
+
+ Ext.EventManager.removeResizeListener(me.onWindowResize, me);
+ },
+
+
+ onDenyColumnHide : function() {
+
+ },
+
+
+ render : function() {
+ if (this.autoFill) {
+ var ct = this.grid.ownerCt;
+
+ if (ct && ct.getLayout()) {
+ ct.on('afterlayout', function() {
+ this.fitColumns(true, true);
+ this.updateHeaders();
+ this.updateHeaderSortState();
+ }, this, {single: true});
+ }
+ } else if (this.forceFit) {
+ this.fitColumns(true, false);
+ } else if (this.grid.autoExpandColumn) {
+ this.autoExpand(true);
+ }
+
+ this.grid.getGridEl().dom.innerHTML = this.renderUI();
+
+ this.afterRenderUI();
+ },
+
+
+
+
+ initData : function(newStore, newColModel) {
+ var me = this;
+
+ if (me.ds) {
+ var oldStore = me.ds;
+
+ oldStore.un('add', me.onAdd, me);
+ oldStore.un('load', me.onLoad, me);
+ oldStore.un('clear', me.onClear, me);
+ oldStore.un('remove', me.onRemove, me);
+ oldStore.un('update', me.onUpdate, me);
+ oldStore.un('datachanged', me.onDataChange, me);
+
+ if (oldStore !== newStore && oldStore.autoDestroy) {
+ oldStore.destroy();
+ }
+ }
+
+ if (newStore) {
+ newStore.on({
+ scope : me,
+ load : me.onLoad,
+ add : me.onAdd,
+ remove : me.onRemove,
+ update : me.onUpdate,
+ clear : me.onClear,
+ datachanged: me.onDataChange
+ });
+ }
+
+ if (me.cm) {
+ var oldColModel = me.cm;
+
+ oldColModel.un('configchange', me.onColConfigChange, me);
+ oldColModel.un('widthchange', me.onColWidthChange, me);
+ oldColModel.un('headerchange', me.onHeaderChange, me);
+ oldColModel.un('hiddenchange', me.onHiddenChange, me);
+ oldColModel.un('columnmoved', me.onColumnMove, me);
+ }
+
+ if (newColModel) {
+ delete me.lastViewWidth;
+
+ newColModel.on({
+ scope : me,
+ configchange: me.onColConfigChange,
+ widthchange : me.onColWidthChange,
+ headerchange: me.onHeaderChange,
+ hiddenchange: me.onHiddenChange,
+ columnmoved : me.onColumnMove
+ });
+ }
+
+ me.ds = newStore;
+ me.cm = newColModel;
+ },
+
+
+ onDataChange : function(){
+ this.refresh(true);
+ this.updateHeaderSortState();
+ this.syncFocusEl(0);
+ },
+
+
+ onClear : function() {
+ this.refresh();
+ this.syncFocusEl(0);
+ },
+
+
+ onUpdate : function(store, record) {
+ this.refreshRow(record);
+ },
+
+
+ onAdd : function(store, records, index) {
+ this.insertRows(store, index, index + (records.length-1));
+ },
+
+
+ onRemove : function(store, record, index, isUpdate) {
+ if (isUpdate !== true) {
+ this.fireEvent('beforerowremoved', this, index, record);
+ }
+
+ this.removeRow(index);
+
+ if (isUpdate !== true) {
+ this.processRows(index);
+ this.applyEmptyText();
+ this.fireEvent('rowremoved', this, index, record);
+ }
+ },
+
+
+ onLoad : function() {
+ if (Ext.isGecko) {
+ if (!this.scrollToTopTask) {
+ this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
+ }
+ this.scrollToTopTask.delay(1);
+ } else {
+ this.scrollToTop();
+ }
+ },
+
+
+ onColWidthChange : function(cm, col, width) {
+ this.updateColumnWidth(col, width);
+ },
+
+
+ onHeaderChange : function(cm, col, text) {
+ this.updateHeaders();
+ },
+
+
+ onHiddenChange : function(cm, col, hidden) {
+ this.updateColumnHidden(col, hidden);
+ },
+
+
+ onColumnMove : function(cm, oldIndex, newIndex) {
+ this.indexMap = null;
+ this.refresh(true);
+ this.restoreScroll(this.getScrollState());
+
+ this.afterMove(newIndex);
+ this.grid.fireEvent('columnmove', oldIndex, newIndex);
+ },
+
+
+ onColConfigChange : function() {
+ delete this.lastViewWidth;
+ this.indexMap = null;
+ this.refresh(true);
+ },
+
+
+
+ initUI : function(grid) {
+ grid.on('headerclick', this.onHeaderClick, this);
+ },
+
+
+ initEvents : Ext.emptyFn,
+
+
+ onHeaderClick : function(g, index) {
+ if (this.headersDisabled || !this.cm.isSortable(index)) {
+ return;
+ }
+ g.stopEditing(true);
+ g.store.sort(this.cm.getDataIndex(index));
+ },
+
+
+ onRowOver : function(e, target) {
+ var row = this.findRowIndex(target);
+
+ if (row !== false) {
+ this.addRowClass(row, this.rowOverCls);
+ }
+ },
+
+
+ onRowOut : function(e, target) {
+ var row = this.findRowIndex(target);
+
+ if (row !== false && !e.within(this.getRow(row), true)) {
+ this.removeRowClass(row, this.rowOverCls);
+ }
+ },
+
+
+ onRowSelect : function(row) {
+ this.addRowClass(row, this.selectedRowClass);
+ },
+
+
+ onRowDeselect : function(row) {
+ this.removeRowClass(row, this.selectedRowClass);
+ },
+
+
+ onCellSelect : function(row, col) {
+ var cell = this.getCell(row, col);
+ if (cell) {
+ this.fly(cell).addClass('x-grid3-cell-selected');
+ }
+ },
+
+
+ onCellDeselect : function(row, col) {
+ var cell = this.getCell(row, col);
+ if (cell) {
+ this.fly(cell).removeClass('x-grid3-cell-selected');
+ }
+ },
+
+
+ handleWheel : function(e) {
+ e.stopPropagation();
+ },
+
+
+ onColumnSplitterMoved : function(cellIndex, width) {
+ this.userResized = true;
+ this.grid.colModel.setColumnWidth(cellIndex, width, true);
+
+ if (this.forceFit) {
+ this.fitColumns(true, false, cellIndex);
+ this.updateAllColumnWidths();
+ } else {
+ this.updateColumnWidth(cellIndex, width);
+ this.syncHeaderScroll();
+ }
+
+ this.grid.fireEvent('columnresize', cellIndex, width);
+ },
+
+
+ beforeColMenuShow : function() {
+ var colModel = this.cm,
+ colCount = colModel.getColumnCount(),
+ colMenu = this.colMenu,
+ i;
+
+ colMenu.removeAll();
+
+ for (i = 0; i < colCount; i++) {
+ if (colModel.config[i].hideable !== false) {
+ colMenu.add(new Ext.menu.CheckItem({
+ text : colModel.getColumnHeader(i),
+ itemId : 'col-' + colModel.getColumnId(i),
+ checked : !colModel.isHidden(i),
+ disabled : colModel.config[i].hideable === false,
+ hideOnClick: false
+ }));
+ }
+ }
+ },
+
+
+ handleHdMenuClick : function(item) {
+ var store = this.ds,
+ dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
+
+ switch (item.getItemId()) {
+ case 'asc':
+ store.sort(dataIndex, 'ASC');
+ break;
+ case 'desc':
+ store.sort(dataIndex, 'DESC');
+ break;
+ default:
+ this.handleHdMenuClickDefault(item);
+ }
+ return true;
+ },
+
+
+ handleHdMenuClickDefault: function(item) {
+ var colModel = this.cm,
+ itemId = item.getItemId(),
+ index = colModel.getIndexById(itemId.substr(4));
+
+ if (index != -1) {
+ if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
+ this.onDenyColumnHide();
+ return;
+ }
+ colModel.setHidden(index, item.checked);
+ }
+ },
+
+
+ handleHdDown : function(e, target) {
+ if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
+ e.stopEvent();
+
+ var colModel = this.cm,
+ header = this.findHeaderCell(target),
+ index = this.getCellIndex(header),
+ sortable = colModel.isSortable(index),
+ menu = this.hmenu,
+ menuItems = menu.items,
+ menuCls = this.headerMenuOpenCls,
+ sep;
+
+ this.hdCtxIndex = index;
+
+ Ext.fly(header).addClass(menuCls);
+ if (this.hideSortIcons) {
+ menuItems.get('asc').setVisible(sortable);
+ menuItems.get('desc').setVisible(sortable);
+ sep = menuItems.get('sortSep');
+ if (sep) {
+ sep.setVisible(sortable);
+ }
+ } else {
+ menuItems.get('asc').setDisabled(!sortable);
+ menuItems.get('desc').setDisabled(!sortable);
+ }
+
+ menu.on('hide', function() {
+ Ext.fly(header).removeClass(menuCls);
+ }, this, {single:true});
+
+ menu.show(target, 'tl-bl?');
+ }
+ },
+
+
+ handleHdMove : function(e) {
+ var header = this.findHeaderCell(this.activeHdRef);
+
+ if (header && !this.headersDisabled) {
+ var handleWidth = this.splitHandleWidth || 5,
+ activeRegion = this.activeHdRegion,
+ headerStyle = header.style,
+ colModel = this.cm,
+ cursor = '',
+ pageX = e.getPageX();
+
+ if (this.grid.enableColumnResize !== false) {
+ var activeHeaderIndex = this.activeHdIndex,
+ previousVisible = this.getPreviousVisible(activeHeaderIndex),
+ currentResizable = colModel.isResizable(activeHeaderIndex),
+ previousResizable = previousVisible && colModel.isResizable(previousVisible),
+ inLeftResizer = pageX - activeRegion.left <= handleWidth,
+ inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
+
+ if (inLeftResizer && previousResizable) {
+ cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
+ } else if (inRightResizer && currentResizable) {
+ cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
+ }
+ }
+
+ headerStyle.cursor = cursor;
+ }
+ },
+
+
+ getPreviousVisible: function(index) {
+ while (index > 0) {
+ if (!this.cm.isHidden(index - 1)) {
+ return index;
+ }
+ index--;
+ }
+ return undefined;
+ },
+
+
+ handleHdOver : function(e, target) {
+ var header = this.findHeaderCell(target);
+
+ if (header && !this.headersDisabled) {
+ var fly = this.fly(header);
+
+ this.activeHdRef = target;
+ this.activeHdIndex = this.getCellIndex(header);
+ this.activeHdRegion = fly.getRegion();
+
+ if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
+ fly.addClass('x-grid3-hd-over');
+ this.activeHdBtn = fly.child('.x-grid3-hd-btn');
+
+ if (this.activeHdBtn) {
+ this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
+ }
+ }
+ }
+ },
+
+
+ handleHdOut : function(e, target) {
+ var header = this.findHeaderCell(target);
+
+ if (header && (!Ext.isIE9m || !e.within(header, true))) {
+ this.activeHdRef = null;
+ this.fly(header).removeClass('x-grid3-hd-over');
+ header.style.cursor = '';
+ }
+ },
+
+
+ isMenuDisabled: function(cellIndex, el) {
+ return this.cm.isMenuDisabled(cellIndex);
+ },
+
+
+ hasRows : function() {
+ var fc = this.mainBody.dom.firstChild;
+ return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
+ },
+
+
+ isHideableColumn : function(c) {
+ return !c.hidden;
+ },
+
+
+ bind : function(d, c) {
+ this.initData(d, c);
+ }
+});
+
+
+
+
+Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
+
+ constructor: function(grid, hd){
+ this.grid = grid;
+ this.view = grid.getView();
+ this.marker = this.view.resizeMarker;
+ this.proxy = this.view.resizeProxy;
+ Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
+ 'gridSplitters' + this.grid.getGridEl().id, {
+ dragElId : Ext.id(this.proxy.dom), resizeFrame:false
+ });
+ this.scroll = false;
+ this.hw = this.view.splitHandleWidth || 5;
+ },
+
+ b4StartDrag : function(x, y){
+ this.dragHeadersDisabled = this.view.headersDisabled;
+ this.view.headersDisabled = true;
+ var h = this.view.mainWrap.getHeight();
+ this.marker.setHeight(h);
+ this.marker.show();
+ this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
+ this.proxy.setHeight(h);
+ var w = this.cm.getColumnWidth(this.cellIndex),
+ minw = Math.max(w-this.grid.minColumnWidth, 0);
+ this.resetConstraints();
+ this.setXConstraint(minw, 1000);
+ this.setYConstraint(0, 0);
+ this.minX = x - minw;
+ this.maxX = x + 1000;
+ this.startPos = x;
+ Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
+ },
+
+ allowHeaderDrag : function(e){
+ return true;
+ },
+
+ handleMouseDown : function(e){
+ var t = this.view.findHeaderCell(e.getTarget());
+ if(t && this.allowHeaderDrag(e)){
+ var xy = this.view.fly(t).getXY(),
+ x = xy[0],
+ exy = e.getXY(),
+ ex = exy[0],
+ w = t.offsetWidth,
+ adjust = false;
+
+ if((ex - x) <= this.hw){
+ adjust = -1;
+ }else if((x+w) - ex <= this.hw){
+ adjust = 0;
+ }
+ if(adjust !== false){
+ this.cm = this.grid.colModel;
+ var ci = this.view.getCellIndex(t);
+ if(adjust == -1){
+ if (ci + adjust < 0) {
+ return;
+ }
+ while(this.cm.isHidden(ci+adjust)){
+ --adjust;
+ if(ci+adjust < 0){
+ return;
+ }
+ }
+ }
+ this.cellIndex = ci+adjust;
+ this.split = t.dom;
+ if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
+ Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
+ }
+ }else if(this.view.columnDrag){
+ this.view.columnDrag.callHandleMouseDown(e);
+ }
+ }
+ },
+
+ endDrag : function(e){
+ this.marker.hide();
+ var v = this.view,
+ endX = Math.max(this.minX, e.getPageX()),
+ diff = endX - this.startPos,
+ disabled = this.dragHeadersDisabled;
+
+ v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
+ setTimeout(function(){
+ v.headersDisabled = disabled;
+ }, 50);
+ },
+
+ autoOffset : function(){
+ this.setDelta(0,0);
+ }
+});
+
+Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
+
+
+ colHeaderCellCls: 'grid-hd-group-cell',
+
+
+ title: '',
+
+
+
+
+ getColumnHeaders: function() {
+ return this.grid.topAxis.buildHeaders();;
+ },
+
+
+ getRowHeaders: function() {
+ return this.grid.leftAxis.buildHeaders();
+ },
+
+
+ renderRows : function(startRow, endRow) {
+ var grid = this.grid,
+ rows = grid.extractData(),
+ rowCount = rows.length,
+ templates = this.templates,
+ renderer = grid.renderer,
+ hasRenderer = typeof renderer == 'function',
+ getCellCls = this.getCellCls,
+ hasGetCellCls = typeof getCellCls == 'function',
+ cellTemplate = templates.cell,
+ rowTemplate = templates.row,
+ rowBuffer = [],
+ meta = {},
+ tstyle = 'width:' + this.getGridInnerWidth() + 'px;',
+ colBuffer, colCount, column, i, row;
+
+ startRow = startRow || 0;
+ endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
+
+ for (i = 0; i < rowCount; i++) {
+ row = rows[i];
+ colCount = row.length;
+ colBuffer = [];
+
+
+ for (var j = 0; j < colCount; j++) {
+
+ meta.id = i + '-' + j;
+ meta.css = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
+ meta.attr = meta.cellAttr = '';
+ meta.value = row[j];
+
+ if (Ext.isEmpty(meta.value)) {
+ meta.value = '&#160;';
+ }
+
+ if (hasRenderer) {
+ meta.value = renderer(meta.value);
+ }
+
+ if (hasGetCellCls) {
+ meta.css += getCellCls(meta.value) + ' ';
+ }
+
+ colBuffer[colBuffer.length] = cellTemplate.apply(meta);
+ }
+
+ rowBuffer[rowBuffer.length] = rowTemplate.apply({
+ tstyle: tstyle,
+ cols : colCount,
+ cells : colBuffer.join(""),
+ alt : ''
+ });
+ }
+
+ return rowBuffer.join("");
+ },
+
+
+ masterTpl: new Ext.Template(
+ '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
+ '<div class="x-grid3-viewport">',
+ '<div class="x-grid3-header">',
+ '<div class="x-grid3-header-title"><span>{title}</span></div>',
+ '<div class="x-grid3-header-inner">',
+ '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
+ '</div>',
+ '<div class="x-clear"></div>',
+ '</div>',
+ '<div class="x-grid3-scroller">',
+ '<div class="x-grid3-row-headers"></div>',
+ '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
+ '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
+ '</div>',
+ '</div>',
+ '<div class="x-grid3-resize-marker">&#160;</div>',
+ '<div class="x-grid3-resize-proxy">&#160;</div>',
+ '</div>'
+ ),
+
+
+ initTemplates: function() {
+ Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
+
+ var templates = this.templates || {};
+ if (!templates.gcell) {
+ templates.gcell = new Ext.XTemplate(
+ '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
+ '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id} x-unselectable" unselectable="on" style="{istyle}">',
+ this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
+ '</div>',
+ '</td>'
+ );
+ }
+
+ this.templates = templates;
+ this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
+ },
+
+
+ initElements: function() {
+ Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
+
+
+ this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
+
+
+ this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
+ },
+
+
+ getGridInnerWidth: function() {
+ var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
+
+ return previousWidth - this.getTotalRowHeaderWidth();
+ },
+
+
+ getTotalRowHeaderWidth: function() {
+ var headers = this.getRowHeaders(),
+ length = headers.length,
+ total = 0,
+ i;
+
+ for (i = 0; i< length; i++) {
+ total += headers[i].width;
+ }
+
+ return total;
+ },
+
+
+ getTotalColumnHeaderHeight: function() {
+ return this.getColumnHeaders().length * 21;
+ },
+
+
+ getCellIndex : function(el) {
+ if (el) {
+ var match = el.className.match(this.colRe),
+ data;
+
+ if (match && (data = match[1])) {
+ return parseInt(data.split('-')[1], 10);
+ }
+ }
+ return false;
+ },
+
+
+
+ renderUI : function() {
+ var templates = this.templates,
+ innerWidth = this.getGridInnerWidth();
+
+ return templates.master.apply({
+ body : templates.body.apply({rows:'&#160;'}),
+ ostyle: 'width:' + innerWidth + 'px',
+ bstyle: 'width:' + innerWidth + 'px'
+ });
+ },
+
+
+ onLayout: function(width, height) {
+ Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
+
+ var width = this.getGridInnerWidth();
+
+ this.resizeColumnHeaders(width);
+ this.resizeAllRows(width);
+ },
+
+
+ refresh : function(headersToo) {
+ this.fireEvent('beforerefresh', this);
+ this.grid.stopEditing(true);
+
+ var result = this.renderBody();
+ this.mainBody.update(result).setWidth(this.getGridInnerWidth());
+ if (headersToo === true) {
+ this.updateHeaders();
+ this.updateHeaderSortState();
+ }
+ this.processRows(0, true);
+ this.layout();
+ this.applyEmptyText();
+ this.fireEvent('refresh', this);
+ },
+
+
+ renderHeaders: Ext.emptyFn,
+
+
+ fitColumns: Ext.emptyFn,
+
+
+ resizeColumnHeaders: function(width) {
+ var topAxis = this.grid.topAxis;
+
+ if (topAxis.rendered) {
+ topAxis.el.setWidth(width);
+ }
+ },
+
+
+ resizeRowHeaders: function() {
+ var rowHeaderWidth = this.getTotalRowHeaderWidth(),
+ marginStyle = String.format("margin-left: {0}px;", rowHeaderWidth);
+
+ this.rowHeadersEl.setWidth(rowHeaderWidth);
+ this.mainBody.applyStyles(marginStyle);
+ Ext.fly(this.innerHd).applyStyles(marginStyle);
+
+ this.headerTitleEl.setWidth(rowHeaderWidth);
+ this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
+ },
+
+
+ resizeAllRows: function(width) {
+ var rows = this.getRows(),
+ length = rows.length,
+ i;
+
+ for (i = 0; i < length; i++) {
+ Ext.fly(rows[i]).setWidth(width);
+ Ext.fly(rows[i]).child('table').setWidth(width);
+ }
+ },
+
+
+ updateHeaders: function() {
+ this.renderGroupRowHeaders();
+ this.renderGroupColumnHeaders();
+ },
+
+
+ renderGroupRowHeaders: function() {
+ var leftAxis = this.grid.leftAxis;
+
+ this.resizeRowHeaders();
+ leftAxis.rendered = false;
+ leftAxis.render(this.rowHeadersEl);
+
+ this.setTitle(this.title);
+ },
+
+
+ setTitle: function(title) {
+ this.headerTitleEl.child('span').dom.innerHTML = title;
+ },
+
+
+ renderGroupColumnHeaders: function() {
+ var topAxis = this.grid.topAxis;
+
+ topAxis.rendered = false;
+ topAxis.render(this.innerHd.firstChild);
+ },
+
+
+ isMenuDisabled: function(cellIndex, el) {
+ return true;
+ }
+});
+Ext.grid.PivotAxis = Ext.extend(Ext.Component, {
+
+ orientation: 'horizontal',
+
+
+ defaultHeaderWidth: 80,
+
+
+ paddingWidth: 7,
+
+
+ setDimensions: function(dimensions) {
+ this.dimensions = dimensions;
+ },
+
+
+ onRender: function(ct, position) {
+ var rows = this.orientation == 'horizontal'
+ ? this.renderHorizontalRows()
+ : this.renderVerticalRows();
+
+ this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true);
+ },
+
+
+ renderHorizontalRows: function() {
+ var headers = this.buildHeaders(),
+ rowCount = headers.length,
+ rows = [],
+ cells, cols, colCount, i, j;
+
+ for (i = 0; i < rowCount; i++) {
+ cells = [];
+ cols = headers[i].items;
+ colCount = cols.length;
+
+ for (j = 0; j < colCount; j++) {
+ cells.push({
+ tag: 'td',
+ html: cols[j].header,
+ colspan: cols[j].span
+ });
+ }
+
+ rows[i] = {
+ tag: 'tr',
+ cn: cells
+ };
+ }
+
+ return rows;
+ },
+
+
+ renderVerticalRows: function() {
+ var headers = this.buildHeaders(),
+ colCount = headers.length,
+ rowCells = [],
+ rows = [],
+ rowCount, col, row, colWidth, i, j;
+
+ for (i = 0; i < colCount; i++) {
+ col = headers[i];
+ colWidth = col.width || 80;
+ rowCount = col.items.length;
+
+ for (j = 0; j < rowCount; j++) {
+ row = col.items[j];
+
+ rowCells[row.start] = rowCells[row.start] || [];
+ rowCells[row.start].push({
+ tag : 'td',
+ html : row.header,
+ rowspan: row.span,
+ width : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
+ });
+ }
+ }
+
+ rowCount = rowCells.length;
+ for (i = 0; i < rowCount; i++) {
+ rows[i] = {
+ tag: 'tr',
+ cn : rowCells[i]
+ };
+ }
+
+ return rows;
+ },
+
+
+ getTuples: function() {
+ var newStore = new Ext.data.Store({});
+
+ newStore.data = this.store.data.clone();
+ newStore.fields = this.store.fields;
+
+ var sorters = [],
+ dimensions = this.dimensions,
+ length = dimensions.length,
+ i;
+
+ for (i = 0; i < length; i++) {
+ sorters.push({
+ field : dimensions[i].dataIndex,
+ direction: dimensions[i].direction || 'ASC'
+ });
+ }
+
+ newStore.sort(sorters);
+
+ var records = newStore.data.items,
+ hashes = [],
+ tuples = [],
+ recData, hash, info, data, key;
+
+ length = records.length;
+
+ for (i = 0; i < length; i++) {
+ info = this.getRecordInfo(records[i]);
+ data = info.data;
+ hash = "";
+
+ for (key in data) {
+ hash += data[key] + '---';
+ }
+
+ if (hashes.indexOf(hash) == -1) {
+ hashes.push(hash);
+ tuples.push(info);
+ }
+ }
+
+ newStore.destroy();
+
+ return tuples;
+ },
+
+
+ getRecordInfo: function(record) {
+ var dimensions = this.dimensions,
+ length = dimensions.length,
+ data = {},
+ dimension, dataIndex, i;
+
+
+ for (i = 0; i < length; i++) {
+ dimension = dimensions[i];
+ dataIndex = dimension.dataIndex;
+
+ data[dataIndex] = record.get(dataIndex);
+ }
+
+
+
+ var createMatcherFunction = function(data) {
+ return function(record) {
+ for (var dataIndex in data) {
+ if (record.get(dataIndex) != data[dataIndex]) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+ };
+
+ return {
+ data: data,
+ matcher: createMatcherFunction(data)
+ };
+ },
+
+
+ buildHeaders: function() {
+ var tuples = this.getTuples(),
+ rowCount = tuples.length,
+ dimensions = this.dimensions,
+ dimension,
+ colCount = dimensions.length,
+ headers = [],
+ tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
+
+ for (i = 0; i < colCount; i++) {
+ dimension = dimensions[i];
+ rows = [];
+ span = 0;
+ start = 0;
+
+ for (j = 0; j < rowCount; j++) {
+ tuple = tuples[j];
+ isLast = j == (rowCount - 1);
+ currentHeader = tuple.data[dimension.dataIndex];
+
+
+ changed = previousHeader != undefined && previousHeader != currentHeader;
+ if (i > 0 && j > 0) {
+ changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
+ }
+
+ if (changed) {
+ rows.push({
+ header: previousHeader,
+ span : span,
+ start : start
+ });
+
+ start += span;
+ span = 0;
+ }
+
+ if (isLast) {
+ rows.push({
+ header: currentHeader,
+ span : span + 1,
+ start : start
+ });
+
+ start += span;
+ span = 0;
+ }
+
+ previousHeader = currentHeader;
+ span++;
+ }
+
+ headers.push({
+ items: rows,
+ width: dimension.width || this.defaultHeaderWidth
+ });
+
+ previousHeader = undefined;
+ }
+
+ return headers;
+ }
+});
+
+
+Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
+ maxDragWidth: 120,
+
+ constructor : function(grid, hd, hd2){
+ this.grid = grid;
+ this.view = grid.getView();
+ this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
+ Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
+ if(hd2){
+ this.setHandleElId(Ext.id(hd));
+ this.setOuterHandleElId(Ext.id(hd2));
+ }
+ this.scroll = false;
+ },
+
+ getDragData : function(e){
+ var t = Ext.lib.Event.getTarget(e),
+ h = this.view.findHeaderCell(t);
+ if(h){
+ return {ddel: h.firstChild, header:h};
+ }
+ return false;
+ },
+
+ onInitDrag : function(e){
+
+ this.dragHeadersDisabled = this.view.headersDisabled;
+ this.view.headersDisabled = true;
+ var clone = this.dragData.ddel.cloneNode(true);
+ clone.id = Ext.id();
+ clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
+ this.proxy.update(clone);
+ return true;
+ },
+
+ afterValidDrop : function(){
+ this.completeDrop();
+ },
+
+ afterInvalidDrop : function(){
+ this.completeDrop();
+ },
+
+ completeDrop: function(){
+ var v = this.view,
+ disabled = this.dragHeadersDisabled;
+ setTimeout(function(){
+ v.headersDisabled = disabled;
+ }, 50);
+ }
+});
+
+
+
+Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
+ proxyOffsets : [-4, -9],
+ fly: Ext.Element.fly,
+
+ constructor : function(grid, hd, hd2){
+ this.grid = grid;
+ this.view = grid.getView();
+
+ this.proxyTop = Ext.DomHelper.append(document.body, {
+ cls:"col-move-top", html:"&#160;"
+ }, true);
+ this.proxyBottom = Ext.DomHelper.append(document.body, {
+ 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.getGridEl().id;
+
+
+ Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
+ },
+
+ getTargetFromEvent : function(e){
+ var t = Ext.lib.Event.getTarget(e),
+ cindex = this.view.findCellIndex(t);
+ if(cindex !== false){
+ return this.view.getHeaderCell(cindex);
+ }
+ },
+
+ 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),
+ r = Ext.lib.Dom.getRegion(n.firstChild),
+ 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";
+ }
+
+ if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
+ 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, data){
+ if(data.header != n){
+ this.positionIndicator(data.header, n, e);
+ }
+ },
+
+ onNodeOver : function(n, dd, e, data){
+ var result = false;
+ if(data.header != n){
+ result = this.positionIndicator(data.header, n, e);
+ }
+ if(!result){
+ this.proxyTop.hide();
+ this.proxyBottom.hide();
+ }
+ return result ? this.dropAllowed : this.dropNotAllowed;
+ },
+
+ onNodeOut : function(n, dd, e, data){
+ this.proxyTop.hide();
+ this.proxyBottom.hide();
+ },
+
+ onNodeDrop : function(n, dd, e, data){
+ var h = data.header;
+ if(h != n){
+ var cm = this.grid.colModel,
+ x = Ext.lib.Event.getPageX(e),
+ r = Ext.lib.Dom.getRegion(n.firstChild),
+ pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
+ oldIndex = this.view.getCellIndex(h),
+ newIndex = this.view.getCellIndex(n);
+ if(pt == "after"){
+ newIndex++;
+ }
+ if(oldIndex < newIndex){
+ newIndex--;
+ }
+ cm.moveColumn(oldIndex, newIndex);
+ return true;
+ }
+ return false;
+ }
+});
+
+Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
+
+ constructor : function(grid, hd){
+ Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
+ this.proxy.el.addClass('x-grid3-col-dd');
+ },
+
+ handleMouseDown : function(e){
+ },
+
+ callHandleMouseDown : function(e){
+ Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
+ }
+});
+
+Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
+ fly: Ext.Element.fly,
+
+ constructor : function(grid, hd, hd2){
+ this.grid = grid;
+ this.view = grid.getView();
+ this.proxy = this.view.resizeProxy;
+ Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
+ "gridSplitters" + this.grid.getGridEl().id, {
+ dragElId : Ext.id(this.proxy.dom), resizeFrame:false
+ });
+ this.setHandleElId(Ext.id(hd));
+ this.setOuterHandleElId(Ext.id(hd2));
+ this.scroll = false;
+ },
+
+ b4StartDrag : function(x, y){
+ this.view.headersDisabled = true;
+ this.proxy.setHeight(this.view.mainWrap.getHeight());
+ var w = this.cm.getColumnWidth(this.cellIndex);
+ var minw = Math.max(w-this.grid.minColumnWidth, 0);
+ this.resetConstraints();
+ this.setXConstraint(minw, 1000);
+ this.setYConstraint(0, 0);
+ this.minX = x - minw;
+ this.maxX = x + 1000;
+ this.startPos = x;
+ Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
+ },
+
+
+ handleMouseDown : function(e){
+ var 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 endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
+ var diff = endX - this.startPos;
+ this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
+ },
+
+ autoOffset : function(){
+ this.setDelta(0,0);
+ }
+});
+Ext.grid.GridDragZone = function(grid, config){
+ this.view = grid.getView();
+ Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
+ this.scroll = false;
+ this.grid = grid;
+ this.ddel = document.createElement('div');
+ this.ddel.className = 'x-grid-dd-wrap';
+
+ this.preventDefault = true;
+};
+
+Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
+ ddGroup : "GridDD",
+
+
+ getDragData : function(e){
+ var t = Ext.lib.Event.getTarget(e),
+ sm,
+ rowIndex = this.view.findRowIndex(t),
+ cellIndex,
+ selectedCell,
+ selection;
+
+ if (rowIndex !== false){
+ sm = this.grid.selModel;
+
+
+
+ if (sm.getSelectedCell) {
+ cellIndex = this.view.findCellIndex(t);
+ selectedCell = sm.getSelectedCell();
+ if (!selectedCell || selectedCell[0] !== rowIndex || selectedCell[1] !== cellIndex) {
+ sm.handleMouseDown(this.grid, rowIndex, cellIndex, e);
+ }
+ if (this.grid.dragCell) {
+
+ selection = sm.getSelectedCell();
+ if (!this.grid.hasOwnProperty('ddText')) {
+ this.grid.ddText = '{0} selected cell{1}';
+ }
+ } else {
+
+ selection = [this.grid.store.getAt(rowIndex)];
+ }
+ } else {
+ if(!sm.isSelected(rowIndex) || e.hasModifier()){
+ sm.handleMouseDown(this.grid, rowIndex, e);
+ }
+ selection = sm.getSelections();
+ }
+ return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections: selection};
+ }
+ return false;
+ },
+
+
+ onInitDrag : function(e){
+ var data = this.dragData;
+ this.ddel.innerHTML = this.grid.getDragDropText();
+ this.proxy.update(this.ddel);
+
+ },
+
+
+ afterRepair : function(){
+ this.dragging = false;
+ },
+
+
+ getRepairXY : function(e, data){
+ return false;
+ },
+
+ onEndDrag : function(data, e){
+
+ },
+
+ onValidDrop : function(dd, e, id){
+
+ this.hideProxy();
+ },
+
+ beforeInvalidDrop : function(e, id){
+
+ }
+});
+
+Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
+
+ defaultWidth: 100,
+
+
+ defaultSortable: false,
+
+
+
+
+
+ constructor : function(config) {
+
+ if (config.columns) {
+ Ext.apply(this, config);
+ this.setConfig(config.columns, true);
+ } else {
+ this.setConfig(config, true);
+ }
+
+ this.addEvents(
+
+ "widthchange",
+
+
+ "headerchange",
+
+
+ "hiddenchange",
+
+
+ "columnmoved",
+
+
+ "configchange"
+ );
+
+ Ext.grid.ColumnModel.superclass.constructor.call(this);
+ },
+
+
+ getColumnId : function(index) {
+ return this.config[index].id;
+ },
+
+ getColumnAt : function(index) {
+ return this.config[index];
+ },
+
+
+ setConfig : function(config, initial) {
+ var i, c, len;
+
+ if (!initial) {
+ delete this.totalWidth;
+
+ for (i = 0, len = this.config.length; i < len; i++) {
+ c = this.config[i];
+
+ if (c.setEditor) {
+
+ c.setEditor(null);
+ }
+ }
+ }
+
+
+ this.defaults = Ext.apply({
+ width: this.defaultWidth,
+ sortable: this.defaultSortable
+ }, this.defaults);
+
+ this.config = config;
+ this.lookup = {};
+
+ for (i = 0, len = config.length; i < len; i++) {
+ c = Ext.applyIf(config[i], this.defaults);
+
+
+ if (Ext.isEmpty(c.id)) {
+ c.id = i;
+ }
+
+ if (!c.isColumn) {
+ var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
+ c = new Cls(c);
+ config[i] = c;
+ }
+
+ this.lookup[c.id] = c;
+ }
+
+ if (!initial) {
+ this.fireEvent('configchange', this);
+ }
+ },
+
+
+ getColumnById : function(id) {
+ return this.lookup[id];
+ },
+
+
+ getIndexById : function(id) {
+ for (var i = 0, len = this.config.length; i < len; i++) {
+ if (this.config[i].id == id) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+
+ moveColumn : function(oldIndex, newIndex) {
+ var config = this.config,
+ c = config[oldIndex];
+
+ config.splice(oldIndex, 1);
+ config.splice(newIndex, 0, c);
+ this.dataMap = null;
+ this.fireEvent("columnmoved", this, oldIndex, newIndex);
+ },
+
+
+ getColumnCount : function(visibleOnly) {
+ var length = this.config.length,
+ c = 0,
+ i;
+
+ if (visibleOnly === true) {
+ for (i = 0; i < length; i++) {
+ if (!this.isHidden(i)) {
+ c++;
+ }
+ }
+
+ return c;
+ }
+
+ return length;
+ },
+
+
+ getColumnsBy : function(fn, scope) {
+ var config = this.config,
+ length = config.length,
+ result = [],
+ i, c;
+
+ for (i = 0; i < length; i++){
+ c = config[i];
+
+ if (fn.call(scope || this, c, i) === true) {
+ result[result.length] = c;
+ }
+ }
+
+ return result;
+ },
+
+
+ isSortable : function(col) {
+ return !!this.config[col].sortable;
+ },
+
+
+ isMenuDisabled : function(col) {
+ return !!this.config[col].menuDisabled;
+ },
+
+
+ getRenderer : function(col) {
+ return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
+ },
+
+ getRendererScope : function(col) {
+ return this.config[col].scope;
+ },
+
+
+ setRenderer : function(col, fn) {
+ this.config[col].renderer = fn;
+ },
+
+
+ getColumnWidth : function(col) {
+ var width = this.config[col].width;
+ if(typeof width != 'number'){
+ width = this.defaultWidth;
+ }
+ return width;
+ },
+
+
+ setColumnWidth : function(col, width, suppressEvent) {
+ this.config[col].width = width;
+ this.totalWidth = null;
+
+ if (!suppressEvent) {
+ this.fireEvent("widthchange", this, col, width);
+ }
+ },
+
+
+ getTotalWidth : function(includeHidden) {
+ if (!this.totalWidth) {
+ this.totalWidth = 0;
+ for (var i = 0, len = this.config.length; i < len; i++) {
+ if (includeHidden || !this.isHidden(i)) {
+ this.totalWidth += this.getColumnWidth(i);
+ }
+ }
+ }
+ return this.totalWidth;
+ },
+
+
+ getColumnHeader : function(col) {
+ return this.config[col].header;
+ },
+
+
+ setColumnHeader : function(col, header) {
+ this.config[col].header = header;
+ this.fireEvent("headerchange", this, col, header);
+ },
+
+
+ getColumnTooltip : function(col) {
+ return this.config[col].tooltip;
+ },
+
+ setColumnTooltip : function(col, tooltip) {
+ this.config[col].tooltip = tooltip;
+ },
+
+
+ getDataIndex : function(col) {
+ return this.config[col].dataIndex;
+ },
+
+
+ setDataIndex : function(col, dataIndex) {
+ this.config[col].dataIndex = dataIndex;
+ },
+
+
+ findColumnIndex : function(dataIndex) {
+ var c = this.config;
+ for(var i = 0, len = c.length; i < len; i++){
+ if(c[i].dataIndex == dataIndex){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+
+ isCellEditable : function(colIndex, rowIndex) {
+ var c = this.config[colIndex],
+ ed = c.editable;
+
+
+ return !!(ed || (!Ext.isDefined(ed) && c.editor));
+ },
+
+
+ getCellEditor : function(colIndex, rowIndex) {
+ return this.config[colIndex].getCellEditor(rowIndex);
+ },
+
+
+ setEditable : function(col, editable) {
+ this.config[col].editable = editable;
+ },
+
+
+ isHidden : function(colIndex) {
+ return !!this.config[colIndex].hidden;
+ },
+
+
+ isFixed : function(colIndex) {
+ return !!this.config[colIndex].fixed;
+ },
+
+
+ isResizable : function(colIndex) {
+ return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
+ },
+
+
+ setHidden : function(colIndex, hidden) {
+ var c = this.config[colIndex];
+ if(c.hidden !== hidden){
+ c.hidden = hidden;
+ this.totalWidth = null;
+ this.fireEvent("hiddenchange", this, colIndex, hidden);
+ }
+ },
+
+
+ setEditor : function(col, editor) {
+ this.config[col].setEditor(editor);
+ },
+
+
+ destroy : function() {
+ var length = this.config.length,
+ i = 0;
+
+ for (; i < length; i++){
+ this.config[i].destroy();
+ }
+ delete this.config;
+ delete this.lookup;
+ this.purgeListeners();
+ },
+
+
+ setState : function(col, state) {
+ state = Ext.applyIf(state, this.defaults);
+ Ext.apply(this.config[col], state);
+ }
+});
+
+
+Ext.grid.ColumnModel.defaultRenderer = function(value) {
+ if (typeof value == "string" && value.length < 1) {
+ return "&#160;";
+ }
+ return value;
+};
+Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, {
+
+
+ constructor : function(){
+ this.locked = false;
+ Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
+ },
+
+
+ init : function(grid){
+ this.grid = grid;
+ if(this.lockOnInit){
+ delete this.lockOnInit;
+ this.locked = false;
+ this.lock();
+ }
+ this.initEvents();
+ },
+
+
+ lock : function(){
+ if(!this.locked){
+ this.locked = true;
+
+ var g = this.grid;
+ if(g){
+ g.getView().on({
+ scope: this,
+ beforerefresh: this.sortUnLock,
+ refresh: this.sortLock
+ });
+ }else{
+ this.lockOnInit = true;
+ }
+ }
+ },
+
+
+ sortLock : function() {
+ this.locked = true;
+ },
+
+
+ sortUnLock : function() {
+ this.locked = false;
+ },
+
+
+ unlock : function(){
+ if(this.locked){
+ this.locked = false;
+ var g = this.grid,
+ gv;
+
+
+ if(g){
+ gv = g.getView();
+ gv.un('beforerefresh', this.sortUnLock, this);
+ gv.un('refresh', this.sortLock, this);
+ }else{
+ delete this.lockOnInit;
+ }
+ }
+ },
+
+
+ isLocked : function(){
+ return this.locked;
+ },
+
+ destroy: function(){
+ this.unlock();
+ this.purgeListeners();
+ }
+});
+Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
+
+ singleSelect : false,
+
+ constructor : function(config){
+ Ext.apply(this, config);
+ this.selections = new Ext.util.MixedCollection(false, function(o){
+ return o.id;
+ });
+
+ this.last = false;
+ this.lastActive = false;
+
+ this.addEvents(
+
+ 'selectionchange',
+
+ 'beforerowselect',
+
+ 'rowselect',
+
+ 'rowdeselect'
+ );
+ Ext.grid.RowSelectionModel.superclass.constructor.call(this);
+ },
+
+
+
+ initEvents : function(){
+
+ if(!this.grid.enableDragDrop && !this.grid.enableDrag){
+ this.grid.on('rowmousedown', this.handleMouseDown, this);
+ }
+
+ this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
+ up: this.onKeyPress,
+ down: this.onKeyPress,
+ scope: this
+ });
+
+ this.grid.getView().on({
+ scope: this,
+ refresh: this.onRefresh,
+ rowupdated: this.onRowUpdated,
+ rowremoved: this.onRemove
+ });
+ },
+
+ onKeyPress : function(e, name){
+ var up = name == 'up',
+ method = up ? 'selectPrevious' : 'selectNext',
+ add = up ? -1 : 1,
+ last;
+ if(!e.shiftKey || this.singleSelect){
+ this[method](false);
+ }else if(this.last !== false && this.lastActive !== false){
+ last = this.last;
+ this.selectRange(this.last, this.lastActive + add);
+ this.grid.getView().focusRow(this.lastActive);
+ if(last !== false){
+ this.last = last;
+ }
+ }else{
+ this.selectFirstRow();
+ }
+ },
+
+
+ onRefresh : function(){
+ var ds = this.grid.store,
+ s = this.getSelections(),
+ i = 0,
+ len = s.length,
+ index, r;
+
+ this.silent = true;
+ this.clearSelections(true);
+ for(; i < len; i++){
+ r = s[i];
+ if((index = ds.indexOfId(r.id)) != -1){
+ this.selectRow(index, true);
+ }
+ }
+ if(s.length != this.selections.getCount()){
+ this.fireEvent('selectionchange', this);
+ }
+ this.silent = false;
+ },
+
+
+ onRemove : function(v, index, r){
+ if(this.selections.remove(r) !== false){
+ this.fireEvent('selectionchange', this);
+ }
+ },
+
+
+ onRowUpdated : function(v, index, r){
+ if(this.isSelected(r)){
+ v.onRowSelect(index);
+ }
+ },
+
+
+ selectRecords : function(records, keepExisting){
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ var ds = this.grid.store,
+ i = 0,
+ len = records.length;
+ for(; i < len; i++){
+ this.selectRow(ds.indexOf(records[i]), true);
+ }
+ },
+
+
+ getCount : function(){
+ return this.selections.length;
+ },
+
+
+ selectFirstRow : function(){
+ this.selectRow(0);
+ },
+
+
+ selectLastRow : function(keepExisting){
+ this.selectRow(this.grid.store.getCount() - 1, keepExisting);
+ },
+
+
+ selectNext : function(keepExisting){
+ if(this.hasNext()){
+ this.selectRow(this.last+1, keepExisting);
+ this.grid.getView().focusRow(this.last);
+ return true;
+ }
+ return false;
+ },
+
+
+ selectPrevious : function(keepExisting){
+ if(this.hasPrevious()){
+ this.selectRow(this.last-1, keepExisting);
+ this.grid.getView().focusRow(this.last);
+ return true;
+ }
+ return false;
+ },
+
+
+ hasNext : function(){
+ return this.last !== false && (this.last+1) < this.grid.store.getCount();
+ },
+
+
+ hasPrevious : function(){
+ return !!this.last;
+ },
+
+
+
+ getSelections : function(){
+ return [].concat(this.selections.items);
+ },
+
+
+ getSelected : function(){
+ return this.selections.itemAt(0);
+ },
+
+
+ each : function(fn, scope){
+ var s = this.getSelections(),
+ i = 0,
+ len = s.length;
+
+ for(; i < len; i++){
+ if(fn.call(scope || this, s[i], i) === false){
+ return false;
+ }
+ }
+ return true;
+ },
+
+
+ clearSelections : function(fast){
+ if(this.isLocked()){
+ return;
+ }
+ if(fast !== true){
+ var ds = this.grid.store,
+ 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.isLocked()){
+ return;
+ }
+ this.selections.clear();
+ for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
+ this.selectRow(i, true);
+ }
+ },
+
+
+ hasSelection : function(){
+ return this.selections.length > 0;
+ },
+
+
+ isSelected : function(index){
+ var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
+ return (r && this.selections.key(r.id) ? true : false);
+ },
+
+
+ isIdSelected : function(id){
+ return (this.selections.key(id) ? true : false);
+ },
+
+
+ handleMouseDown : function(g, rowIndex, e){
+ if(e.button !== 0 || this.isLocked()){
+ return;
+ }
+ var view = this.grid.getView();
+ if(e.shiftKey && !this.singleSelect && this.last !== false){
+ var last = this.last;
+ this.selectRange(last, rowIndex, e.ctrlKey);
+ this.last = last;
+ view.focusRow(rowIndex);
+ }else{
+ var isSelected = this.isSelected(rowIndex);
+ if(e.ctrlKey && isSelected){
+ this.deselectRow(rowIndex);
+ }else if(!isSelected || this.getCount() > 1){
+ this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
+ view.focusRow(rowIndex);
+ }
+ }
+ },
+
+
+ selectRows : function(rows, keepExisting){
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ for(var i = 0, len = rows.length; i < len; i++){
+ this.selectRow(rows[i], true);
+ }
+ },
+
+
+ selectRange : function(startRow, endRow, keepExisting){
+ var i;
+ if(this.isLocked()){
+ return;
+ }
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ if(startRow <= endRow){
+ for(i = startRow; i <= endRow; i++){
+ this.selectRow(i, true);
+ }
+ }else{
+ for(i = startRow; i >= endRow; i--){
+ this.selectRow(i, true);
+ }
+ }
+ },
+
+
+ deselectRange : function(startRow, endRow, preventViewNotify){
+ if(this.isLocked()){
+ return;
+ }
+ for(var i = startRow; i <= endRow; i++){
+ this.deselectRow(i, preventViewNotify);
+ }
+ },
+
+
+ selectRow : function(index, keepExisting, preventViewNotify){
+ if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
+ return;
+ }
+ var r = this.grid.store.getAt(index);
+ if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
+ if(!keepExisting || this.singleSelect){
+ this.clearSelections();
+ }
+ this.selections.add(r);
+ this.last = this.lastActive = index;
+ if(!preventViewNotify){
+ this.grid.getView().onRowSelect(index);
+ }
+ if(!this.silent){
+ this.fireEvent('rowselect', this, index, r);
+ this.fireEvent('selectionchange', this);
+ }
+ }
+ },
+
+
+ deselectRow : function(index, preventViewNotify){
+ if(this.isLocked()){
+ return;
+ }
+ if(this.last == index){
+ this.last = false;
+ }
+ if(this.lastActive == index){
+ this.lastActive = false;
+ }
+ var r = this.grid.store.getAt(index);
+ if(r){
+ this.selections.remove(r);
+ if(!preventViewNotify){
+ this.grid.getView().onRowDeselect(index);
+ }
+ this.fireEvent('rowdeselect', this, index, r);
+ this.fireEvent('selectionchange', this);
+ }
+ },
+
+
+ acceptsNav : function(row, col, cm){
+ return !cm.isHidden(col) && cm.isCellEditable(col, row);
+ },
+
+
+ onEditorKey : function(field, e){
+ var k = e.getKey(),
+ newCell,
+ g = this.grid,
+ last = g.lastEdit,
+ ed = g.activeEditor,
+ shift = e.shiftKey,
+ ae, last, r, c;
+
+ if(k == e.TAB){
+ e.stopEvent();
+ ed.completeEdit();
+ if(shift){
+ newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
+ }else{
+ newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
+ }
+ }else if(k == e.ENTER){
+ if(this.moveEditorOnEnter !== false){
+ if(shift){
+ newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
+ }else{
+ newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
+ }
+ }
+ }
+ if(newCell){
+ r = newCell[0];
+ c = newCell[1];
+
+ this.onEditorSelect(r, last.row);
+
+ if(g.isEditor && g.editing){
+ ae = g.activeEditor;
+ if(ae && ae.field.triggerBlur){
+
+ ae.field.triggerBlur();
+ }
+ }
+ g.startEditing(r, c);
+ }
+ },
+
+ onEditorSelect: function(row, lastRow){
+ if(lastRow != row){
+ this.selectRow(row);
+ }
+ },
+
+ destroy : function(){
+ Ext.destroy(this.rowNav);
+ this.rowNav = null;
+ Ext.grid.RowSelectionModel.superclass.destroy.call(this);
+ }
+});
+
+Ext.grid.Column = Ext.extend(Ext.util.Observable, {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ isColumn : true,
+
+ constructor : function(config){
+ Ext.apply(this, config);
+
+ if(Ext.isString(this.renderer)){
+ this.renderer = Ext.util.Format[this.renderer];
+ }else if(Ext.isObject(this.renderer)){
+ this.scope = this.renderer.scope;
+ this.renderer = this.renderer.fn;
+ }
+ if(!this.scope){
+ this.scope = this;
+ }
+
+ var ed = this.editor;
+ delete this.editor;
+ this.setEditor(ed);
+ this.addEvents(
+
+ 'click',
+
+ 'contextmenu',
+
+ 'dblclick',
+
+ 'mousedown'
+ );
+ Ext.grid.Column.superclass.constructor.call(this);
+ },
+
+
+ processEvent : function(name, e, grid, rowIndex, colIndex){
+ return this.fireEvent(name, this, grid, rowIndex, e);
+ },
+
+
+ destroy: function() {
+ if(this.setEditor){
+ this.setEditor(null);
+ }
+ this.purgeListeners();
+ },
+
+
+ renderer : function(value){
+ return value;
+ },
+
+
+ getEditor: function(rowIndex){
+ return this.editable !== false ? this.editor : null;
+ },
+
+
+ setEditor : function(editor){
+ var ed = this.editor;
+ if(ed){
+ if(ed.gridEditor){
+ ed.gridEditor.destroy();
+ delete ed.gridEditor;
+ }else{
+ ed.destroy();
+ }
+ }
+ this.editor = null;
+ if(editor){
+
+ if(!editor.isXType){
+ editor = Ext.create(editor, 'textfield');
+ }
+ this.editor = editor;
+ }
+ },
+
+
+ getCellEditor: function(rowIndex){
+ var ed = this.getEditor(rowIndex);
+ if(ed){
+ if(!ed.startEdit){
+ if(!ed.gridEditor){
+ ed.gridEditor = new Ext.grid.GridEditor(ed);
+ }
+ ed = ed.gridEditor;
+ }
+ }
+ return ed;
+ }
+});
+
+
+Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
+
+ trueText: 'true',
+
+ falseText: 'false',
+
+ undefinedText: '&#160;',
+
+ constructor: function(cfg){
+ Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
+ var t = this.trueText, f = this.falseText, u = this.undefinedText;
+ this.renderer = function(v){
+ if(v === undefined){
+ return u;
+ }
+ if(!v || v === 'false'){
+ return f;
+ }
+ return t;
+ };
+ }
+});
+
+
+Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
+
+ format : '0,000.00',
+ constructor: function(cfg){
+ Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
+ this.renderer = Ext.util.Format.numberRenderer(this.format);
+ }
+});
+
+
+Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
+
+ format : 'm/d/Y',
+ constructor: function(cfg){
+ Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
+ this.renderer = Ext.util.Format.dateRenderer(this.format);
+ }
+});
+
+
+Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
+
+ constructor: function(cfg){
+ Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
+ var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
+ this.renderer = function(value, p, r){
+ return tpl.apply(r.data);
+ };
+ this.tpl = tpl;
+ }
+});
+
+
+Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
+
+
+
+
+
+
+
+
+ header: '&#160;',
+
+ actionIdRe: /x-action-col-(\d+)/,
+
+
+ altText: '',
+
+ constructor: function(cfg) {
+ var me = this,
+ items = cfg.items || (me.items = [me]),
+ l = items.length,
+ i,
+ item;
+
+ Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);
+
+
+
+ me.renderer = function(v, meta) {
+
+ v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
+
+ meta.css += ' x-action-col-cell';
+ for (i = 0; i < l; i++) {
+ item = items[i];
+ v += '<img alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
+ '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
+ ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
+ ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
+ }
+ return v;
+ };
+ },
+
+ destroy: function() {
+ delete this.items;
+ delete this.renderer;
+ return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
+ },
+
+
+ processEvent : function(name, e, grid, rowIndex, colIndex){
+ var m = e.getTarget().className.match(this.actionIdRe),
+ item, fn;
+ if (m && (item = this.items[parseInt(m[1], 10)])) {
+ if (name == 'click') {
+ (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
+ } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
+ return false;
+ }
+ }
+ return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
+ }
+});
+
+
+Ext.grid.Column.types = {
+ gridcolumn : Ext.grid.Column,
+ booleancolumn: Ext.grid.BooleanColumn,
+ numbercolumn: Ext.grid.NumberColumn,
+ datecolumn: Ext.grid.DateColumn,
+ templatecolumn: Ext.grid.TemplateColumn,
+ actioncolumn: Ext.grid.ActionColumn
+};
+Ext.grid.RowNumberer = Ext.extend(Object, {
+
+ header: "",
+
+ width: 23,
+
+ sortable: false,
+
+ constructor : function(config){
+ Ext.apply(this, config);
+ if(this.rowspan){
+ this.renderer = this.renderer.createDelegate(this);
+ }
+ },
+
+
+ fixed:true,
+ hideable: false,
+ menuDisabled:true,
+ dataIndex: '',
+ id: 'numberer',
+ rowspan: undefined,
+
+
+ renderer : function(v, p, record, rowIndex){
+ if(this.rowspan){
+ p.cellAttr = 'rowspan="'+this.rowspan+'"';
+ }
+ return rowIndex+1;
+ }
+});
+Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
+
+
+
+ header : '<div class="x-grid3-hd-checker">&#160;</div>',
+
+ width : 20,
+
+ sortable : false,
+
+
+ menuDisabled : true,
+ fixed : true,
+ hideable: false,
+ dataIndex : '',
+ id : 'checker',
+ isColumn: true,
+
+ constructor : function(){
+ Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
+ if(this.checkOnly){
+ this.handleMouseDown = Ext.emptyFn;
+ }
+ },
+
+
+ initEvents : function(){
+ Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
+ this.grid.on('render', function(){
+ Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
+ }, this);
+ },
+
+
+ processEvent : function(name, e, grid, rowIndex, colIndex){
+ if (name == 'mousedown') {
+ this.onMouseDown(e, e.getTarget());
+ return false;
+ } else {
+ return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
+ }
+ },
+
+
+ onMouseDown : function(e, t){
+ if(e.button === 0 && t.className == 'x-grid3-row-checker'){
+ e.stopEvent();
+ var row = e.getTarget('.x-grid3-row');
+ if(row){
+ var index = row.rowIndex;
+ if(this.isSelected(index)){
+ this.deselectRow(index);
+ }else{
+ this.selectRow(index, true);
+ this.grid.getView().focusRow(index);
+ }
+ }
+ }
+ },
+
+
+ onHdMouseDown : function(e, t) {
+ if(t.className == 'x-grid3-hd-checker'){
+ e.stopEvent();
+ var hd = Ext.fly(t.parentNode);
+ var isChecked = hd.hasClass('x-grid3-hd-checker-on');
+ if(isChecked){
+ hd.removeClass('x-grid3-hd-checker-on');
+ this.clearSelections();
+ }else{
+ hd.addClass('x-grid3-hd-checker-on');
+ this.selectAll();
+ }
+ }
+ },
+
+
+ renderer : function(v, p, record){
+ return '<div class="x-grid3-row-checker">&#160;</div>';
+ },
+
+ onEditorSelect: function(row, lastRow){
+ if(lastRow != row && !this.checkOnly){
+ this.selectRow(row);
+ }
+ }
+});
+Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
+
+ constructor : function(config){
+ Ext.apply(this, config);
+
+ this.selection = null;
+
+ this.addEvents(
+
+ "beforecellselect",
+
+ "cellselect",
+
+ "selectionchange"
+ );
+
+ Ext.grid.CellSelectionModel.superclass.constructor.call(this);
+ },
+
+
+ initEvents : function(){
+ this.grid.on('cellmousedown', this.handleMouseDown, this);
+ this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
+ this.grid.getView().on({
+ scope: this,
+ refresh: this.onViewChange,
+ rowupdated: this.onRowUpdated,
+ beforerowremoved: this.clearSelections,
+ beforerowsinserted: this.clearSelections
+ });
+ 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, index, r){
+ if(this.selection && this.selection.record == r){
+ v.onCellSelect(index, this.selection.cell[1]);
+ }
+ },
+
+
+ onViewChange : function(){
+ this.clearSelections(true);
+ },
+
+
+ getSelectedCell : function(){
+ return this.selection ? this.selection.cell : null;
+ },
+
+
+ clearSelections : function(preventNotify){
+ var s = this.selection;
+ if(s){
+ if(preventNotify !== 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(g, row, cell, e){
+ if(e.button !== 0 || this.isLocked()){
+ return;
+ }
+ this.select(row, cell);
+ },
+
+
+ select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
+ if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
+ this.clearSelections();
+ r = r || this.grid.store.getAt(rowIndex);
+ this.selection = {
+ record : r,
+ cell : [rowIndex, colIndex]
+ };
+ if(!preventViewNotify){
+ var v = this.grid.getView();
+ v.onCellSelect(rowIndex, colIndex);
+ if(preventFocus !== true){
+ v.focusCell(rowIndex, colIndex);
+ }
+ }
+ this.fireEvent("cellselect", this, rowIndex, colIndex);
+ this.fireEvent("selectionchange", this, this.selection);
+ }
+ },
+
+
+ isSelectable : function(rowIndex, colIndex, cm){
+ return !cm.isHidden(colIndex);
+ },
+
+
+ onEditorKey: function(field, e){
+ if(e.getKey() == e.TAB){
+ this.handleKeyDown(e);
+ }
+ },
+
+
+ handleKeyDown : function(e){
+ if(!e.isNavKeyPress()){
+ return;
+ }
+
+ var k = e.getKey(),
+ g = this.grid,
+ s = this.selection,
+ sm = this,
+ walk = function(row, col, step){
+ return g.walkCells(
+ row,
+ col,
+ step,
+ g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
+ sm
+ );
+ },
+ cell, newCell, r, c, ae;
+
+ switch(k){
+ case e.ESC:
+ case e.PAGE_UP:
+ case e.PAGE_DOWN:
+
+ break;
+ default:
+
+ e.stopEvent();
+ break;
+ }
+
+ if(!s){
+ cell = walk(0, 0, 1);
+ if(cell){
+ this.select(cell[0], cell[1]);
+ }
+ return;
+ }
+
+ cell = s.cell;
+ r = cell[0];
+ c = cell[1];
+
+ switch(k){
+ case e.TAB:
+ if(e.shiftKey){
+ newCell = walk(r, c - 1, -1);
+ }else{
+ newCell = walk(r, c + 1, 1);
+ }
+ break;
+ case e.DOWN:
+ newCell = walk(r + 1, c, 1);
+ break;
+ case e.UP:
+ newCell = walk(r - 1, c, -1);
+ break;
+ case e.RIGHT:
+ newCell = walk(r, c + 1, 1);
+ break;
+ case e.LEFT:
+ newCell = walk(r, c - 1, -1);
+ break;
+ case e.ENTER:
+ if (g.isEditor && !g.editing) {
+ g.startEditing(r, c);
+ return;
+ }
+ break;
+ }
+
+ if(newCell){
+
+ r = newCell[0];
+ c = newCell[1];
+
+ this.select(r, c);
+
+ if(g.isEditor && g.editing){
+ ae = g.activeEditor;
+ if(ae && ae.field.triggerBlur){
+
+ ae.field.triggerBlur();
+ }
+ g.startEditing(r, c);
+ }
+ }
+ },
+
+ acceptsNav : function(row, col, cm){
+ return !cm.isHidden(col) && cm.isCellEditable(col, row);
+ }
+});
+Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
+
+ clicksToEdit: 2,
+
+
+ forceValidation: false,
+
+
+ isEditor : true,
+
+ detectEdit: false,
+
+
+ autoEncode : false,
+
+
+
+ trackMouseOver: false,
+
+
+ initComponent : function(){
+ Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
+
+ if(!this.selModel){
+
+ this.selModel = new Ext.grid.CellSelectionModel();
+ }
+
+ this.activeEditor = null;
+
+ this.addEvents(
+
+ "beforeedit",
+
+ "afteredit",
+
+ "validateedit"
+ );
+ },
+
+
+ initEvents : function(){
+ Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
+
+ this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
+ this.on('columnresize', this.stopEditing, this, [true]);
+
+ if(this.clicksToEdit == 1){
+ this.on("cellclick", this.onCellDblClick, this);
+ }else {
+ var view = this.getView();
+ if(this.clicksToEdit == 'auto' && view.mainBody){
+ view.mainBody.on('mousedown', this.onAutoEditClick, this);
+ }
+ this.on('celldblclick', this.onCellDblClick, this);
+ }
+ },
+
+ onResize : function(){
+ Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
+ var ae = this.activeEditor;
+ if(this.editing && ae){
+ ae.realign(true);
+ }
+ },
+
+
+ onCellDblClick : function(g, row, col){
+ this.startEditing(row, col);
+ },
+
+
+ onAutoEditClick : function(e, t){
+ if(e.button !== 0){
+ return;
+ }
+ var row = this.view.findRowIndex(t),
+ col = this.view.findCellIndex(t);
+ if(row !== false && col !== false){
+ this.stopEditing();
+ if(this.selModel.getSelectedCell){
+ var sc = this.selModel.getSelectedCell();
+ if(sc && sc[0] === row && sc[1] === col){
+ this.startEditing(row, col);
+ }
+ }else{
+ if(this.selModel.isSelected(row)){
+ this.startEditing(row, col);
+ }
+ }
+ }
+ },
+
+
+ onEditComplete : function(ed, value, startValue){
+ this.editing = false;
+ this.lastActiveEditor = this.activeEditor;
+ this.activeEditor = null;
+
+ var r = ed.record,
+ field = this.colModel.getDataIndex(ed.col);
+ value = this.postEditValue(value, startValue, r, field);
+ if(this.forceValidation === true || String(value) !== String(startValue)){
+ var e = {
+ grid: this,
+ record: r,
+ field: field,
+ originalValue: startValue,
+ value: value,
+ row: ed.row,
+ column: ed.col,
+ cancel:false
+ };
+ if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
+ r.set(field, e.value);
+ delete e.cancel;
+ this.fireEvent("afteredit", e);
+ }
+ }
+ this.view.focusCell(ed.row, ed.col);
+ },
+
+
+ startEditing : function(row, col){
+ this.stopEditing();
+ if(this.colModel.isCellEditable(col, row)){
+ this.view.ensureVisible(row, col, true);
+ var r = this.store.getAt(row),
+ field = this.colModel.getDataIndex(col),
+ e = {
+ grid: this,
+ record: r,
+ field: field,
+ value: r.data[field],
+ row: row,
+ column: col,
+ cancel:false
+ };
+ if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
+ this.editing = true;
+ var ed = this.colModel.getCellEditor(col, row);
+ if(!ed){
+ return;
+ }
+ if(!ed.rendered){
+ ed.parentEl = this.view.getEditorParent(ed);
+ ed.on({
+ scope: this,
+ render: {
+ fn: function(c){
+ c.field.focus(false, true);
+ },
+ single: true,
+ scope: this
+ },
+ specialkey: function(field, e){
+ this.getSelectionModel().onEditorKey(field, e);
+ },
+ complete: this.onEditComplete,
+ canceledit: this.stopEditing.createDelegate(this, [true])
+ });
+ }
+ Ext.apply(ed, {
+ row : row,
+ col : col,
+ record : r
+ });
+ this.lastEdit = {
+ row: row,
+ col: col
+ };
+ this.activeEditor = ed;
+ if (ed.field.isXType('checkbox')) {
+ ed.allowBlur = false;
+ this.setupCheckbox(ed.field);
+ }
+
+
+ ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
+ var v = this.preEditValue(r, field);
+ ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
+
+
+ (function(){
+ delete ed.selectSameEditor;
+ }).defer(50);
+ }
+ }
+ },
+
+ setupCheckbox: function(field){
+ var me = this,
+ fn = function() {
+ field.el.on('click', me.onCheckClick, me, {single: true});
+ };
+ if (field.rendered) {
+ fn();
+ } else {
+ field.on('render', fn, null, {single: true});
+ }
+ },
+
+ onCheckClick: function(){
+ var ed = this.activeEditor;
+ ed.allowBlur = true;
+ ed.field.focus(false, 10);
+ },
+
+
+ preEditValue : function(r, field){
+ var value = r.data[field];
+ return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
+ },
+
+
+ postEditValue : function(value, originalValue, r, field){
+ return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
+ },
+
+
+ stopEditing : function(cancel){
+ if(this.editing){
+
+ var ae = this.lastActiveEditor = this.activeEditor;
+ if(ae){
+ ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
+ this.view.focusCell(ae.row, ae.col);
+ }
+ this.activeEditor = null;
+ }
+ this.editing = false;
+ }
+});
+Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
+
+Ext.grid.GridEditor = function(field, config){
+ Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
+ field.monitorTab = false;
+};
+
+Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
+ alignment: "tl-tl",
+ autoSize: "width",
+ hideEl : false,
+ cls: "x-small-editor x-grid-editor",
+ shim:false,
+ shadow:false
+});
+Ext.grid.PropertyRecord = Ext.data.Record.create([
+ {name:'name',type:'string'}, 'value'
+]);
+
+
+Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
+
+ constructor : function(grid, source){
+ this.grid = grid;
+ this.store = new Ext.data.Store({
+ recordType : Ext.grid.PropertyRecord
+ });
+ this.store.on('update', this.onUpdate, this);
+ if(source){
+ this.setSource(source);
+ }
+ Ext.grid.PropertyStore.superclass.constructor.call(this);
+ },
+
+
+ setSource : function(o){
+ this.source = o;
+ this.store.removeAll();
+ var data = [];
+ for(var k in o){
+ if(this.isEditableValue(o[k])){
+ data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
+ }
+ }
+ this.store.loadRecords({records: data}, {}, true);
+ },
+
+
+ onUpdate : function(ds, record, type){
+ if(type == Ext.data.Record.EDIT){
+ var v = record.data.value;
+ var oldValue = record.modified.value;
+ if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
+ this.source[record.id] = v;
+ record.commit();
+ this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
+ }else{
+ record.reject();
+ }
+ }
+ },
+
+
+ getProperty : function(row){
+ return this.store.getAt(row);
+ },
+
+
+ isEditableValue: function(val){
+ return Ext.isPrimitive(val) || Ext.isDate(val);
+ },
+
+
+ setValue : function(prop, value, create){
+ var r = this.getRec(prop);
+ if(r){
+ r.set('value', value);
+ this.source[prop] = value;
+ }else if(create){
+
+ this.source[prop] = value;
+ r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
+ this.store.add(r);
+
+ }
+ },
+
+
+ remove : function(prop){
+ var r = this.getRec(prop);
+ if(r){
+ this.store.remove(r);
+ delete this.source[prop];
+ }
+ },
+
+
+ getRec : function(prop){
+ return this.store.getById(prop);
+ },
+
+
+ getSource : function(){
+ return this.source;
+ }
+});
+
+
+Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
+
+ nameText : 'Name',
+ valueText : 'Value',
+ dateFormat : 'm/j/Y',
+ trueText: 'true',
+ falseText: 'false',
+
+ constructor : function(grid, store){
+ var g = Ext.grid,
+ f = Ext.form;
+
+ this.grid = grid;
+ g.PropertyColumnModel.superclass.constructor.call(this, [
+ {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
+ {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
+ ]);
+ this.store = store;
+
+ var bfield = new f.Field({
+ autoCreate: {tag: 'select', children: [
+ {tag: 'option', value: 'true', html: this.trueText},
+ {tag: 'option', value: 'false', html: this.falseText}
+ ]},
+ getValue : function(){
+ return this.el.dom.value == 'true';
+ }
+ });
+ 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(bfield, {
+ autoSize: 'both'
+ })
+ };
+ this.renderCellDelegate = this.renderCell.createDelegate(this);
+ this.renderPropDelegate = this.renderProp.createDelegate(this);
+ },
+
+
+ renderDate : function(dateVal){
+ return dateVal.dateFormat(this.dateFormat);
+ },
+
+
+ renderBool : function(bVal){
+ return this[bVal ? 'trueText' : 'falseText'];
+ },
+
+
+ isCellEditable : function(colIndex, rowIndex){
+ return colIndex == 1;
+ },
+
+
+ getRenderer : function(col){
+ return col == 1 ?
+ this.renderCellDelegate : this.renderPropDelegate;
+ },
+
+
+ renderProp : function(v){
+ return this.getPropertyName(v);
+ },
+
+
+ renderCell : function(val, meta, rec){
+ var renderer = this.grid.customRenderers[rec.get('name')];
+ if(renderer){
+ return renderer.apply(this, arguments);
+ }
+ var rv = val;
+ if(Ext.isDate(val)){
+ rv = this.renderDate(val);
+ }else if(typeof val == 'boolean'){
+ rv = this.renderBool(val);
+ }
+ return Ext.util.Format.htmlEncode(rv);
+ },
+
+
+ getPropertyName : function(name){
+ var pn = this.grid.propertyNames;
+ return pn && pn[name] ? pn[name] : name;
+ },
+
+
+ getCellEditor : function(colIndex, rowIndex){
+ var p = this.store.getProperty(rowIndex),
+ n = p.data.name,
+ val = p.data.value;
+ if(this.grid.customEditors[n]){
+ return this.grid.customEditors[n];
+ }
+ if(Ext.isDate(val)){
+ 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;
+ }
+ },
+
+
+ destroy : function(){
+ Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
+ this.destroyEditors(this.editors);
+ this.destroyEditors(this.grid.customEditors);
+ },
+
+ destroyEditors: function(editors){
+ for(var ed in editors){
+ Ext.destroy(editors[ed]);
+ }
+ }
+});
+
+
+Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
+
+
+
+
+
+
+ enableColumnMove:false,
+ stripeRows:false,
+ trackMouseOver: false,
+ clicksToEdit:1,
+ enableHdMenu : false,
+ viewConfig : {
+ forceFit:true
+ },
+
+
+ initComponent : function(){
+ this.customRenderers = this.customRenderers || {};
+ this.customEditors = this.customEditors || {};
+ this.lastEditRow = null;
+ var store = new Ext.grid.PropertyStore(this);
+ this.propStore = store;
+ var cm = new Ext.grid.PropertyColumnModel(this, store);
+ store.store.sort('name', 'ASC');
+ this.addEvents(
+
+ 'beforepropertychange',
+
+ 'propertychange'
+ );
+ this.cm = cm;
+ this.ds = store.store;
+ Ext.grid.PropertyGrid.superclass.initComponent.call(this);
+
+ this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
+ if(colIndex === 0){
+ this.startEditing.defer(200, this, [rowIndex, 1]);
+ return false;
+ }
+ }, this);
+ },
+
+
+ onRender : function(){
+ Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
+
+ this.getGridEl().addClass('x-props-grid');
+ },
+
+
+ afterRender: function(){
+ Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
+ if(this.source){
+ this.setSource(this.source);
+ }
+ },
+
+
+ setSource : function(source){
+ this.propStore.setSource(source);
+ },
+
+
+ getSource : function(){
+ return this.propStore.getSource();
+ },
+
+
+ setProperty : function(prop, value, create){
+ this.propStore.setValue(prop, value, create);
+ },
+
+
+ removeProperty : function(prop){
+ this.propStore.remove(prop);
+ }
+
+
+
+
+
+});
+Ext.reg("propertygrid", Ext.grid.PropertyGrid);
+
+Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
+
+
+ groupByText : 'Group By This Field',
+
+ showGroupsText : 'Show in Groups',
+
+ hideGroupedColumn : false,
+
+ showGroupName : true,
+
+ startCollapsed : false,
+
+ enableGrouping : true,
+
+ enableGroupingMenu : true,
+
+ enableNoGroups : true,
+
+ emptyGroupText : '(None)',
+
+ ignoreAdd : false,
+
+ groupTextTpl : '{text}',
+
+
+ groupMode: 'value',
+
+
+
+
+ cancelEditOnToggle: true,
+
+
+ initTemplates : function(){
+ Ext.grid.GroupingView.superclass.initTemplates.call(this);
+ this.state = {};
+
+ var sm = this.grid.getSelectionModel();
+ sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
+ this.onBeforeRowSelect, this);
+
+ if(!this.startGroup){
+ this.startGroup = new Ext.XTemplate(
+ '<div id="{groupId}" class="x-grid-group {cls}">',
+ '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
+ '<div id="{groupId}-bd" class="x-grid-group-body">'
+ );
+ }
+ this.startGroup.compile();
+
+ if (!this.endGroup) {
+ this.endGroup = '</div></div>';
+ }
+ },
+
+
+ findGroup : function(el){
+ return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
+ },
+
+
+ getGroups : function(){
+ return this.hasRows() ? this.mainBody.dom.childNodes : [];
+ },
+
+
+ onAdd : function(ds, records, index) {
+ if (this.canGroup() && !this.ignoreAdd) {
+ var ss = this.getScrollState();
+ this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
+ this.refresh();
+ this.restoreScroll(ss);
+ this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
+ } else if (!this.canGroup()) {
+ Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
+ }
+ },
+
+
+ onRemove : function(ds, record, index, isUpdate){
+ Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
+ var g = document.getElementById(record._groupId);
+ if(g && g.childNodes[1].childNodes.length < 1){
+ Ext.removeNode(g);
+ }
+ this.applyEmptyText();
+ },
+
+
+ refreshRow : function(record){
+ if(this.ds.getCount()==1){
+ this.refresh();
+ }else{
+ this.isUpdating = true;
+ Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
+ this.isUpdating = false;
+ }
+ },
+
+
+ beforeMenuShow : function(){
+ var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
+ if((item = items.get('groupBy'))){
+ item.setDisabled(disabled);
+ }
+ if((item = items.get('showGroups'))){
+ item.setDisabled(disabled);
+ item.setChecked(this.canGroup(), true);
+ }
+ },
+
+
+ renderUI : function(){
+ var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);
+
+ if(this.enableGroupingMenu && this.hmenu){
+ this.hmenu.add('-',{
+ itemId:'groupBy',
+ text: this.groupByText,
+ handler: this.onGroupByClick,
+ scope: this,
+ iconCls:'x-group-by-icon'
+ });
+ if(this.enableNoGroups){
+ this.hmenu.add({
+ itemId:'showGroups',
+ text: this.showGroupsText,
+ checked: true,
+ checkHandler: this.onShowGroupsClick,
+ scope: this
+ });
+ }
+ this.hmenu.on('beforeshow', this.beforeMenuShow, this);
+ }
+ return markup;
+ },
+
+ processEvent: function(name, e){
+ Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
+ var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
+ if(hd){
+
+ var field = this.getGroupField(),
+ prefix = this.getPrefix(field),
+ groupValue = hd.id.substring(prefix.length),
+ emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
+
+
+ groupValue = groupValue.substr(0, groupValue.length - 3);
+
+
+ if(groupValue || emptyRe.test(hd.id)){
+ this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
+ }
+ if(name == 'mousedown' && e.button == 0){
+ this.toggleGroup(hd.parentNode);
+ }
+ }
+
+ },
+
+
+ onGroupByClick : function(){
+ var grid = this.grid;
+ this.enableGrouping = true;
+ grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
+ grid.fireEvent('groupchange', grid, grid.store.getGroupState());
+ this.beforeMenuShow();
+ this.refresh();
+ },
+
+
+ onShowGroupsClick : function(mi, checked){
+ this.enableGrouping = checked;
+ if(checked){
+ this.onGroupByClick();
+ }else{
+ this.grid.store.clearGrouping();
+ this.grid.fireEvent('groupchange', this, null);
+ }
+ },
+
+
+ toggleRowIndex : function(rowIndex, expanded){
+ if(!this.canGroup()){
+ return;
+ }
+ var row = this.getRow(rowIndex);
+ if(row){
+ this.toggleGroup(this.findGroup(row), expanded);
+ }
+ },
+
+
+ toggleGroup : function(group, expanded){
+ var gel = Ext.get(group),
+ id = Ext.util.Format.htmlEncode(gel.id);
+
+ expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
+ if(this.state[id] !== expanded){
+ if (this.cancelEditOnToggle !== false) {
+ this.grid.stopEditing(true);
+ }
+ this.state[id] = expanded;
+ gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
+ }
+ },
+
+
+ toggleAllGroups : function(expanded){
+ var groups = this.getGroups();
+ for(var i = 0, len = groups.length; i < len; i++){
+ this.toggleGroup(groups[i], expanded);
+ }
+ },
+
+
+ expandAllGroups : function(){
+ this.toggleAllGroups(true);
+ },
+
+
+ collapseAllGroups : function(){
+ this.toggleAllGroups(false);
+ },
+
+
+ getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
+ var column = this.cm.config[colIndex],
+ g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
+ if(g === '' || g === '&#160;'){
+ g = column.emptyGroupText || this.emptyGroupText;
+ }
+ return g;
+ },
+
+
+ getGroupField : function(){
+ return this.grid.store.getGroupState();
+ },
+
+
+ afterRender : function(){
+ if(!this.ds || !this.cm){
+ return;
+ }
+ Ext.grid.GroupingView.superclass.afterRender.call(this);
+ if(this.grid.deferRowRender){
+ this.updateGroupWidths();
+ }
+ },
+
+ afterRenderUI: function () {
+ Ext.grid.GroupingView.superclass.afterRenderUI.call(this);
+
+ if (this.enableGroupingMenu && this.hmenu) {
+ this.hmenu.add('-',{
+ itemId:'groupBy',
+ text: this.groupByText,
+ handler: this.onGroupByClick,
+ scope: this,
+ iconCls:'x-group-by-icon'
+ });
+
+ if (this.enableNoGroups) {
+ this.hmenu.add({
+ itemId:'showGroups',
+ text: this.showGroupsText,
+ checked: true,
+ checkHandler: this.onShowGroupsClick,
+ scope: this
+ });
+ }
+
+ this.hmenu.on('beforeshow', this.beforeMenuShow, this);
+ }
+ },
+
+
+ renderRows : function(){
+ var groupField = this.getGroupField();
+ var eg = !!groupField;
+
+ if(this.hideGroupedColumn) {
+ var colIndex = this.cm.findColumnIndex(groupField),
+ hasLastGroupField = Ext.isDefined(this.lastGroupField);
+ if(!eg && hasLastGroupField){
+ this.mainBody.update('');
+ this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
+ delete this.lastGroupField;
+ }else if (eg && !hasLastGroupField){
+ this.lastGroupField = groupField;
+ this.cm.setHidden(colIndex, true);
+ }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
+ this.mainBody.update('');
+ var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
+ this.cm.setHidden(oldIndex, false);
+ this.lastGroupField = groupField;
+ this.cm.setHidden(colIndex, true);
+ }
+ }
+ return Ext.grid.GroupingView.superclass.renderRows.apply(
+ this, arguments);
+ },
+
+
+ doRender : function(cs, rs, ds, startRow, colCount, stripe){
+ if(rs.length < 1){
+ return '';
+ }
+
+ if(!this.canGroup() || this.isUpdating){
+ return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
+ }
+
+ var groupField = this.getGroupField(),
+ colIndex = this.cm.findColumnIndex(groupField),
+ g,
+ gstyle = 'width:' + this.getTotalWidth() + ';',
+ cfg = this.cm.config[colIndex],
+ groupRenderer = cfg.groupRenderer || cfg.renderer,
+ prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
+ groups = [],
+ curGroup, i, len, gid;
+
+ for(i = 0, len = rs.length; i < len; i++){
+ var rowIndex = startRow + i,
+ r = rs[i],
+ gvalue = r.data[groupField];
+
+ g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
+ if(!curGroup || curGroup.group != g){
+ gid = this.constructId(gvalue, groupField, colIndex);
+
+
+ this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
+ curGroup = {
+ group: g,
+ gvalue: gvalue,
+ text: prefix + g,
+ groupId: gid,
+ startRow: rowIndex,
+ rs: [r],
+ cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
+ style: gstyle
+ };
+ groups.push(curGroup);
+ }else{
+ curGroup.rs.push(r);
+ }
+ r._groupId = gid;
+ }
+
+ var buf = [];
+ for(i = 0, len = groups.length; i < len; i++){
+ g = groups[i];
+ this.doGroupStart(buf, g, cs, ds, colCount);
+ buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
+ this, cs, g.rs, ds, g.startRow, colCount, stripe);
+
+ this.doGroupEnd(buf, g, cs, ds, colCount);
+ }
+ return buf.join('');
+ },
+
+
+ getGroupId : function(value){
+ var field = this.getGroupField();
+ return this.constructId(value, field, this.cm.findColumnIndex(field));
+ },
+
+
+ constructId : function(value, field, idx){
+ var cfg = this.cm.config[idx],
+ groupRenderer = cfg.groupRenderer || cfg.renderer,
+ val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
+
+ return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
+ },
+
+
+ canGroup : function(){
+ return this.enableGrouping && !!this.getGroupField();
+ },
+
+
+ getPrefix: function(field){
+ return this.grid.getGridEl().id + '-gp-' + field + '-';
+ },
+
+
+ doGroupStart : function(buf, g, cs, ds, colCount){
+ buf[buf.length] = this.startGroup.apply(g);
+ },
+
+
+ doGroupEnd : function(buf, g, cs, ds, colCount){
+ buf[buf.length] = this.endGroup;
+ },
+
+
+ getRows : function(){
+ if(!this.canGroup()){
+ return Ext.grid.GroupingView.superclass.getRows.call(this);
+ }
+ var r = [],
+ gs = this.getGroups(),
+ g,
+ i = 0,
+ len = gs.length,
+ j,
+ jlen;
+ for(; i < len; ++i){
+ g = gs[i].childNodes[1];
+ if(g){
+ g = g.childNodes;
+ for(j = 0, jlen = g.length; j < jlen; ++j){
+ r[r.length] = g[j];
+ }
+ }
+ }
+ return r;
+ },
+
+
+ updateGroupWidths : function(){
+ if(!this.canGroup() || !this.hasRows()){
+ return;
+ }
+ var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
+ var gs = this.getGroups();
+ for(var i = 0, len = gs.length; i < len; i++){
+ gs[i].firstChild.style.width = tw;
+ }
+ },
+
+
+ onColumnWidthUpdated : function(col, w, tw){
+ Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
+ this.updateGroupWidths();
+ },
+
+
+ onAllColumnWidthsUpdated : function(ws, tw){
+ Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
+ this.updateGroupWidths();
+ },
+
+
+ onColumnHiddenUpdated : function(col, hidden, tw){
+ Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
+ this.updateGroupWidths();
+ },
+
+
+ onLayout : function(){
+ this.updateGroupWidths();
+ },
+
+
+ onBeforeRowSelect : function(sm, rowIndex){
+ this.toggleRowIndex(rowIndex, true);
+ }
+});
+
+Ext.grid.GroupingView.GROUP_ID = 1000;
diff --git a/deluge/ui/web/js/extjs/ext-all.js b/deluge/ui/web/js/extjs/ext-all.js
new file mode 100644
index 0000000..5f3e5aa
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-all.js
@@ -0,0 +1,21 @@
+/*
+This file is part of Ext JS 3.4
+
+Copyright (c) 2011-2013 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as
+published by the Free Software Foundation and appearing in the file LICENSE included in the
+packaging of this file.
+
+Please review the following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department
+at http://www.sencha.com/contact.
+
+Build date: 2013-04-03 15:07:25
+*/
+(function(){var h=Ext.util,j=Ext.each,g=true,i=false;h.Observable=function(){var k=this,l=k.events;if(k.listeners){k.on(k.listeners);delete k.listeners}k.events=l||{}};h.Observable.prototype={filterOptRe:/^(?:scope|delay|buffer|single)$/,fireEvent:function(){var k=Array.prototype.slice.call(arguments,0),m=k[0].toLowerCase(),n=this,l=g,p=n.events[m],s,o,r;if(n.eventsSuspended===g){if(o=n.eventQueue){o.push(k)}}else{if(typeof p=="object"){if(p.bubble){if(p.fire.apply(p,k.slice(1))===i){return i}r=n.getBubbleTarget&&n.getBubbleTarget();if(r&&r.enableBubble){s=r.events[m];if(!s||typeof s!="object"||!s.bubble){r.enableBubble(m)}return r.fireEvent.apply(r,k)}}else{k.shift();l=p.fire.apply(p,k)}}}return l},addListener:function(k,m,l,r){var n=this,q,s,p;if(typeof k=="object"){r=k;for(q in r){s=r[q];if(!n.filterOptRe.test(q)){n.addListener(q,s.fn||s,s.scope||r.scope,s.fn?s:r)}}}else{k=k.toLowerCase();p=n.events[k]||g;if(typeof p=="boolean"){n.events[k]=p=new h.Event(n,k)}p.addListener(m,l,typeof r=="object"?r:{})}},removeListener:function(k,m,l){var n=this.events[k.toLowerCase()];if(typeof n=="object"){n.removeListener(m,l)}},purgeListeners:function(){var m=this.events,k,l;for(l in m){k=m[l];if(typeof k=="object"){k.clearListeners()}}},addEvents:function(n){var m=this;m.events=m.events||{};if(typeof n=="string"){var k=arguments,l=k.length;while(l--){m.events[k[l]]=m.events[k[l]]||g}}else{Ext.applyIf(m.events,n)}},hasListener:function(k){var l=this.events[k.toLowerCase()];return typeof l=="object"&&l.listeners.length>0},suspendEvents:function(k){this.eventsSuspended=g;if(k&&!this.eventQueue){this.eventQueue=[]}},resumeEvents:function(){var k=this,l=k.eventQueue||[];k.eventsSuspended=i;delete k.eventQueue;j(l,function(m){k.fireEvent.apply(k,m)})}};var d=h.Observable.prototype;d.on=d.addListener;d.un=d.removeListener;h.Observable.releaseCapture=function(k){k.fireEvent=d.fireEvent};function e(l,m,k){return function(){if(m.target==arguments[0]){l.apply(k,Array.prototype.slice.call(arguments,0))}}}function b(n,p,k,m){k.task=new h.DelayedTask();return function(){k.task.delay(p.buffer,n,m,Array.prototype.slice.call(arguments,0))}}function c(m,n,l,k){return function(){n.removeListener(l,k);return m.apply(k,arguments)}}function a(n,p,k,m){return function(){var l=new h.DelayedTask(),o=Array.prototype.slice.call(arguments,0);if(!k.tasks){k.tasks=[]}k.tasks.push(l);l.delay(p.delay||10,function(){k.tasks.remove(l);n.apply(m,o)},m)}}h.Event=function(l,k){this.name=k;this.obj=l;this.listeners=[]};h.Event.prototype={addListener:function(o,n,m){var p=this,k;n=n||p.obj;if(!p.isListening(o,n)){k=p.createListener(o,n,m);if(p.firing){p.listeners=p.listeners.slice(0)}p.listeners.push(k)}},createListener:function(p,n,q){q=q||{};n=n||this.obj;var k={fn:p,scope:n,options:q},m=p;if(q.target){m=e(m,q,n)}if(q.delay){m=a(m,q,k,n)}if(q.single){m=c(m,this,p,n)}if(q.buffer){m=b(m,q,k,n)}k.fireFn=m;return k},findListener:function(o,n){var p=this.listeners,m=p.length,k;n=n||this.obj;while(m--){k=p[m];if(k){if(k.fn==o&&k.scope==n){return m}}}return -1},isListening:function(l,k){return this.findListener(l,k)!=-1},removeListener:function(r,q){var p,m,n,s=this,o=i;if((p=s.findListener(r,q))!=-1){if(s.firing){s.listeners=s.listeners.slice(0)}m=s.listeners[p];if(m.task){m.task.cancel();delete m.task}n=m.tasks&&m.tasks.length;if(n){while(n--){m.tasks[n].cancel()}delete m.tasks}s.listeners.splice(p,1);o=g}return o},clearListeners:function(){var n=this,k=n.listeners,m=k.length;while(m--){n.removeListener(k[m].fn,k[m].scope)}},fire:function(){var q=this,p=q.listeners,k=p.length,o=0,m;if(k>0){q.firing=g;var n=Array.prototype.slice.call(arguments,0);for(;o<k;o++){m=p[o];if(m&&m.fireFn.apply(m.scope||q.obj||window,n)===i){return(q.firing=i)}}}q.firing=i;return g}}})();Ext.DomHelper=function(){var x=null,k=/^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,m=/^table|tbody|tr|td$/i,d=/tag|children|cn|html$/i,t=/td|tr|tbody/i,o=/([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,v=/end/i,r,n="afterbegin",p="afterend",c="beforebegin",q="beforeend",a="<table>",i="</table>",b=a+"<tbody>",j="</tbody>"+i,l=b+"<tr>",w="</tr>"+j;function h(B,D,C,E,A,y){var z=r.insertHtml(E,Ext.getDom(B),u(D));return C?Ext.get(z,true):z}function u(D){var z="",y,C,B,E;if(typeof D=="string"){z=D}else{if(Ext.isArray(D)){for(var A=0;A<D.length;A++){if(D[A]){z+=u(D[A])}}}else{z+="<"+(D.tag=D.tag||"div");for(y in D){C=D[y];if(!d.test(y)){if(typeof C=="object"){z+=" "+y+'="';for(B in C){z+=B+":"+C[B]+";"}z+='"'}else{z+=" "+({cls:"class",htmlFor:"for"}[y]||y)+'="'+C+'"'}}}if(k.test(D.tag)){z+="/>"}else{z+=">";if((E=D.children||D.cn)){z+=u(E)}else{if(D.html){z+=D.html}}z+="</"+D.tag+">"}}}return z}function g(F,C,B,D){x.innerHTML=[C,B,D].join("");var y=-1,A=x,z;while(++y<F){A=A.firstChild}if(z=A.nextSibling){var E=document.createDocumentFragment();while(A){z=A.nextSibling;E.appendChild(A);A=z}A=E}return A}function e(y,z,B,A){var C,D;x=x||document.createElement("div");if(y=="td"&&(z==n||z==q)||!t.test(y)&&(z==c||z==p)){return}D=z==c?B:z==p?B.nextSibling:z==n?B.firstChild:null;if(z==c||z==p){B=B.parentNode}if(y=="td"||(y=="tr"&&(z==q||z==n))){C=g(4,l,A,w)}else{if((y=="tbody"&&(z==q||z==n))||(y=="tr"&&(z==c||z==p))){C=g(3,b,A,j)}else{C=g(2,a,A,i)}}B.insertBefore(C,D);return C}function s(A){var D=document.createElement("div"),y=document.createDocumentFragment(),z=0,B,C;D.innerHTML=A;C=D.childNodes;B=C.length;for(;z<B;z++){y.appendChild(C[z].cloneNode(true))}return y}r={markup:function(y){return u(y)},applyStyles:function(y,z){if(z){var A;y=Ext.fly(y);if(typeof z=="function"){z=z.call()}if(typeof z=="string"){o.lastIndex=0;while((A=o.exec(z))){y.setStyle(A[1],A[2])}}else{if(typeof z=="object"){y.setStyle(z)}}}},insertHtml:function(D,y,E){var B={},A,F,C,G,H,z;D=D.toLowerCase();B[c]=["BeforeBegin","previousSibling"];B[p]=["AfterEnd","nextSibling"];if(y.insertAdjacentHTML){if(m.test(y.tagName)&&(z=e(y.tagName.toLowerCase(),D,y,E))){return z}B[n]=["AfterBegin","firstChild"];B[q]=["BeforeEnd","lastChild"];if((A=B[D])){y.insertAdjacentHTML(A[0],E);return y[A[1]]}}else{F=y.ownerDocument.createRange();G="setStart"+(v.test(D)?"After":"Before");if(B[D]){F[G](y);if(!F.createContextualFragment){H=s(E)}else{H=F.createContextualFragment(E)}y.parentNode.insertBefore(H,D==c?y:y.nextSibling);return y[(D==c?"previous":"next")+"Sibling"]}else{C=(D==n?"first":"last")+"Child";if(y.firstChild){F[G](y[C]);if(!F.createContextualFragment){H=s(E)}else{H=F.createContextualFragment(E)}if(D==n){y.insertBefore(H,y.firstChild)}else{y.appendChild(H)}}else{y.innerHTML=E}return y[C]}}throw'Illegal insertion point -> "'+D+'"'},insertBefore:function(y,A,z){return h(y,A,z,c)},insertAfter:function(y,A,z){return h(y,A,z,p,"nextSibling")},insertFirst:function(y,A,z){return h(y,A,z,n,"firstChild")},append:function(y,A,z){return h(y,A,z,q,"",true)},overwrite:function(y,A,z){y=Ext.getDom(y);y.innerHTML=u(A);return z?Ext.get(y.firstChild):y.firstChild},createHtml:u};return r}();Ext.Template=function(h){var j=this,c=arguments,e=[],d;if(Ext.isArray(h)){h=h.join("")}else{if(c.length>1){for(var g=0,b=c.length;g<b;g++){d=c[g];if(typeof d=="object"){Ext.apply(j,d)}else{e.push(d)}}h=e.join("")}}j.html=h;if(j.compiled){j.compile()}};Ext.Template.prototype={re:/\{([\w\-]+)\}/g,applyTemplate:function(a){var b=this;return b.compiled?b.compiled(a):b.html.replace(b.re,function(c,d){return a[d]!==undefined?a[d]:""})},set:function(a,c){var b=this;b.html=a;b.compiled=null;return c?b.compile():b},compile:function(){var me=this,sep=Ext.isGecko?"+":",";function fn(m,name){name="values['"+name+"']";return"'"+sep+"("+name+" == undefined ? '' : "+name+")"+sep+"'"}eval("this.compiled = function(values){ return "+(Ext.isGecko?"'":"['")+me.html.replace(/\\/g,"\\\\").replace(/(\r\n|\n)/g,"\\n").replace(/'/g,"\\'").replace(this.re,fn)+(Ext.isGecko?"';};":"'].join('');};"));return me},insertFirst:function(b,a,c){return this.doInsert("afterBegin",b,a,c)},insertBefore:function(b,a,c){return this.doInsert("beforeBegin",b,a,c)},insertAfter:function(b,a,c){return this.doInsert("afterEnd",b,a,c)},append:function(b,a,c){return this.doInsert("beforeEnd",b,a,c)},doInsert:function(c,e,b,a){e=Ext.getDom(e);var d=Ext.DomHelper.insertHtml(c,e,this.applyTemplate(b));return a?Ext.get(d,true):d},overwrite:function(b,a,c){b=Ext.getDom(b);b.innerHTML=this.applyTemplate(a);return c?Ext.get(b.firstChild,true):b.firstChild}};Ext.Template.prototype.apply=Ext.Template.prototype.applyTemplate;Ext.Template.from=function(b,a){b=Ext.getDom(b);return new Ext.Template(b.value||b.innerHTML,a||"")};Ext.DomQuery=function(){var cache={},simpleCache={},valueCache={},nonSpace=/\S/,trimRe=/^\s+|\s+$/g,tplRe=/\{(\d+)\}/g,modeRe=/^(\s?[\/>+~]\s?|\s|$)/,tagTokenRe=/^(#)?([\w\-\*]+)/,nthRe=/(\d*)n\+?(\d*)/,nthRe2=/\D/,isIE=window.ActiveXObject?true:false,key=30803;eval("var batch = 30803;");function child(parent,index){var i=0,n=parent.firstChild;while(n){if(n.nodeType==1){if(++i==index){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 children(parent){var n=parent.firstChild,nodeIndex=-1,nextNode;while(n){nextNode=n.nextSibling;if(n.nodeType==3&&!nonSpace.test(n.nodeValue)){parent.removeChild(n)}else{n.nodeIndex=++nodeIndex}n=nextNode}return this}function byClassName(nodeSet,cls){if(!cls){return nodeSet}var result=[],ri=-1;for(var i=0,ci;ci=nodeSet[i];i++){if((" "+ci.className+" ").indexOf(cls)!=-1){result[++ri]=ci}}return result}function attrValue(n,attr){if(!n.tagName&&typeof n.length!="undefined"){n=n[0]}if(!n){return null}if(attr=="for"){return n.htmlFor}if(attr=="class"||attr=="className"){return n.className}return n.getAttribute(attr)||n[attr]}function getNodes(ns,mode,tagName){var result=[],ri=-1,cs;if(!ns){return result}tagName=tagName||"*";if(typeof ns.getElementsByTagName!="undefined"){ns=[ns]}if(!mode){for(var i=0,ni;ni=ns[i];i++){cs=ni.getElementsByTagName(tagName);for(var j=0,ci;ci=cs[j];j++){result[++ri]=ci}}}else{if(mode=="/"||mode==">"){var utag=tagName.toUpperCase();for(var i=0,ni,cn;ni=ns[i];i++){cn=ni.childNodes;for(var j=0,cj;cj=cn[j];j++){if(cj.nodeName==utag||cj.nodeName==tagName||tagName=="*"){result[++ri]=cj}}}}else{if(mode=="+"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(n&&(n.nodeName==utag||n.nodeName==tagName||tagName=="*")){result[++ri]=n}}}else{if(mode=="~"){var utag=tagName.toUpperCase();for(var i=0,n;n=ns[i];i++){while((n=n.nextSibling)){if(n.nodeName==utag||n.nodeName==tagName||tagName=="*"){result[++ri]=n}}}}}}}return result}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,tagName){if(cs.tagName||cs==document){cs=[cs]}if(!tagName){return cs}var result=[],ri=-1;tagName=tagName.toLowerCase();for(var i=0,ci;ci=cs[i];i++){if(ci.nodeType==1&&ci.tagName.toLowerCase()==tagName){result[++ri]=ci}}return result}function byId(cs,id){if(cs.tagName||cs==document){cs=[cs]}if(!id){return cs}var result=[],ri=-1;for(var i=0,ci;ci=cs[i];i++){if(ci&&ci.id==id){result[++ri]=ci;return result}}return result}function byAttribute(cs,attr,value,op,custom){var result=[],ri=-1,useGetStyle=custom=="{",fn=Ext.DomQuery.operators[op],a,xml,hasXml;for(var i=0,ci;ci=cs[i];i++){if(ci.nodeType!=1){continue}if(!hasXml){xml=Ext.DomQuery.isXml(ci);hasXml=true}if(!xml){if(useGetStyle){a=Ext.DomQuery.getStyle(ci,attr)}else{if(attr=="class"||attr=="className"){a=ci.className}else{if(attr=="for"){a=ci.htmlFor}else{if(attr=="href"){a=ci.getAttribute("href",2)}else{a=ci.getAttribute(attr)}}}}}else{a=ci.getAttribute(attr)}if((fn&&fn(a,value))||(!fn&&a)){result[++ri]=ci}}return result}function byPseudo(cs,name,value){return Ext.DomQuery.pseudos[name](cs,value)}function nodupIEXml(cs){var d=++key,r;cs[0].setAttribute("_nodup",d);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,ri=-1;if(!len||typeof cs.nodeType!="undefined"||len==1){return cs}if(isIE&&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[++ri]=cs[j]}for(j=i+1;cj=cs[j];j++){if(cj._nodup!=d){cj._nodup=d;r[++ri]=cj}}return r}}return r}function quickDiffIEXml(c1,c2){var d=++key,r=[];for(var i=0,len=c1.length;i<len;i++){c1[i].setAttribute("_qdiff",d)}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 len1=c1.length,d=++key,r=[];if(!len1){return c2}if(isIE&&typeof c1[0].selectSingleNode!="undefined"){return quickDiffIEXml(c1,c2)}for(var i=0;i<len1;i++){c1[i]._qdiff=d}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,mode,root,id){if(ns==root){var d=root.ownerDocument||root;return d.getElementById(id)}ns=getNodes(ns,mode,"*");return byId(ns,id)}return{getStyle:function(el,name){return Ext.fly(el).getStyle(name)},compile:function(path,type){type=type||"select";var fn=["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],mode,lastPath,matchers=Ext.DomQuery.matchers,matchersLn=matchers.length,modeMatch,lmode=path.match(modeRe);if(lmode&&lmode[1]){fn[fn.length]='mode="'+lmode[1].replace(trimRe,"")+'";';path=path.replace(lmode[1],"")}while(path.substr(0,1)=="/"){path=path.substr(1)}while(path&&lastPath!=path){lastPath=path;var tokenMatch=path.match(tagTokenRe);if(type=="select"){if(tokenMatch){if(tokenMatch[1]=="#"){fn[fn.length]='n = quickId(n, mode, root, "'+tokenMatch[2]+'");'}else{fn[fn.length]='n = getNodes(n, mode, "'+tokenMatch[2]+'");'}path=path.replace(tokenMatch[0],"")}else{if(path.substr(0,1)!="@"){fn[fn.length]='n = getNodes(n, mode, "*");'}}}else{if(tokenMatch){if(tokenMatch[1]=="#"){fn[fn.length]='n = byId(n, "'+tokenMatch[2]+'");'}else{fn[fn.length]='n = byTag(n, "'+tokenMatch[2]+'");'}path=path.replace(tokenMatch[0],"")}}while(!(modeMatch=path.match(modeRe))){var matched=false;for(var j=0;j<matchersLn;j++){var t=matchers[j];var m=path.match(t.re);if(m){fn[fn.length]=t.select.replace(tplRe,function(x,i){return m[i]});path=path.replace(m[0],"");matched=true;break}}if(!matched){throw'Error parsing selector, parsing failed at "'+path+'"'}}if(modeMatch[1]){fn[fn.length]='mode="'+modeMatch[1].replace(trimRe,"")+'";';path=path.replace(modeMatch[1],"")}}fn[fn.length]="return nodup(n);\n}";eval(fn.join(""));return f},jsSelect:function(path,root,type){root=root||document;if(typeof root=="string"){root=document.getElementById(root)}var paths=path.split(","),results=[];for(var i=0,len=paths.length;i<len;i++){var subPath=paths[i].replace(trimRe,"");if(!cache[subPath]){cache[subPath]=Ext.DomQuery.compile(subPath);if(!cache[subPath]){throw subPath+" is not a valid selector"}}var result=cache[subPath](root);if(result&&result!=document){results=results.concat(result)}}if(paths.length>1){return nodup(results)}return results},isXml:function(el){var docEl=(el?el.ownerDocument||el:0).documentElement;return docEl?docEl.nodeName!=="HTML":false},select:document.querySelectorAll?function(path,root,type){root=root||document;if(!Ext.DomQuery.isXml(root)){try{var cs=root.querySelectorAll(path);return Ext.toArray(cs)}catch(ex){}}return Ext.DomQuery.jsSelect.call(this,path,root,type)}:function(path,root,type){return Ext.DomQuery.jsSelect.call(this,path,root,type)},selectNode:function(path,root){return Ext.DomQuery.select(path,root)[0]},selectValue:function(path,root,defaultValue){path=path.replace(trimRe,"");if(!valueCache[path]){valueCache[path]=Ext.DomQuery.compile(path,"select")}var n=valueCache[path](root),v;n=n[0]?n[0]:n;if(typeof n.normalize=="function"){n.normalize()}v=(n&&n.firstChild?n.firstChild.nodeValue:null);return((v===null||v===undefined||v==="")?defaultValue:v)},selectNumber:function(path,root,defaultValue){var v=Ext.DomQuery.selectValue(path,root,defaultValue||0);return parseFloat(v)},is:function(el,ss){if(typeof el=="string"){el=document.getElementById(el)}var isArray=Ext.isArray(el),result=Ext.DomQuery.filter(isArray?el:[el],ss);return isArray?(result.length==el.length):(result.length>0)},filter:function(els,ss,nonMatches){ss=ss.replace(trimRe,"");if(!simpleCache[ss]){simpleCache[ss]=Ext.DomQuery.compile(ss,"simple")}var result=simpleCache[ss](els);return nonMatches?quickDiff(result,els):result},matchers:[{re:/^\.([\w\-]+)/,select:'n = byClassName(n, " {1} ");'},{re:/^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,select:'n = byPseudo(n, "{1}", "{2}");'},{re:/^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?(["']?)(.*?)\4)?[\]\}])/,select:'n = byAttribute(n, "{2}", "{5}", "{3}", "{1}");'},{re:/^#([\w\-]+)/,select:'n = byId(n, "{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},"|=":function(a,v){return a&&(a==v||a.substr(0,v.length+1)==v+"-")},"~=":function(a,v){return a&&(" "+a+" ").indexOf(" "+v+" ")!=-1}},pseudos:{"first-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.previousSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"last-child":function(c){var r=[],ri=-1,n;for(var i=0,ci;ci=n=c[i];i++){while((n=n.nextSibling)&&n.nodeType!=1){}if(!n){r[++ri]=ci}}return r},"nth-child":function(c,a){var r=[],ri=-1,m=nthRe.exec(a=="even"&&"2n"||a=="odd"&&"2n+1"||!nthRe2.test(a)&&"n+"+a||a),f=(m[1]||1)-0,l=m[2]-0;for(var i=0,n;n=c[i];i++){var pn=n.parentNode;if(batch!=pn._batch){var j=0;for(var cn=pn.firstChild;cn;cn=cn.nextSibling){if(cn.nodeType==1){cn.nodeIndex=++j}}pn._batch=batch}if(f==1){if(l==0||n.nodeIndex==l){r[++ri]=n}}else{if((n.nodeIndex+l)%f==0){r[++ri]=n}}}return r},"only-child":function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(!prev(ci)&&!next(ci)){r[++ri]=ci}}return r},empty:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var cns=ci.childNodes,j=0,cn,empty=true;while(cn=cns[j]){++j;if(cn.nodeType==1||cn.nodeType==3){empty=false;break}}if(empty){r[++ri]=ci}}return r},contains:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if((ci.textContent||ci.innerText||"").indexOf(v)!=-1){r[++ri]=ci}}return r},nodeValue:function(c,v){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.firstChild&&ci.firstChild.nodeValue==v){r[++ri]=ci}}return r},checked:function(c){var r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(ci.checked==true){r[++ri]=ci}}return r},not:function(c,ss){return Ext.DomQuery.filter(c,ss,true)},any:function(c,selectors){var ss=selectors.split("|"),r=[],ri=-1,s;for(var i=0,ci;ci=c[i];i++){for(var j=0;s=ss[j];j++){if(Ext.DomQuery.is(ci,s)){r[++ri]=ci;break}}}return r},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,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){if(s(ss,ci).length>0){r[++ri]=ci}}return r},next:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=next(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r},prev:function(c,ss){var is=Ext.DomQuery.is,r=[],ri=-1;for(var i=0,ci;ci=c[i];i++){var n=prev(ci);if(n&&is(n,ss)){r[++ri]=ci}}return r}}}}();Ext.query=Ext.DomQuery.select;Ext.util.DelayedTask=function(d,c,a){var e=this,g,b=function(){clearInterval(g);g=null;d.apply(c,a||[])};e.delay=function(i,k,j,h){e.cancel();d=k||d;c=j||c;a=h||a;g=setInterval(b,i)};e.cancel=function(){if(g){clearInterval(g);g=null}}};(function(){var h=document;Ext.Element=function(l,m){var n=typeof l=="string"?h.getElementById(l):l,o;if(!n){return null}o=n.id;if(!m&&o&&Ext.elCache[o]){return Ext.elCache[o].el}this.dom=n;this.id=o||Ext.id(n)};var d=Ext.DomHelper,e=Ext.Element,a=Ext.elCache;e.prototype={set:function(q,m){var n=this.dom,l,p,m=(m!==false)&&!!n.setAttribute;for(l in q){if(q.hasOwnProperty(l)){p=q[l];if(l=="style"){d.applyStyles(n,p)}else{if(l=="cls"){n.className=p}else{if(m){n.setAttribute(l,p)}else{n[l]=p}}}}}return this},defaultUnit:"px",is:function(l){return Ext.DomQuery.is(this.dom,l)},focus:function(o,n){var l=this,n=n||l.dom;try{if(Number(o)){l.focus.defer(o,null,[null,n])}else{n.focus()}}catch(m){}return l},blur:function(){try{this.dom.blur()}catch(l){}return this},getValue:function(l){var m=this.dom.value;return l?parseInt(m,10):m},addListener:function(l,o,n,m){Ext.EventManager.on(this.dom,l,o,n||this,m);return this},removeListener:function(l,n,m){Ext.EventManager.removeListener(this.dom,l,n,m||this);return this},removeAllListeners:function(){Ext.EventManager.removeAll(this.dom);return this},purgeAllListeners:function(){Ext.EventManager.purgeElement(this,true);return this},addUnits:function(l){if(l===""||l=="auto"||l===undefined){l=l||""}else{if(!isNaN(l)||!i.test(l)){l=l+(this.defaultUnit||"px")}}return l},load:function(m,n,l){Ext.Ajax.request(Ext.apply({params:n,url:m.url||m,callback:l,el:this.dom,indicatorText:m.indicatorText||""},Ext.isObject(m)?m:{}));return this},isBorderBox:function(){return Ext.isBorderBox||Ext.isForcedBorderBox||g[(this.dom.tagName||"").toLowerCase()]},remove:function(){var l=this,m=l.dom;if(m){delete l.dom;Ext.removeNode(m)}},hover:function(m,l,o,n){var p=this;p.on("mouseenter",m,o||p.dom,n);p.on("mouseleave",l,o||p.dom,n);return p},contains:function(l){return !l?false:Ext.lib.Dom.isAncestor(this.dom,l.dom?l.dom:l)},getAttributeNS:function(m,l){return this.getAttribute(l,m)},getAttribute:(function(){var p=document.createElement("table"),o=false,m="getAttribute" in p,l=/undefined|unknown/;if(m){try{p.getAttribute("ext:qtip")}catch(n){o=true}return function(q,s){var r=this.dom,t;if(r.getAttributeNS){t=r.getAttributeNS(s,q)||null}if(t==null){if(s){if(o&&r.tagName.toUpperCase()=="TABLE"){try{t=r.getAttribute(s+":"+q)}catch(u){t=""}}else{t=r.getAttribute(s+":"+q)}}else{t=r.getAttribute(q)||r[q]}}return t||""}}else{return function(q,s){var r=this.om,u,t;if(s){t=r[s+":"+q];u=l.test(typeof t)?undefined:t}else{u=r[q]}return u||""}}p=null})(),update:function(l){if(this.dom){this.dom.innerHTML=l}return this}};var k=e.prototype;e.addMethods=function(l){Ext.apply(k,l)};k.on=k.addListener;k.un=k.removeListener;k.autoBoxAdjust=true;var i=/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,c;e.get=function(m){var l,p,o;if(!m){return null}if(typeof m=="string"){if(!(p=h.getElementById(m))){return null}if(a[m]&&a[m].el){l=a[m].el;l.dom=p}else{l=e.addToCache(new e(p))}return l}else{if(m.tagName){if(!(o=m.id)){o=Ext.id(m)}if(a[o]&&a[o].el){l=a[o].el;l.dom=m}else{l=e.addToCache(new e(m))}return l}else{if(m instanceof e){if(m!=c){if(Ext.isIE&&(m.id==undefined||m.id=="")){m.dom=m.dom}else{m.dom=h.getElementById(m.id)||m.dom}}return m}else{if(m.isComposite){return m}else{if(Ext.isArray(m)){return e.select(m)}else{if(m==h){if(!c){var n=function(){};n.prototype=e.prototype;c=new n();c.dom=h}return c}}}}}}return null};e.addToCache=function(l,m){m=m||l.id;a[m]={el:l,data:{},events:{}};return l};e.data=function(m,l,n){m=e.get(m);if(!m){return null}var o=a[m.id].data;if(arguments.length==2){return o[l]}else{return(o[l]=n)}};function j(){if(!Ext.enableGarbageCollector){clearInterval(e.collectorThreadId)}else{var l,n,q,p;for(l in a){p=a[l];if(p.skipGC){Ext.EventManager.removeFromSpecialCache(p.el);continue}n=p.el;q=n.dom;if(!q||!q.parentNode||(!q.offsetParent&&!h.getElementById(l))){if(Ext.enableListenerCollection){Ext.EventManager.removeAll(q)}delete a[l]}}if(Ext.isIE){var m={};for(l in a){m[l]=a[l]}a=Ext.elCache=m}}}e.collectorThreadId=setInterval(j,30000);var b=function(){};b.prototype=e.prototype;e.Flyweight=function(l){this.dom=l};e.Flyweight.prototype=new b();e.Flyweight.prototype.isFlyweight=true;e._flyweights={};e.fly=function(n,l){var m=null;l=l||"_global";if(n=Ext.getDom(n)){(e._flyweights[l]=e._flyweights[l]||new e.Flyweight()).dom=n;m=e._flyweights[l]}return m};Ext.get=e.get;Ext.fly=e.fly;var g=Ext.isStrict?{select:1}:{input:1,select:1,textarea:1};if(Ext.isIE||Ext.isGecko){g.button=1}})();Ext.Element.addMethods(function(){var d="parentNode",b="nextSibling",c="previousSibling",e=Ext.DomQuery,a=Ext.get;return{findParent:function(m,l,h){var j=this.dom,g=document.body,k=0,i;if(Ext.isGecko&&Object.prototype.toString.call(j)=="[object XULElement]"){return null}l=l||50;if(isNaN(l)){i=Ext.getDom(l);l=Number.MAX_VALUE}while(j&&j.nodeType==1&&k<l&&j!=g&&j!=i){if(e.is(j,m)){return h?a(j):j}k++;j=j.parentNode}return null},findParentNode:function(j,i,g){var h=Ext.fly(this.dom.parentNode,"_internal");return h?h.findParent(j,i,g):null},up:function(h,g){return this.findParentNode(h,g,true)},select:function(g){return Ext.Element.select(g,this.dom)},query:function(g){return e.select(g,this.dom)},child:function(g,h){var i=e.selectNode(g,this.dom);return h?i:a(i)},down:function(g,h){var i=e.selectNode(" > "+g,this.dom);return h?i:a(i)},parent:function(g,h){return this.matchNode(d,d,g,h)},next:function(g,h){return this.matchNode(b,b,g,h)},prev:function(g,h){return this.matchNode(c,c,g,h)},first:function(g,h){return this.matchNode(b,"firstChild",g,h)},last:function(g,h){return this.matchNode(c,"lastChild",g,h)},matchNode:function(h,k,g,i){var j=this.dom[k];while(j){if(j.nodeType==1&&(!g||e.is(j,g))){return !i?a(j):j}j=j[h]}return null}}}());Ext.Element.addMethods(function(){var c=Ext.getDom,a=Ext.get,b=Ext.DomHelper;return{appendChild:function(d){return a(d).appendTo(this)},appendTo:function(d){c(d).appendChild(this.dom);return this},insertBefore:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d);return this},insertAfter:function(d){(d=c(d)).parentNode.insertBefore(this.dom,d.nextSibling);return this},insertFirst:function(e,d){e=e||{};if(e.nodeType||e.dom||typeof e=="string"){e=c(e);this.dom.insertBefore(e,this.dom.firstChild);return !d?a(e):e}else{return this.createChild(e,this.dom.firstChild,d)}},replace:function(d){d=a(d);this.insertBefore(d);d.remove();return this},replaceWith:function(d){var e=this;if(d.nodeType||d.dom||typeof d=="string"){d=c(d);e.dom.parentNode.insertBefore(d,e.dom)}else{d=b.insertBefore(e.dom,d)}delete Ext.elCache[e.id];Ext.removeNode(e.dom);e.id=Ext.id(e.dom=d);Ext.Element.addToCache(e.isFlyweight?new Ext.Element(e.dom):e);return e},createChild:function(e,d,g){e=e||{tag:"div"};return d?b.insertBefore(d,e,g!==true):b[!this.dom.firstChild?"overwrite":"append"](this.dom,e,g!==true)},wrap:function(d,e){var g=b.insertBefore(this.dom,d||{tag:"div"},!e);g.dom?g.dom.appendChild(this.dom):g.appendChild(this.dom);return g},insertHtml:function(e,g,d){var h=b.insertHtml(e,this.dom,g);return d?Ext.get(h):h}}}());Ext.Element.addMethods(function(){var A=Ext.supports,h={},x=/(-[a-z])/gi,s=document.defaultView,D=/alpha\(opacity=(.*)\)/i,l=/^\s+|\s+$/g,B=Ext.Element,u=/\s+/,b=/\w/g,d="padding",c="margin",y="border",t="-left",q="-right",w="-top",o="-bottom",j="-width",r=Math,z="hidden",e="isClipped",k="overflow",n="overflow-x",m="overflow-y",C="originalClip",i={l:y+t+j,r:y+q+j,t:y+w+j,b:y+o+j},g={l:d+t,r:d+q,t:d+w,b:d+o},a={l:c+t,r:c+q,t:c+w,b:c+o},E=Ext.Element.data;function p(F,G){return G.charAt(1).toUpperCase()}function v(F){return h[F]||(h[F]=F=="float"?(A.cssFloat?"cssFloat":"styleFloat"):F.replace(x,p))}return{adjustWidth:function(F){var G=this;var H=(typeof F=="number");if(H&&G.autoBoxAdjust&&!G.isBorderBox()){F-=(G.getBorderWidth("lr")+G.getPadding("lr"))}return(H&&F<0)?0:F},adjustHeight:function(F){var G=this;var H=(typeof F=="number");if(H&&G.autoBoxAdjust&&!G.isBorderBox()){F-=(G.getBorderWidth("tb")+G.getPadding("tb"))}return(H&&F<0)?0:F},addClass:function(J){var K=this,I,F,H,G=[];if(!Ext.isArray(J)){if(typeof J=="string"&&!this.hasClass(J)){K.dom.className+=" "+J}}else{for(I=0,F=J.length;I<F;I++){H=J[I];if(typeof H=="string"&&(" "+K.dom.className+" ").indexOf(" "+H+" ")==-1){G.push(H)}}if(G.length){K.dom.className+=" "+G.join(" ")}}return K},removeClass:function(K){var L=this,J,G,F,I,H;if(!Ext.isArray(K)){K=[K]}if(L.dom&&L.dom.className){H=L.dom.className.replace(l,"").split(u);for(J=0,F=K.length;J<F;J++){I=K[J];if(typeof I=="string"){I=I.replace(l,"");G=H.indexOf(I);if(G!=-1){H.splice(G,1)}}}L.dom.className=H.join(" ")}return L},radioClass:function(I){var J=this.dom.parentNode.childNodes,G,H,F;I=Ext.isArray(I)?I:[I];for(H=0,F=J.length;H<F;H++){G=J[H];if(G&&G.nodeType==1){Ext.fly(G,"_internal").removeClass(I)}}return this.addClass(I)},toggleClass:function(F){return this.hasClass(F)?this.removeClass(F):this.addClass(F)},hasClass:function(F){return F&&(" "+this.dom.className+" ").indexOf(" "+F+" ")!=-1},replaceClass:function(G,F){return this.removeClass(G).addClass(F)},isStyle:function(F,G){return this.getStyle(F)==G},getStyle:function(){return s&&s.getComputedStyle?function(K){var I=this.dom,F,H,G,J;if(I==document){return null}K=v(K);G=(F=I.style[K])?F:(H=s.getComputedStyle(I,""))?H[K]:null;if(K=="marginRight"&&G!="0px"&&!A.correctRightMargin){J=I.style.display;I.style.display="inline-block";G=s.getComputedStyle(I,"").marginRight;I.style.display=J}if(K=="backgroundColor"&&G=="rgba(0, 0, 0, 0)"&&!A.correctTransparentColor){G="transparent"}return G}:function(J){var H=this.dom,F,G;if(H==document){return null}if(J=="opacity"){if(H.style.filter.match){if(F=H.style.filter.match(D)){var I=parseFloat(F[1]);if(!isNaN(I)){return I?I/100:0}}}return 1}J=v(J);return H.style[J]||((G=H.currentStyle)?G[J]:null)}}(),getColor:function(F,G,K){var I=this.getStyle(F),H=(typeof K!="undefined")?K:"#",J;if(!I||(/transparent|inherit/.test(I))){return G}if(/^r/.test(I)){Ext.each(I.slice(4,I.length-1).split(","),function(L){J=parseInt(L,10);H+=(J<16?"0":"")+J.toString(16)})}else{I=I.replace("#","");H+=I.length==3?I.replace(/^(\w)(\w)(\w)$/,"$1$1$2$2$3$3"):I}return(H.length>5?H.toLowerCase():G)},setStyle:function(I,H){var F,G;if(typeof I!="object"){F={};F[I]=H;I=F}for(G in I){H=I[G];G=="opacity"?this.setOpacity(H):this.dom.style[v(G)]=H}return this},setOpacity:function(G,F){var J=this,H=J.dom.style;if(!F||!J.anim){if(Ext.isIE9m){var I=G<1?"alpha(opacity="+G*100+")":"",K=H.filter.replace(D,"").replace(l,"");H.zoom=1;H.filter=K+(K.length>0?" ":"")+I}else{H.opacity=G}}else{J.anim({opacity:{to:G}},J.preanim(arguments,1),null,0.35,"easeIn")}return J},clearOpacity:function(){var F=this.dom.style;if(Ext.isIE9m){if(!Ext.isEmpty(F.filter)){F.filter=F.filter.replace(D,"").replace(l,"")}}else{F.opacity=F["-moz-opacity"]=F["-khtml-opacity"]=""}return this},getHeight:function(H){var G=this,J=G.dom,I=Ext.isIE9m&&G.isStyle("display","none"),F=r.max(J.offsetHeight,I?0:J.clientHeight)||0;F=!H?F:F-G.getBorderWidth("tb")-G.getPadding("tb");return F<0?0:F},getWidth:function(G){var H=this,J=H.dom,I=Ext.isIE9m&&H.isStyle("display","none"),F=r.max(J.offsetWidth,I?0:J.clientWidth)||0;F=!G?F:F-H.getBorderWidth("lr")-H.getPadding("lr");return F<0?0:F},setWidth:function(G,F){var H=this;G=H.adjustWidth(G);!F||!H.anim?H.dom.style.width=H.addUnits(G):H.anim({width:{to:G}},H.preanim(arguments,1));return H},setHeight:function(F,G){var H=this;F=H.adjustHeight(F);!G||!H.anim?H.dom.style.height=H.addUnits(F):H.anim({height:{to:F}},H.preanim(arguments,1));return H},getBorderWidth:function(F){return this.addStyles(F,i)},getPadding:function(F){return this.addStyles(F,g)},clip:function(){var F=this,G=F.dom;if(!E(G,e)){E(G,e,true);E(G,C,{o:F.getStyle(k),x:F.getStyle(n),y:F.getStyle(m)});F.setStyle(k,z);F.setStyle(n,z);F.setStyle(m,z)}return F},unclip:function(){var F=this,H=F.dom;if(E(H,e)){E(H,e,false);var G=E(H,C);if(G.o){F.setStyle(k,G.o)}if(G.x){F.setStyle(n,G.x)}if(G.y){F.setStyle(m,G.y)}}return F},addStyles:function(M,L){var J=0,K=M.match(b),I,H,G,F=K.length;for(G=0;G<F;G++){I=K[G];H=I&&parseInt(this.getStyle(L[I]),10);if(H){J+=r.abs(H)}}return J},margins:a}}());(function(){var a=Ext.lib.Dom,b="left",g="right",d="top",i="bottom",h="position",c="static",e="relative",j="auto",k="z-index";Ext.Element.addMethods({getX:function(){return a.getX(this.dom)},getY:function(){return a.getY(this.dom)},getXY:function(){return a.getXY(this.dom)},getOffsetsTo:function(l){var n=this.getXY(),m=Ext.fly(l,"_internal").getXY();return[n[0]-m[0],n[1]-m[1]]},setX:function(l,m){return this.setXY([l,this.getY()],this.animTest(arguments,m,1))},setY:function(m,l){return this.setXY([this.getX(),m],this.animTest(arguments,l,1))},setLeft:function(l){this.setStyle(b,this.addUnits(l));return this},setTop:function(l){this.setStyle(d,this.addUnits(l));return this},setRight:function(l){this.setStyle(g,this.addUnits(l));return this},setBottom:function(l){this.setStyle(i,this.addUnits(l));return this},setXY:function(n,l){var m=this;if(!l||!m.anim){a.setXY(m.dom,n)}else{m.anim({points:{to:n}},m.preanim(arguments,1),"motion")}return m},setLocation:function(l,n,m){return this.setXY([l,n],this.animTest(arguments,m,2))},moveTo:function(l,n,m){return this.setXY([l,n],this.animTest(arguments,m,2))},getLeft:function(l){return !l?this.getX():parseInt(this.getStyle(b),10)||0},getRight:function(l){var m=this;return !l?m.getX()+m.getWidth():(m.getLeft(true)+m.getWidth())||0},getTop:function(l){return !l?this.getY():parseInt(this.getStyle(d),10)||0},getBottom:function(l){var m=this;return !l?m.getY()+m.getHeight():(m.getTop(true)+m.getHeight())||0},position:function(p,o,l,n){var m=this;if(!p&&m.isStyle(h,c)){m.setStyle(h,e)}else{if(p){m.setStyle(h,p)}}if(o){m.setStyle(k,o)}if(l||n){m.setXY([l||false,n||false])}},clearPositioning:function(l){l=l||"";this.setStyle({left:l,right:l,top:l,bottom:l,"z-index":"",position:c});return this},getPositioning:function(){var m=this.getStyle(b);var n=this.getStyle(d);return{position:this.getStyle(h),left:m,right:m?"":this.getStyle(g),top:n,bottom:n?"":this.getStyle(i),"z-index":this.getStyle(k)}},setPositioning:function(l){var n=this,m=n.dom.style;n.setStyle(l);if(l.right==j){m.right=""}if(l.bottom==j){m.bottom=""}return n},translatePoints:function(m,u){u=isNaN(m[1])?u:m[1];m=isNaN(m[0])?m:m[0];var q=this,r=q.isStyle(h,e),s=q.getXY(),n=parseInt(q.getStyle(b),10),p=parseInt(q.getStyle(d),10);n=!isNaN(n)?n:(r?0:q.dom.offsetLeft);p=!isNaN(p)?p:(r?0:q.dom.offsetTop);return{left:(m-s[0]+n),top:(u-s[1]+p)}},animTest:function(m,l,n){return !!l&&this.preanim?this.preanim(m,n):false}})})();Ext.Element.addMethods({isScrollable:function(){var a=this.dom;return a.scrollHeight>a.clientHeight||a.scrollWidth>a.clientWidth},scrollTo:function(a,b){this.dom["scroll"+(/top/i.test(a)?"Top":"Left")]=b;return this},getScroll:function(){var i=this.dom,h=document,a=h.body,c=h.documentElement,b,g,e;if(i==h||i==a){if(Ext.isIE&&Ext.isStrict){b=c.scrollLeft;g=c.scrollTop}else{b=window.pageXOffset;g=window.pageYOffset}e={left:b||(a?a.scrollLeft:0),top:g||(a?a.scrollTop:0)}}else{e={left:i.scrollLeft,top:i.scrollTop}}return e}});Ext.Element.VISIBILITY=1;Ext.Element.DISPLAY=2;Ext.Element.OFFSETS=3;Ext.Element.ASCLASS=4;Ext.Element.visibilityCls="x-hide-nosize";Ext.Element.addMethods(function(){var e=Ext.Element,p="opacity",j="visibility",g="display",d="hidden",n="offsets",k="asclass",m="none",a="nosize",b="originalDisplay",c="visibilityMode",h="isVisible",i=e.data,l=function(r){var q=i(r,b);if(q===undefined){i(r,b,q="")}return q},o=function(r){var q=i(r,c);if(q===undefined){i(r,c,q=1)}return q};return{originalDisplay:"",visibilityMode:1,setVisibilityMode:function(q){i(this.dom,c,q);return this},animate:function(r,t,s,u,q){this.anim(r,{duration:t,callback:s,easing:u},q);return this},anim:function(t,u,r,w,s,q){r=r||"run";u=u||{};var v=this,x=Ext.lib.Anim[r](v.dom,t,(u.duration||w)||0.35,(u.easing||s)||"easeOut",function(){if(q){q.call(v)}if(u.callback){u.callback.call(u.scope||v,v,u)}},v);u.anim=x;return x},preanim:function(q,r){return !q[r]?false:(typeof q[r]=="object"?q[r]:{duration:q[r+1],callback:q[r+2],easing:q[r+3]})},isVisible:function(){var q=this,s=q.dom,r=i(s,h);if(typeof r=="boolean"){return r}r=!q.isStyle(j,d)&&!q.isStyle(g,m)&&!((o(s)==e.ASCLASS)&&q.hasClass(q.visibilityCls||e.visibilityCls));i(s,h,r);return r},setVisible:function(t,q){var w=this,r,y,x,v,u=w.dom,s=o(u);if(typeof q=="string"){switch(q){case g:s=e.DISPLAY;break;case j:s=e.VISIBILITY;break;case n:s=e.OFFSETS;break;case a:case k:s=e.ASCLASS;break}w.setVisibilityMode(s);q=false}if(!q||!w.anim){if(s==e.ASCLASS){w[t?"removeClass":"addClass"](w.visibilityCls||e.visibilityCls)}else{if(s==e.DISPLAY){return w.setDisplayed(t)}else{if(s==e.OFFSETS){if(!t){w.hideModeStyles={position:w.getStyle("position"),top:w.getStyle("top"),left:w.getStyle("left")};w.applyStyles({position:"absolute",top:"-10000px",left:"-10000px"})}else{w.applyStyles(w.hideModeStyles||{position:"",top:"",left:""});delete w.hideModeStyles}}else{w.fixDisplay();u.style.visibility=t?"visible":d}}}}else{if(t){w.setOpacity(0.01);w.setVisible(true)}w.anim({opacity:{to:(t?1:0)}},w.preanim(arguments,1),null,0.35,"easeIn",function(){t||w.setVisible(false).setOpacity(1)})}i(u,h,t);return w},hasMetrics:function(){var q=this.dom;return this.isVisible()||(o(q)==e.VISIBILITY)},toggle:function(q){var r=this;r.setVisible(!r.isVisible(),r.preanim(arguments,0));return r},setDisplayed:function(q){if(typeof q=="boolean"){q=q?l(this.dom):m}this.setStyle(g,q);return this},fixDisplay:function(){var q=this;if(q.isStyle(g,m)){q.setStyle(j,d);q.setStyle(g,l(this.dom));if(q.isStyle(g,m)){q.setStyle(g,"block")}}},hide:function(q){if(typeof q=="string"){this.setVisible(false,q);return this}this.setVisible(false,this.preanim(arguments,0));return this},show:function(q){if(typeof q=="string"){this.setVisible(true,q);return this}this.setVisible(true,this.preanim(arguments,0));return this}}}());(function(){var y=null,A=undefined,k=true,t=false,j="setX",h="setY",a="setXY",n="left",l="bottom",s="top",m="right",q="height",g="width",i="points",w="hidden",z="absolute",u="visible",e="motion",o="position",r="easeOut",d=new Ext.Element.Flyweight(),v={},x=function(B){return B||{}},p=function(B){d.dom=B;d.id=Ext.id(B);return d},c=function(B){if(!v[B]){v[B]=[]}return v[B]},b=function(C,B){v[C]=B};Ext.enableFx=k;Ext.Fx={switchStatements:function(C,D,B){return D.apply(this,B[C])},slideIn:function(H,E){E=x(E);var J=this,G=J.dom,M=G.style,O,B,L,D,C,M,I,N,K,F;H=H||"t";J.queueFx(E,function(){O=p(G).getXY();p(G).fixDisplay();B=p(G).getFxRestore();L={x:O[0],y:O[1],0:O[0],1:O[1],width:G.offsetWidth,height:G.offsetHeight};L.right=L.x+L.width;L.bottom=L.y+L.height;p(G).setWidth(L.width).setHeight(L.height);D=p(G).fxWrap(B.pos,E,w);M.visibility=u;M.position=z;function P(){p(G).fxUnwrap(D,B.pos,E);M.width=B.width;M.height=B.height;p(G).afterFx(E)}N={to:[L.x,L.y]};K={to:L.width};F={to:L.height};function Q(U,R,V,S,X,Z,ac,ab,aa,W,T){var Y={};p(U).setWidth(V).setHeight(S);if(p(U)[X]){p(U)[X](Z)}R[ac]=R[ab]="0";if(aa){Y.width=aa}if(W){Y.height=W}if(T){Y.points=T}return Y}I=p(G).switchStatements(H.toLowerCase(),Q,{t:[D,M,L.width,0,y,y,n,l,y,F,y],l:[D,M,0,L.height,y,y,m,s,K,y,y],r:[D,M,L.width,L.height,j,L.right,n,s,y,y,N],b:[D,M,L.width,L.height,h,L.bottom,n,s,y,F,N],tl:[D,M,0,0,y,y,m,l,K,F,N],bl:[D,M,0,0,h,L.y+L.height,m,s,K,F,N],br:[D,M,0,0,a,[L.right,L.bottom],n,s,K,F,N],tr:[D,M,0,0,j,L.x+L.width,n,l,K,F,N]});M.visibility=u;p(D).show();arguments.callee.anim=p(D).fxanim(I,E,e,0.5,r,P)});return J},slideOut:function(F,D){D=x(D);var H=this,E=H.dom,K=E.style,L=H.getXY(),C,B,I,J,G={to:0};F=F||"t";H.queueFx(D,function(){B=p(E).getFxRestore();I={x:L[0],y:L[1],0:L[0],1:L[1],width:E.offsetWidth,height:E.offsetHeight};I.right=I.x+I.width;I.bottom=I.y+I.height;p(E).setWidth(I.width).setHeight(I.height);C=p(E).fxWrap(B.pos,D,u);K.visibility=u;K.position=z;p(C).setWidth(I.width).setHeight(I.height);function M(){D.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).fxUnwrap(C,B.pos,D);K.width=B.width;K.height=B.height;p(E).afterFx(D)}function N(O,W,U,X,S,V,R,T,Q){var P={};O[W]=O[U]="0";P[X]=S;if(V){P[V]=R}if(T){P[T]=Q}return P}J=p(E).switchStatements(F.toLowerCase(),N,{t:[K,n,l,q,G],l:[K,m,s,g,G],r:[K,n,s,g,G,i,{to:[I.right,I.y]}],b:[K,n,s,q,G,i,{to:[I.x,I.bottom]}],tl:[K,m,l,g,G,q,G],bl:[K,m,s,g,G,q,G,i,{to:[I.x,I.bottom]}],br:[K,n,s,g,G,q,G,i,{to:[I.x+I.width,I.bottom]}],tr:[K,n,l,g,G,q,G,i,{to:[I.right,I.y]}]});arguments.callee.anim=p(C).fxanim(J,D,e,0.5,r,M)});return H},puff:function(H){H=x(H);var F=this,G=F.dom,C=G.style,D,B,E;F.queueFx(H,function(){D=p(G).getWidth();B=p(G).getHeight();p(G).clearOpacity();p(G).show();E=p(G).getFxRestore();function I(){H.useDisplay?p(G).setDisplayed(t):p(G).hide();p(G).clearOpacity();p(G).setPositioning(E.pos);C.width=E.width;C.height=E.height;C.fontSize="";p(G).afterFx(H)}arguments.callee.anim=p(G).fxanim({width:{to:p(G).adjustWidth(D*2)},height:{to:p(G).adjustHeight(B*2)},points:{by:[-D*0.5,-B*0.5]},opacity:{to:0},fontSize:{to:200,unit:"%"}},H,e,0.5,r,I)});return F},switchOff:function(F){F=x(F);var D=this,E=D.dom,B=E.style,C;D.queueFx(F,function(){p(E).clearOpacity();p(E).clip();C=p(E).getFxRestore();function G(){F.useDisplay?p(E).setDisplayed(t):p(E).hide();p(E).clearOpacity();p(E).setPositioning(C.pos);B.width=C.width;B.height=C.height;p(E).afterFx(F)}p(E).fxanim({opacity:{to:0.3}},y,y,0.1,y,function(){p(E).clearOpacity();(function(){p(E).fxanim({height:{to:1},points:{by:[0,p(E).getHeight()*0.5]}},F,e,0.3,"easeIn",G)}).defer(100)})});return D},highlight:function(D,H){H=x(H);var F=this,G=F.dom,B=H.attr||"backgroundColor",C={},E;F.queueFx(H,function(){p(G).clearOpacity();p(G).show();function I(){G.style[B]=E;p(G).afterFx(H)}E=G.style[B];C[B]={from:D||"ffff9c",to:H.endColor||p(G).getColor(B)||"ffffff"};arguments.callee.anim=p(G).fxanim(C,H,"color",1,"easeIn",I)});return F},frame:function(B,E,H){H=x(H);var D=this,G=D.dom,C,F;D.queueFx(H,function(){B=B||"#C3DAF9";if(B.length==6){B="#"+B}E=E||1;p(G).show();var L=p(G).getXY(),J={x:L[0],y:L[1],0:L[0],1:L[1],width:G.offsetWidth,height:G.offsetHeight},I=function(){C=p(document.body||document.documentElement).createChild({style:{position:z,"z-index":35000,border:"0px solid "+B}});return C.queueFx({},K)};arguments.callee.anim={isAnimated:true,stop:function(){E=0;C.stopFx()}};function K(){var M=Ext.isBorderBox?2:1;F=C.anim({top:{from:J.y,to:J.y-20},left:{from:J.x,to:J.x-20},borderWidth:{from:0,to:10},opacity:{from:1,to:0},height:{from:J.height,to:J.height+20*M},width:{from:J.width,to:J.width+20*M}},{duration:H.duration||1,callback:function(){C.remove();--E>0?I():p(G).afterFx(H)}});arguments.callee.anim={isAnimated:true,stop:function(){F.stop()}}}I()});return D},pause:function(D){var C=this.dom,B;this.queueFx({},function(){B=setTimeout(function(){p(C).afterFx({})},D*1000);arguments.callee.anim={isAnimated:true,stop:function(){clearTimeout(B);p(C).afterFx({})}}});return this},fadeIn:function(D){D=x(D);var B=this,C=B.dom,E=D.endOpacity||1;B.queueFx(D,function(){p(C).setOpacity(0);p(C).fixDisplay();C.style.visibility=u;arguments.callee.anim=p(C).fxanim({opacity:{to:E}},D,y,0.5,r,function(){if(E==1){p(C).clearOpacity()}p(C).afterFx(D)})});return B},fadeOut:function(E){E=x(E);var C=this,D=C.dom,B=D.style,F=E.endOpacity||0;C.queueFx(E,function(){arguments.callee.anim=p(D).fxanim({opacity:{to:F}},E,y,0.5,r,function(){if(F==0){Ext.Element.data(D,"visibilityMode")==Ext.Element.DISPLAY||E.useDisplay?B.display="none":B.visibility=w;p(D).clearOpacity()}p(D).afterFx(E)})});return C},scale:function(B,C,D){this.shift(Ext.apply({},D,{width:B,height:C}));return this},shift:function(D){D=x(D);var C=this.dom,B={};this.queueFx(D,function(){for(var E in D){if(D[E]!=A){B[E]={to:D[E]}}}B.width?B.width.to=p(C).adjustWidth(D.width):B;B.height?B.height.to=p(C).adjustWidth(D.height):B;if(B.x||B.y||B.xy){B.points=B.xy||{to:[B.x?B.x.to:p(C).getX(),B.y?B.y.to:p(C).getY()]}}arguments.callee.anim=p(C).fxanim(B,D,e,0.35,r,function(){p(C).afterFx(D)})});return this},ghost:function(E,C){C=x(C);var G=this,D=G.dom,J=D.style,H={opacity:{to:0},points:{}},K=H.points,B,I,F;E=E||"b";G.queueFx(C,function(){B=p(D).getFxRestore();I=p(D).getWidth();F=p(D).getHeight();function L(){C.useDisplay?p(D).setDisplayed(t):p(D).hide();p(D).clearOpacity();p(D).setPositioning(B.pos);J.width=B.width;J.height=B.height;p(D).afterFx(C)}K.by=p(D).switchStatements(E.toLowerCase(),function(N,M){return[N,M]},{t:[0,-F],l:[-I,0],r:[I,0],b:[0,F],tl:[-I,-F],bl:[-I,F],br:[I,F],tr:[I,-F]});arguments.callee.anim=p(D).fxanim(H,C,e,0.5,r,L)});return G},syncFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:k,stopFx:t});return B},sequenceFx:function(){var B=this;B.fxDefaults=Ext.apply(B.fxDefaults||{},{block:t,concurrent:t,stopFx:t});return B},nextFx:function(){var B=c(this.dom.id)[0];if(B){B.call(this)}},hasActiveFx:function(){return c(this.dom.id)[0]},stopFx:function(B){var C=this,E=C.dom.id;if(C.hasActiveFx()){var D=c(E)[0];if(D&&D.anim){if(D.anim.isAnimated){b(E,[D]);D.anim.stop(B!==undefined?B:k)}else{b(E,[])}}}return C},beforeFx:function(B){if(this.hasActiveFx()&&!B.concurrent){if(B.stopFx){this.stopFx();return k}return t}return k},hasFxBlock:function(){var B=c(this.dom.id);return B&&B[0]&&B[0].block},queueFx:function(E,B){var C=p(this.dom);if(!C.hasFxBlock()){Ext.applyIf(E,C.fxDefaults);if(!E.concurrent){var D=C.beforeFx(E);B.block=E.block;c(C.dom.id).push(B);if(D){C.nextFx()}}else{B.call(C)}}return C},fxWrap:function(H,F,D){var E=this.dom,C,B;if(!F.wrap||!(C=Ext.getDom(F.wrap))){if(F.fixPosition){B=p(E).getXY()}var G=document.createElement("div");G.style.visibility=D;C=E.parentNode.insertBefore(G,E);p(C).setPositioning(H);if(p(C).isStyle(o,"static")){p(C).position("relative")}p(E).clearPositioning("auto");p(C).clip();C.appendChild(E);if(B){p(C).setXY(B)}}return C},fxUnwrap:function(C,F,E){var D=this.dom;p(D).clearPositioning();p(D).setPositioning(F);if(!E.wrap){var B=p(C).dom.parentNode;B.insertBefore(D,C);p(C).remove()}},getFxRestore:function(){var B=this.dom.style;return{pos:this.getPositioning(),width:B.width,height:B.height}},afterFx:function(C){var B=this.dom,D=B.id;if(C.afterStyle){p(B).setStyle(C.afterStyle)}if(C.afterCls){p(B).addClass(C.afterCls)}if(C.remove==k){p(B).remove()}if(C.callback){C.callback.call(C.scope,p(B))}if(!C.concurrent){c(D).shift();p(B).nextFx()}},fxanim:function(E,F,C,G,D,B){C=C||"run";F=F||{};var H=Ext.lib.Anim[C](this.dom,E,(F.duration||G)||0.35,(F.easing||D)||r,B,this);F.anim=H;return H}};Ext.Fx.resize=Ext.Fx.scale;Ext.Element.addMethods(Ext.Fx)})();Ext.CompositeElementLite=function(b,a){this.elements=[];this.add(b,a);this.el=new Ext.Element.Flyweight()};Ext.CompositeElementLite.prototype={isComposite:true,getElement:function(a){var b=this.el;b.dom=a;b.id=a.id;return b},transformElement:function(a){return Ext.getDom(a)},getCount:function(){return this.elements.length},add:function(d,b){var e=this,g=e.elements;if(!d){return this}if(typeof d=="string"){d=Ext.Element.selectorFunction(d,b)}else{if(d.isComposite){d=d.elements}else{if(!Ext.isIterable(d)){d=[d]}}}for(var c=0,a=d.length;c<a;++c){g.push(e.transformElement(d[c]))}return e},invoke:function(g,b){var h=this,d=h.elements,a=d.length,j,c;for(c=0;c<a;c++){j=d[c];if(j){Ext.Element.prototype[g].apply(h.getElement(j),b)}}return h},item:function(b){var d=this,c=d.elements[b],a=null;if(c){a=d.getElement(c)}return a},addListener:function(b,j,h,g){var d=this.elements,a=d.length,c,k;for(c=0;c<a;c++){k=d[c];if(k){Ext.EventManager.on(k,b,j,h||k,g)}}return this},each:function(g,d){var h=this,c=h.elements,a=c.length,b,j;for(b=0;b<a;b++){j=c[b];if(j){j=this.getElement(j);if(g.call(d||j,j,h,b)===false){break}}}return h},fill:function(a){var b=this;b.elements=[];b.add(a);return b},filter:function(a){var b=[],d=this,c=Ext.isFunction(a)?a:function(e){return e.is(a)};d.each(function(h,e,g){if(c(h,g)!==false){b[b.length]=d.transformElement(h)}});d.elements=b;return d},indexOf:function(a){return this.elements.indexOf(this.transformElement(a))},replaceElement:function(e,c,a){var b=!isNaN(e)?e:this.indexOf(e),g;if(b>-1){c=Ext.getDom(c);if(a){g=this.elements[b];g.parentNode.insertBefore(c,g);Ext.removeNode(g)}this.elements.splice(b,1,c)}return this},clear:function(){this.elements=[]}};Ext.CompositeElementLite.prototype.on=Ext.CompositeElementLite.prototype.addListener;Ext.CompositeElementLite.importElementMethods=function(){var c,b=Ext.Element.prototype,a=Ext.CompositeElementLite.prototype;for(c in b){if(typeof b[c]=="function"){(function(d){a[d]=a[d]||function(){return this.invoke(d,arguments)}}).call(a,c)}}};Ext.CompositeElementLite.importElementMethods();if(Ext.DomQuery){Ext.Element.selectorFunction=Ext.DomQuery.select}Ext.Element.select=function(a,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;(function(){var b="beforerequest",e="requestcomplete",d="requestexception",h=undefined,c="load",i="POST",a="GET",g=window;Ext.data.Connection=function(j){Ext.apply(this,j);this.addEvents(b,e,d);Ext.data.Connection.superclass.constructor.call(this)};Ext.extend(Ext.data.Connection,Ext.util.Observable,{timeout:30000,autoAbort:false,disableCaching:true,disableCachingParam:"_dc",request:function(n){var s=this;if(s.fireEvent(b,s,n)){if(n.el){if(!Ext.isEmpty(n.indicatorText)){s.indicatorText='<div class="loading-indicator">'+n.indicatorText+"</div>"}if(s.indicatorText){Ext.getDom(n.el).innerHTML=s.indicatorText}n.success=(Ext.isFunction(n.success)?n.success:function(){}).createInterceptor(function(o){Ext.getDom(n.el).innerHTML=o.responseText})}var l=n.params,k=n.url||s.url,j,q={success:s.handleResponse,failure:s.handleFailure,scope:s,argument:{options:n},timeout:Ext.num(n.timeout,s.timeout)},m,t;if(Ext.isFunction(l)){l=l.call(n.scope||g,n)}l=Ext.urlEncode(s.extraParams,Ext.isObject(l)?Ext.urlEncode(l):l);if(Ext.isFunction(k)){k=k.call(n.scope||g,n)}if((m=Ext.getDom(n.form))){k=k||m.action;if(n.isUpload||(/multipart\/form-data/i.test(m.getAttribute("enctype")))){return s.doFormUpload.call(s,n,l,k)}t=Ext.lib.Ajax.serializeForm(m);l=l?(l+"&"+t):t}j=n.method||s.method||((l||n.xmlData||n.jsonData)?i:a);if(j===a&&(s.disableCaching&&n.disableCaching!==false)||n.disableCaching===true){var r=n.disableCachingParam||s.disableCachingParam;k=Ext.urlAppend(k,r+"="+(new Date().getTime()))}n.headers=Ext.applyIf(n.headers||{},s.defaultHeaders||{});if(n.autoAbort===true||s.autoAbort){s.abort()}if((j==a||n.xmlData||n.jsonData)&&l){k=Ext.urlAppend(k,l);l=""}return(s.transId=Ext.lib.Ajax.request(j,k,q,l,n))}else{return n.callback?n.callback.apply(n.scope,[n,h,h]):null}},isLoading:function(j){return j?Ext.lib.Ajax.isCallInProgress(j):!!this.transId},abort:function(j){if(j||this.isLoading()){Ext.lib.Ajax.abort(j||this.transId)}},handleResponse:function(j){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(e,this,j,k);if(k.success){k.success.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,true,j)}},handleFailure:function(j,l){this.transId=false;var k=j.argument.options;j.argument=k?k.argument:null;this.fireEvent(d,this,j,k,l);if(k.failure){k.failure.call(k.scope,j,k)}if(k.callback){k.callback.call(k.scope,k,false,j)}},doFormUpload:function(q,j,k){var l=Ext.id(),v=document,r=v.createElement("iframe"),m=Ext.getDom(q.form),u=[],t,p="multipart/form-data",n={target:m.target,method:m.method,encoding:m.encoding,enctype:m.enctype,action:m.action};Ext.fly(r).set({id:l,name:l,cls:"x-hidden",src:Ext.SSL_SECURE_URL});v.body.appendChild(r);if(Ext.isIE){document.frames[l].name=l}Ext.fly(m).set({target:l,method:i,enctype:p,encoding:p,action:k||n.action});Ext.iterate(Ext.urlDecode(j,false),function(w,o){t=v.createElement("input");Ext.fly(t).set({type:"hidden",value:o,name:w});m.appendChild(t);u.push(t)});function s(){var x=this,w={responseText:"",responseXML:null,argument:q.argument},A,z;try{A=r.contentWindow.document||r.contentDocument||g.frames[l].document;if(A){if(A.body){if(/textarea/i.test((z=A.body.firstChild||{}).tagName)){w.responseText=z.value}else{w.responseText=A.body.innerHTML}}w.responseXML=A.XMLDocument||A}}catch(y){}Ext.EventManager.removeListener(r,c,s,x);x.fireEvent(e,x,w,q);function o(D,C,B){if(Ext.isFunction(D)){D.apply(C,B)}}o(q.success,q.scope,[w,q]);o(q.callback,q.scope,[q,true,w]);if(!x.debugUploads){setTimeout(function(){Ext.removeNode(r)},100)}}Ext.EventManager.on(r,c,s,this);m.submit();Ext.fly(m).set(n);Ext.each(u,function(o){Ext.removeNode(o)})}})})();Ext.Ajax=new Ext.data.Connection({autoAbort:false,serializeForm:function(a){return Ext.lib.Ajax.serializeForm(a)}});Ext.util.JSON=new (function(){var useHasOwn=!!{}.hasOwnProperty,isNative=function(){var useNative=null;return function(){if(useNative===null){useNative=Ext.USE_NATIVE_JSON&&window.JSON&&JSON.toString()=="[object JSON]"}return useNative}}(),pad=function(n){return n<10?"0"+n:n},doDecode=function(json){return json?eval("("+json+")"):""},doEncode=function(o){if(!Ext.isDefined(o)||o===null){return"null"}else{if(Ext.isArray(o)){return encodeArray(o)}else{if(Ext.isDate(o)){return Ext.util.JSON.encodeDate(o)}else{if(Ext.isString(o)){return encodeString(o)}else{if(typeof o=="number"){return isFinite(o)?String(o):"null"}else{if(Ext.isBoolean(o)){return String(o)}else{var a=["{"],b,i,v;for(i in o){if(!o.getElementsByTagName){if(!useHasOwn||o.hasOwnProperty(i)){v=o[i];switch(typeof v){case"undefined":case"function":case"unknown":break;default:if(b){a.push(",")}a.push(doEncode(i),":",v===null?"null":doEncode(v));b=true}}}}a.push("}");return a.join("")}}}}}}},m={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},encodeString=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+'"'},encodeArray=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("")};this.encodeDate=function(o){return'"'+o.getFullYear()+"-"+pad(o.getMonth()+1)+"-"+pad(o.getDate())+"T"+pad(o.getHours())+":"+pad(o.getMinutes())+":"+pad(o.getSeconds())+'"'};this.encode=function(){var ec;return function(o){if(!ec){ec=isNative()?JSON.stringify:doEncode}return ec(o)}}();this.decode=function(){var dc;return function(json){if(!dc){dc=isNative()?JSON.parse:doDecode}return dc(json)}}()})();Ext.encode=Ext.util.JSON.encode;Ext.decode=Ext.util.JSON.decode;Ext.EventManager=function(){var z,p,j=false,l=Ext.isGecko||Ext.isWebKit||Ext.isSafari||Ext.isIE10p,o=Ext.lib.Event,q=Ext.lib.Dom,c=document,A=window,r="DOMContentLoaded",t="complete",g=/^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,u=[];function n(E){var H=false,D=0,C=u.length,F=false,G;if(E){if(E.getElementById||E.navigator){for(;D<C;++D){G=u[D];if(G.el===E){H=G.id;break}}if(!H){H=Ext.id(E);u.push({id:H,el:E});F=true}}else{H=Ext.id(E)}if(!Ext.elCache[H]){Ext.Element.addToCache(new Ext.Element(E),H);if(F){Ext.elCache[H].skipGC=true}}}return H}function m(E,G,J,F,D,L){E=Ext.getDom(E);var C=n(E),K=Ext.elCache[C].events,H;H=o.on(E,G,D);K[G]=K[G]||[];K[G].push([J,D,L,H,F]);if(E.addEventListener&&G=="mousewheel"){var I=["DOMMouseScroll",D,false];E.addEventListener.apply(E,I);Ext.EventManager.addListener(A,"unload",function(){E.removeEventListener.apply(E,I)})}if(E==c&&G=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.addListener(D)}}function d(){if(window!=top){return false}try{c.documentElement.doScroll("left")}catch(C){return false}b();return true}function B(C){if(Ext.isIE9m&&d()){return true}if(c.readyState==t){b();return true}j||(p=setTimeout(arguments.callee,2));return false}var k;function i(C){k||(k=Ext.query("style, link[rel=stylesheet]"));if(k.length==c.styleSheets.length){b();return true}j||(p=setTimeout(arguments.callee,2));return false}function y(C){c.removeEventListener(r,arguments.callee,false);i()}function b(C){if(!j){j=true;if(p){clearTimeout(p)}if(l){c.removeEventListener(r,b,false)}if(Ext.isIE9m&&B.bindIE){c.detachEvent("onreadystatechange",B)}o.un(A,"load",arguments.callee)}if(z&&!Ext.isReady){Ext.isReady=true;z.fire();z.listeners=[]}}function a(){z||(z=new Ext.util.Event());if(l){c.addEventListener(r,b,false)}if(Ext.isIE9m){if(!B()){B.bindIE=true;c.attachEvent("onreadystatechange",B)}}else{if(Ext.isOpera){(c.readyState==t&&i())||c.addEventListener(r,y,false)}else{if(Ext.isWebKit){B()}}}o.on(A,"load",b)}function x(C,D){return function(){var E=Ext.toArray(arguments);if(D.target==Ext.EventObject.setEvent(E[0]).target){C.apply(this,E)}}}function w(D,E,C){return function(F){C.delay(E.buffer,D,null,[new Ext.EventObjectImpl(F)])}}function s(G,F,C,E,D){return function(H){Ext.EventManager.removeListener(F,C,E,D);G(H)}}function e(D,E,C){return function(G){var F=new Ext.util.DelayedTask(D);if(!C.tasks){C.tasks=[]}C.tasks.push(F);F.delay(E.delay||10,D,null,[new Ext.EventObjectImpl(G)])}}function h(H,G,C,J,K){var D=(!C||typeof C=="boolean")?{}:C,E=Ext.getDom(H),F;J=J||D.fn;K=K||D.scope;if(!E){throw'Error listening for "'+G+'". Element "'+H+"\" doesn't exist."}function I(M){if(!Ext){return}M=Ext.EventObject.setEvent(M);var L;if(D.delegate){if(!(L=M.getTarget(D.delegate,E))){return}}else{L=M.target}if(D.stopEvent){M.stopEvent()}if(D.preventDefault){M.preventDefault()}if(D.stopPropagation){M.stopPropagation()}if(D.normalized===false){M=M.browserEvent}J.call(K||E,M,L,D)}if(D.target){I=x(I,D)}if(D.delay){I=e(I,D,J)}if(D.single){I=s(I,E,G,J,K)}if(D.buffer){F=new Ext.util.DelayedTask(I);I=w(I,D,F)}m(E,G,J,F,I,K);return I}var v={addListener:function(E,C,G,F,D){if(typeof C=="object"){var J=C,H,I;for(H in J){I=J[H];if(!g.test(H)){if(Ext.isFunction(I)){h(E,H,J,I,J.scope)}else{h(E,H,I)}}}}else{h(E,C,D,G,F)}},removeListener:function(E,I,M,N){E=Ext.getDom(E);var C=n(E),K=E&&(Ext.elCache[C].events)[I]||[],D,H,F,G,J,L;for(H=0,J=K.length;H<J;H++){if(Ext.isArray(L=K[H])&&L[0]==M&&(!N||L[2]==N)){if(L[4]){L[4].cancel()}G=M.tasks&&M.tasks.length;if(G){while(G--){M.tasks[G].cancel()}delete M.tasks}D=L[1];o.un(E,I,o.extAdapter?L[3]:D);if(D&&E.addEventListener&&I=="mousewheel"){E.removeEventListener("DOMMouseScroll",D,false)}if(D&&E==c&&I=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.removeListener(D)}K.splice(H,1);if(K.length===0){delete Ext.elCache[C].events[I]}for(G in Ext.elCache[C].events){return false}Ext.elCache[C].events={};return false}}},removeAll:function(E){E=Ext.getDom(E);var D=n(E),J=Ext.elCache[D]||{},M=J.events||{},I,H,K,F,L,G,C;for(F in M){if(M.hasOwnProperty(F)){I=M[F];for(H=0,K=I.length;H<K;H++){L=I[H];if(L[4]){L[4].cancel()}if(L[0].tasks&&(G=L[0].tasks.length)){while(G--){L[0].tasks[G].cancel()}delete L.tasks}C=L[1];o.un(E,F,o.extAdapter?L[3]:C);if(E.addEventListener&&C&&F=="mousewheel"){E.removeEventListener("DOMMouseScroll",C,false)}if(C&&E==c&&F=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.removeListener(C)}}}}if(Ext.elCache[D]){Ext.elCache[D].events={}}},getListeners:function(F,C){F=Ext.getDom(F);var H=n(F),D=Ext.elCache[H]||{},G=D.events||{},E=[];if(G&&G[C]){return G[C]}else{return null}},removeFromSpecialCache:function(E){var D=0,C=u.length;for(;D<C;++D){if(u[D].el==E){u.splice(D,1)}}},purgeElement:function(E,C,G){E=Ext.getDom(E);var D=n(E),J=Ext.elCache[D]||{},K=J.events||{},F,I,H;if(G){if(K&&K.hasOwnProperty(G)){I=K[G];for(F=0,H=I.length;F<H;F++){Ext.EventManager.removeListener(E,G,I[F][0])}}}else{Ext.EventManager.removeAll(E)}if(C&&E&&E.childNodes){for(F=0,H=E.childNodes.length;F<H;F++){Ext.EventManager.purgeElement(E.childNodes[F],C,G)}}},_unload:function(){var C;for(C in Ext.elCache){Ext.EventManager.removeAll(C)}delete Ext.elCache;delete Ext.Element._flyweights;var G,D,F,E=Ext.lib.Ajax;(typeof E.conn=="object")?D=E.conn:D={};for(F in D){G=D[F];if(G){E.abort({conn:G,tId:F})}}},onDocumentReady:function(E,D,C){if(Ext.isReady){z||(z=new Ext.util.Event());z.addListener(E,D,C);z.fire();z.listeners=[]}else{if(!z){a()}C=C||{};C.delay=C.delay||1;z.addListener(E,D,C)}},fireDocReady:b};v.on=v.addListener;v.un=v.removeListener;v.stoppedMouseDownEvent=new Ext.util.Event();return v}();Ext.onReady=Ext.EventManager.onDocumentReady;(function(){var a=function(){var c=document.body||document.getElementsByTagName("body")[0];if(!c){return false}var b=[];if(Ext.isIE){if(!Ext.isIE10p){b.push("ext-ie")}if(Ext.isIE6){b.push("ext-ie6")}else{if(Ext.isIE7){b.push("ext-ie7","ext-ie7m")}else{if(Ext.isIE8){b.push("ext-ie8","ext-ie8m")}else{if(Ext.isIE9){b.push("ext-ie9","ext-ie9m")}else{if(Ext.isIE10){b.push("ext-ie10")}}}}}}if(Ext.isGecko){if(Ext.isGecko2){b.push("ext-gecko2")}else{b.push("ext-gecko3")}}if(Ext.isOpera){b.push("ext-opera")}if(Ext.isWebKit){b.push("ext-webkit")}if(Ext.isSafari){b.push("ext-safari "+(Ext.isSafari2?"ext-safari2":(Ext.isSafari3?"ext-safari3":"ext-safari4")))}else{if(Ext.isChrome){b.push("ext-chrome")}}if(Ext.isMac){b.push("ext-mac")}if(Ext.isLinux){b.push("ext-linux")}if(Ext.isStrict||Ext.isBorderBox){var d=c.parentNode;if(d){if(!Ext.isStrict){Ext.fly(d,"_internal").addClass("x-quirks");if(Ext.isIE9m&&!Ext.isStrict){Ext.isIEQuirks=true}}Ext.fly(d,"_internal").addClass(((Ext.isStrict&&Ext.isIE)||(!Ext.enableForcedBoxModel&&!Ext.isIE))?" ext-strict":" ext-border-box")}}if(Ext.enableForcedBoxModel&&!Ext.isIE){Ext.isForcedBorderBox=true;b.push("ext-forced-border-box")}Ext.fly(c,"_internal").addClass(b);return true};if(!a()){Ext.onReady(a)}})();(function(){var b=Ext.apply(Ext.supports,{correctRightMargin:true,correctTransparentColor:true,cssFloat:true});var a=function(){var g=document.createElement("div"),e=document,c,d;g.innerHTML='<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';e.body.appendChild(g);d=g.lastChild;if((c=e.defaultView)){if(c.getComputedStyle(g.firstChild.firstChild,null).marginRight!="0px"){b.correctRightMargin=false}if(c.getComputedStyle(d,null).backgroundColor!="transparent"){b.correctTransparentColor=false}}b.cssFloat=!!d.style.cssFloat;e.body.removeChild(g)};if(Ext.isReady){a()}else{Ext.onReady(a)}})();Ext.EventObject=function(){var b=Ext.lib.Event,c=/(dbl)?click/,a={3:13,63234:37,63235:39,63232:38,63233:40,63276:33,63277:34,63272:46,63273:36,63275:35},d=Ext.isIE?{1:0,4:1,2:2}:{0:0,1:1,2:2};Ext.EventObjectImpl=function(g){if(g){this.setEvent(g.browserEvent||g)}};Ext.EventObjectImpl.prototype={setEvent:function(h){var g=this;if(h==g||(h&&h.browserEvent)){return h}g.browserEvent=h;if(h){g.button=h.button?d[h.button]:(h.which?h.which-1:-1);if(c.test(h.type)&&g.button==-1){g.button=0}g.type=h.type;g.shiftKey=h.shiftKey;g.ctrlKey=h.ctrlKey||h.metaKey||false;g.altKey=h.altKey;g.keyCode=h.keyCode;g.charCode=h.charCode;g.target=b.getTarget(h);g.xy=b.getXY(h)}else{g.button=-1;g.shiftKey=false;g.ctrlKey=false;g.altKey=false;g.keyCode=0;g.charCode=0;g.target=null;g.xy=[0,0]}return g},stopEvent:function(){var e=this;if(e.browserEvent){if(e.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(e)}b.stopEvent(e.browserEvent)}},preventDefault:function(){if(this.browserEvent){b.preventDefault(this.browserEvent)}},stopPropagation:function(){var e=this;if(e.browserEvent){if(e.browserEvent.type=="mousedown"){Ext.EventManager.stoppedMouseDownEvent.fire(e)}b.stopPropagation(e.browserEvent)}},getCharCode:function(){return this.charCode||this.keyCode},getKey:function(){return this.normalizeKey(this.keyCode||this.charCode)},normalizeKey:function(e){return Ext.isSafari?(a[e]||e):e},getPageX:function(){return this.xy[0]},getPageY:function(){return this.xy[1]},getXY:function(){return this.xy},getTarget:function(g,h,e){return g?Ext.fly(this.target).findParent(g,h,e):(e?Ext.get(this.target):this.target)},getRelatedTarget:function(){return this.browserEvent?b.getRelatedTarget(this.browserEvent):null},getWheelDelta:function(){var g=this.browserEvent;var h=0;if(g.wheelDelta){h=g.wheelDelta/120}else{if(g.detail){h=-g.detail/3}}return h},within:function(h,i,e){if(h){var g=this[i?"getRelatedTarget":"getTarget"]();return g&&((e?(g==Ext.getDom(h)):false)||Ext.fly(h).contains(g))}return false}};return new Ext.EventObjectImpl()}();Ext.Loader=Ext.apply({},{load:function(j,i,k,c){var k=k||this,g=document.getElementsByTagName("head")[0],b=document.createDocumentFragment(),a=j.length,h=0,e=this;var l=function(m){g.appendChild(e.buildScriptTag(j[m],d))};var d=function(){h++;if(a==h&&typeof i=="function"){i.call(k)}else{if(c===true){l(h)}}};if(c===true){l.call(this,0)}else{Ext.each(j,function(n,m){b.appendChild(this.buildScriptTag(n,d))},this);g.appendChild(b)}},buildScriptTag:function(b,c){var a=document.createElement("script");a.type="text/javascript";a.src=b;if(a.readyState){a.onreadystatechange=function(){if(a.readyState=="loaded"||a.readyState=="complete"){a.onreadystatechange=null;c()}}}else{a.onload=c}return a}});Ext.ns("Ext.grid","Ext.list","Ext.dd","Ext.tree","Ext.form","Ext.menu","Ext.state","Ext.layout.boxOverflow","Ext.app","Ext.ux","Ext.chart","Ext.direct","Ext.slider");Ext.apply(Ext,function(){var c=Ext,a=0,b=null;return{emptyFn:function(){},BLANK_IMAGE_URL:Ext.isIE6||Ext.isIE7||Ext.isAir?"http://www.extjs.com/s.gif":"data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",extendX:function(d,e){return Ext.extend(d,e(d.prototype))},getDoc:function(){return Ext.get(document)},num:function(e,d){e=Number(Ext.isEmpty(e)||Ext.isArray(e)||typeof e=="boolean"||(typeof e=="string"&&e.trim().length==0)?NaN:e);return isNaN(e)?d:e},value:function(g,d,e){return Ext.isEmpty(g,e)?d:g},escapeRe:function(d){return d.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")},sequence:function(h,d,g,e){h[d]=h[d].createSequence(g,e)},addBehaviors:function(i){if(!Ext.isReady){Ext.onReady(function(){Ext.addBehaviors(i)})}else{var e={},h,d,g;for(d in i){if((h=d.split("@"))[1]){g=h[0];if(!e[g]){e[g]=Ext.select(g)}e[g].on(h[1],i[d])}}e=null}},getScrollBarWidth:function(g){if(!Ext.isReady){return 0}if(g===true||b===null){var i=Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),h=i.child("div",true);var e=h.offsetWidth;i.setStyle("overflow",(Ext.isWebKit||Ext.isGecko)?"auto":"scroll");var d=h.offsetWidth;i.remove();b=e-d+2}return b},combine:function(){var g=arguments,e=g.length,j=[];for(var h=0;h<e;h++){var d=g[h];if(Ext.isArray(d)){j=j.concat(d)}else{if(d.length!==undefined&&!d.substr){j=j.concat(Array.prototype.slice.call(d,0))}else{j.push(d)}}}return j},copyTo:function(d,e,g){if(typeof g=="string"){g=g.split(/[,;\s]/)}Ext.each(g,function(h){if(e.hasOwnProperty(h)){d[h]=e[h]}},this);return d},destroy:function(){Ext.each(arguments,function(d){if(d){if(Ext.isArray(d)){this.destroy.apply(this,d)}else{if(typeof d.destroy=="function"){d.destroy()}else{if(d.dom){d.remove()}}}}},this)},destroyMembers:function(l,j,g,h){for(var k=1,e=arguments,d=e.length;k<d;k++){Ext.destroy(l[e[k]]);delete l[e[k]]}},clean:function(d){var e=[];Ext.each(d,function(g){if(!!g){e.push(g)}});return e},unique:function(d){var e=[],g={};Ext.each(d,function(h){if(!g[h]){e.push(h)}g[h]=true});return e},flatten:function(d){var g=[];function e(h){Ext.each(h,function(i){if(Ext.isArray(i)){e(i)}else{g.push(i)}});return g}return e(d)},min:function(d,e){var g=d[0];e=e||function(i,h){return i<h?-1:1};Ext.each(d,function(h){g=e(g,h)==-1?g:h});return g},max:function(d,e){var g=d[0];e=e||function(i,h){return i>h?1:-1};Ext.each(d,function(h){g=e(g,h)==1?g:h});return g},mean:function(d){return d.length>0?Ext.sum(d)/d.length:undefined},sum:function(d){var e=0;Ext.each(d,function(g){e+=g});return e},partition:function(d,e){var g=[[],[]];Ext.each(d,function(j,k,h){g[(e&&e(j,k,h))||(!e&&j)?0:1].push(j)});return g},invoke:function(d,e){var h=[],g=Array.prototype.slice.call(arguments,2);Ext.each(d,function(j,k){if(j&&typeof j[e]=="function"){h.push(j[e].apply(j,g))}else{h.push(undefined)}});return h},pluck:function(d,g){var e=[];Ext.each(d,function(h){e.push(h[g])});return e},zip:function(){var n=Ext.partition(arguments,function(i){return typeof i!="function"}),k=n[0],m=n[1][0],d=Ext.max(Ext.pluck(k,"length")),h=[];for(var l=0;l<d;l++){h[l]=[];if(m){h[l]=m.apply(m,Ext.pluck(k,l))}else{for(var g=0,e=k.length;g<e;g++){h[l].push(k[g][l])}}}return h},getCmp:function(d){return Ext.ComponentMgr.get(d)},useShims:c.isIE6||(c.isMac&&c.isGecko2),type:function(e){if(e===undefined||e===null){return false}if(e.htmlElement){return"element"}var d=typeof e;if(d=="object"&&e.nodeName){switch(e.nodeType){case 1:return"element";case 3:return(/\S/).test(e.nodeValue)?"textnode":"whitespace"}}if(d=="object"||d=="function"){switch(e.constructor){case Array:return"array";case RegExp:return"regexp";case Date:return"date"}if(typeof e.length=="number"&&typeof e.item=="function"){return"nodelist"}}return d},intercept:function(h,d,g,e){h[d]=h[d].createInterceptor(g,e)},callback:function(d,h,g,e){if(typeof d=="function"){if(e){d.defer(e,h,g||[])}else{d.apply(h,g||[])}}}}}());Ext.apply(Function.prototype,{createSequence:function(b,a){var c=this;return(typeof b!="function")?this:function(){var d=c.apply(this||window,arguments);b.apply(a||this||window,arguments);return d}}});Ext.applyIf(String,{escape:function(a){return a.replace(/('|\\)/g,"\\$1")},leftPad:function(d,b,c){var a=String(d);if(!c){c=" "}while(a.length<b){a=c+a}return a}});String.prototype.toggle=function(b,a){return this==b?a:b};String.prototype.trim=function(){var a=/^\s+|\s+$/g;return function(){return this.replace(a,"")}}();Date.prototype.getElapsed=function(a){return Math.abs((a||new Date()).getTime()-this.getTime())};Ext.applyIf(Number.prototype,{constrain:function(b,a){return Math.min(Math.max(this,b),a)}});Ext.lib.Dom.getRegion=function(a){return Ext.lib.Region.getRegion(a)};Ext.lib.Region=function(d,g,a,c){var e=this;e.top=d;e[1]=d;e.right=g;e.bottom=a;e.left=c;e[0]=c};Ext.lib.Region.prototype={contains:function(b){var a=this;return(b.left>=a.left&&b.right<=a.right&&b.top>=a.top&&b.bottom<=a.bottom)},getArea:function(){var a=this;return((a.bottom-a.top)*(a.right-a.left))},intersect:function(h){var g=this,d=Math.max(g.top,h.top),e=Math.min(g.right,h.right),a=Math.min(g.bottom,h.bottom),c=Math.max(g.left,h.left);if(a>=d&&e>=c){return new Ext.lib.Region(d,e,a,c)}},union:function(h){var g=this,d=Math.min(g.top,h.top),e=Math.max(g.right,h.right),a=Math.max(g.bottom,h.bottom),c=Math.min(g.left,h.left);return new Ext.lib.Region(d,e,a,c)},constrainTo:function(b){var a=this;a.top=a.top.constrain(b.top,b.bottom);a.bottom=a.bottom.constrain(b.top,b.bottom);a.left=a.left.constrain(b.left,b.right);a.right=a.right.constrain(b.left,b.right);return a},adjust:function(d,c,a,g){var e=this;e.top+=d;e.left+=c;e.right+=g;e.bottom+=a;return e}};Ext.lib.Region.getRegion=function(e){var h=Ext.lib.Dom.getXY(e),d=h[1],g=h[0]+e.offsetWidth,a=h[1]+e.offsetHeight,c=h[0];return new Ext.lib.Region(d,g,a,c)};Ext.lib.Point=function(a,c){if(Ext.isArray(a)){c=a[1];a=a[0]}var b=this;b.x=b.right=b.left=b[0]=a;b.y=b.top=b.bottom=b[1]=c};Ext.lib.Point.prototype=new Ext.lib.Region();Ext.apply(Ext.DomHelper,function(){var e,a="afterbegin",h="afterend",i="beforebegin",d="beforeend",b=/tag|children|cn|html$/i;function g(m,p,n,q,l,j){m=Ext.getDom(m);var k;if(e.useDom){k=c(p,null);if(j){m.appendChild(k)}else{(l=="firstChild"?m:m.parentNode).insertBefore(k,m[l]||m)}}else{k=Ext.DomHelper.insertHtml(q,m,Ext.DomHelper.createHtml(p))}return n?Ext.get(k,true):k}function c(j,r){var k,u=document,p,s,m,t;if(Ext.isArray(j)){k=u.createDocumentFragment();for(var q=0,n=j.length;q<n;q++){c(j[q],k)}}else{if(typeof j=="string"){k=u.createTextNode(j)}else{k=u.createElement(j.tag||"div");p=!!k.setAttribute;for(var s in j){if(!b.test(s)){m=j[s];if(s=="cls"){k.className=m}else{if(p){k.setAttribute(s,m)}else{k[s]=m}}}}Ext.DomHelper.applyStyles(k,j.style);if((t=j.children||j.cn)){c(t,k)}else{if(j.html){k.innerHTML=j.html}}}}if(r){r.appendChild(k)}return k}e={createTemplate:function(k){var j=Ext.DomHelper.createHtml(k);return new Ext.Template(j)},useDom:false,insertBefore:function(j,l,k){return g(j,l,k,i)},insertAfter:function(j,l,k){return g(j,l,k,h,"nextSibling")},insertFirst:function(j,l,k){return g(j,l,k,a,"firstChild")},append:function(j,l,k){return g(j,l,k,d,"",true)},createDom:c};return e}());Ext.apply(Ext.Template.prototype,{disableFormats:false,re:/\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,argsRe:/^\s*['"](.*)["']\s*$/,compileARe:/\\/g,compileBRe:/(\r\n|\n)/g,compileCRe:/'/g,applyTemplate:function(b){var g=this,a=g.disableFormats!==true,e=Ext.util.Format,c=g;if(g.compiled){return g.compiled(b)}function d(j,l,p,k){if(p&&a){if(p.substr(0,5)=="this."){return c.call(p.substr(5),b[l],b)}else{if(k){var o=g.argsRe;k=k.split(",");for(var n=0,h=k.length;n<h;n++){k[n]=k[n].replace(o,"$1")}k=[b[l]].concat(k)}else{k=[b[l]]}return e[p].apply(e,k)}}else{return b[l]!==undefined?b[l]:""}}return g.html.replace(g.re,d)},compile:function(){var me=this,fm=Ext.util.Format,useF=me.disableFormats!==true,sep=Ext.isGecko?"+":",",body;function fn(m,name,format,args){if(format&&useF){args=args?","+args:"";if(format.substr(0,5)!="this."){format="fm."+format+"("}else{format='this.call("'+format.substr(5)+'", ';args=", values"}}else{args="";format="(values['"+name+"'] == undefined ? '' : "}return"'"+sep+format+"values['"+name+"']"+args+")"+sep+"'"}if(Ext.isGecko){body="this.compiled = function(values){ return '"+me.html.replace(me.compileARe,"\\\\").replace(me.compileBRe,"\\n").replace(me.compileCRe,"\\'").replace(me.re,fn)+"';};"}else{body=["this.compiled = function(values){ return ['"];body.push(me.html.replace(me.compileARe,"\\\\").replace(me.compileBRe,"\\n").replace(me.compileCRe,"\\'").replace(me.re,fn));body.push("'].join('');};");body=body.join("")}eval(body);return me},call:function(c,b,a){return this[c](b,a)}});Ext.Template.prototype.apply=Ext.Template.prototype.applyTemplate;Ext.util.Functions={createInterceptor:function(c,b,a){var d=c;if(!Ext.isFunction(b)){return c}else{return function(){var g=this,e=arguments;b.target=g;b.method=c;return(b.apply(a||g||window,e)!==false)?c.apply(g||window,e):null}}},createDelegate:function(c,d,b,a){if(!Ext.isFunction(c)){return c}return function(){var g=b||arguments;if(a===true){g=Array.prototype.slice.call(arguments,0);g=g.concat(b)}else{if(Ext.isNumber(a)){g=Array.prototype.slice.call(arguments,0);var e=[a,0].concat(b);Array.prototype.splice.apply(g,e)}}return c.apply(d||window,g)}},defer:function(d,c,e,b,a){d=Ext.util.Functions.createDelegate(d,e,b,a);if(c>0){return setTimeout(d,c)}d();return 0},createSequence:function(c,b,a){if(!Ext.isFunction(b)){return c}else{return function(){var d=c.apply(this||window,arguments);b.apply(a||this||window,arguments);return d}}}};Ext.defer=Ext.util.Functions.defer;Ext.createInterceptor=Ext.util.Functions.createInterceptor;Ext.createSequence=Ext.util.Functions.createSequence;Ext.createDelegate=Ext.util.Functions.createDelegate;Ext.apply(Ext.util.Observable.prototype,function(){function a(j){var i=(this.methodEvents=this.methodEvents||{})[j],d,c,g,h=this;if(!i){this.methodEvents[j]=i={};i.originalFn=this[j];i.methodName=j;i.before=[];i.after=[];var b=function(l,k,e){if((c=l.apply(k||h,e))!==undefined){if(typeof c=="object"){if(c.returnValue!==undefined){d=c.returnValue}else{d=c}g=!!c.cancel}else{if(c===false){g=true}else{d=c}}}};this[j]=function(){var l=Array.prototype.slice.call(arguments,0),k;d=c=undefined;g=false;for(var m=0,e=i.before.length;m<e;m++){k=i.before[m];b(k.fn,k.scope,l);if(g){return d}}if((c=i.originalFn.apply(h,l))!==undefined){d=c}for(var m=0,e=i.after.length;m<e;m++){k=i.after[m];b(k.fn,k.scope,l);if(g){return d}}return d}}return i}return{beforeMethod:function(d,c,b){a.call(this,d).before.push({fn:c,scope:b})},afterMethod:function(d,c,b){a.call(this,d).after.push({fn:c,scope:b})},removeMethodListener:function(j,g,d){var h=this.getMethodEvent(j);for(var c=0,b=h.before.length;c<b;c++){if(h.before[c].fn==g&&h.before[c].scope==d){h.before.splice(c,1);return}}for(var c=0,b=h.after.length;c<b;c++){if(h.after[c].fn==g&&h.after[c].scope==d){h.after.splice(c,1);return}}},relayEvents:function(j,e){var h=this;function g(i){return function(){return h.fireEvent.apply(h,[i].concat(Array.prototype.slice.call(arguments,0)))}}for(var d=0,b=e.length;d<b;d++){var c=e[d];h.events[c]=h.events[c]||true;j.on(c,g(c),h)}},enableBubble:function(e){var g=this;if(!Ext.isEmpty(e)){e=Ext.isArray(e)?e:Array.prototype.slice.call(arguments,0);for(var d=0,b=e.length;d<b;d++){var c=e[d];c=c.toLowerCase();var h=g.events[c]||true;if(typeof h=="boolean"){h=new Ext.util.Event(g,c);g.events[c]=h}h.bubble=true}}}}}());Ext.util.Observable.capture=function(c,b,a){c.fireEvent=c.fireEvent.createInterceptor(b,a)};Ext.util.Observable.observeClass=function(b,a){if(b){if(!b.fireEvent){Ext.apply(b,new Ext.util.Observable());Ext.util.Observable.capture(b.prototype,b.fireEvent,b)}if(typeof a=="object"){b.on(a)}return b}};Ext.apply(Ext.EventManager,function(){var d,k,g,b,a=Ext.lib.Dom,j=/^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,c=Ext.EventManager._unload,i=0,h=0,e=Ext.isWebKit?Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1])>=525:!((Ext.isGecko&&!Ext.isWindows)||Ext.isOpera);return{_unload:function(){Ext.EventManager.un(window,"resize",this.fireWindowResize,this);c.call(Ext.EventManager)},doResizeEvent:function(){var m=a.getViewHeight(),l=a.getViewWidth();if(h!=m||i!=l){d.fire(i=l,h=m)}},onWindowResize:function(n,m,l){if(!d){d=new Ext.util.Event();k=new Ext.util.DelayedTask(this.doResizeEvent);Ext.EventManager.on(window,"resize",this.fireWindowResize,this)}d.addListener(n,m,l)},fireWindowResize:function(){if(d){k.delay(100)}},onTextResize:function(o,n,l){if(!g){g=new Ext.util.Event();var m=new Ext.Element(document.createElement("div"));m.dom.className="x-text-resize";m.dom.innerHTML="X";m.appendTo(document.body);b=m.dom.offsetHeight;setInterval(function(){if(m.dom.offsetHeight!=b){g.fire(b,b=m.dom.offsetHeight)}},this.textResizeInterval)}g.addListener(o,n,l)},removeResizeListener:function(m,l){if(d){d.removeListener(m,l)}},fireResize:function(){if(d){d.fire(a.getViewWidth(),a.getViewHeight())}},textResizeInterval:50,ieDeferSrc:false,getKeyEvent:function(){return e?"keydown":"keypress"},useKeydown:e}}());Ext.EventManager.on=Ext.EventManager.addListener;Ext.apply(Ext.EventObjectImpl.prototype,{BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,RETURN:13,SHIFT:16,CTRL:17,CONTROL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGEUP:33,PAGE_DOWN:34,PAGEDOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,isNavKeyPress:function(){var b=this,a=this.normalizeKey(b.keyCode);return(a>=33&&a<=40)||a==b.RETURN||a==b.TAB||a==b.ESC},isSpecialKey:function(){var a=this.normalizeKey(this.keyCode);return(this.type=="keypress"&&this.ctrlKey)||this.isNavKeyPress()||(a==this.BACKSPACE)||(a>=16&&a<=20)||(a>=44&&a<=46)},getPoint:function(){return new Ext.lib.Point(this.xy[0],this.xy[1])},hasModifier:function(){return((this.ctrlKey||this.altKey)||this.shiftKey)}});Ext.Element.addMethods({swallowEvent:function(a,b){var d=this;function c(g){g.stopPropagation();if(b){g.preventDefault()}}if(Ext.isArray(a)){Ext.each(a,function(g){d.on(g,c)});return d}d.on(a,c);return d},relayEvent:function(a,b){this.on(a,function(c){b.fireEvent(a,c)})},clean:function(b){var d=this,e=d.dom,g=e.firstChild,c=-1;if(Ext.Element.data(e,"isCleaned")&&b!==true){return d}while(g){var a=g.nextSibling;if(g.nodeType==3&&!(/\S/.test(g.nodeValue))){e.removeChild(g)}else{g.nodeIndex=++c}g=a}Ext.Element.data(e,"isCleaned",true);return d},load:function(){var a=this.getUpdater();a.update.apply(a,arguments);return this},getUpdater:function(){return this.updateManager||(this.updateManager=new Ext.Updater(this))},update:function(html,loadScripts,callback){if(!this.dom){return this}html=html||"";if(loadScripts!==true){this.dom.innerHTML=html;if(typeof callback=="function"){callback()}return this}var id=Ext.id(),dom=this.dom;html+='<span id="'+id+'"></span>';Ext.lib.Event.onAvailable(id,function(){var DOC=document,hd=DOC.getElementsByTagName("head")[0],re=/(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,srcRe=/\ssrc=([\'\"])(.*?)\1/i,typeRe=/\stype=([\'\"])(.*?)\1/i,match,attrs,srcMatch,typeMatch,el,s;while((match=re.exec(html))){attrs=match[1];srcMatch=attrs?attrs.match(srcRe):false;if(srcMatch&&srcMatch[2]){s=DOC.createElement("script");s.src=srcMatch[2];typeMatch=attrs.match(typeRe);if(typeMatch&&typeMatch[2]){s.type=typeMatch[2]}hd.appendChild(s)}else{if(match[2]&&match[2].length>0){if(window.execScript){window.execScript(match[2])}else{window.eval(match[2])}}}}el=DOC.getElementById(id);if(el){Ext.removeNode(el)}if(typeof callback=="function"){callback()}});dom.innerHTML=html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,"");return this},removeAllListeners:function(){this.removeAnchor();Ext.EventManager.removeAll(this.dom);return this},createProxy:function(a,e,d){a=(typeof a=="object")?a:{tag:"div",cls:a};var c=this,b=e?Ext.DomHelper.append(e,a,true):Ext.DomHelper.insertBefore(c.dom,a,true);if(d&&c.setBox&&c.getBox){b.setBox(c.getBox())}return b}});Ext.Element.prototype.getUpdateManager=Ext.Element.prototype.getUpdater;Ext.Element.addMethods({getAnchorXY:function(e,l,q){e=(e||"tl").toLowerCase();q=q||{};var k=this,b=k.dom==document.body||k.dom==document,n=q.width||b?Ext.lib.Dom.getViewWidth():k.getWidth(),i=q.height||b?Ext.lib.Dom.getViewHeight():k.getHeight(),p,a=Math.round,c=k.getXY(),m=k.getScroll(),j=b?m.left:!l?c[0]:0,g=b?m.top:!l?c[1]:0,d={c:[a(n*0.5),a(i*0.5)],t:[a(n*0.5),0],l:[0,a(i*0.5)],r:[n,a(i*0.5)],b:[a(n*0.5),i],tl:[0,0],bl:[0,i],br:[n,i],tr:[n,0]};p=d[e];return[p[0]+j,p[1]+g]},anchorTo:function(b,h,c,a,k,l){var i=this,e=i.dom,j=!Ext.isEmpty(k),d=function(){Ext.fly(e).alignTo(b,h,c,a);Ext.callback(l,Ext.fly(e))},g=this.getAnchor();this.removeAnchor();Ext.apply(g,{fn:d,scroll:j});Ext.EventManager.onWindowResize(d,null);if(j){Ext.EventManager.on(window,"scroll",d,null,{buffer:!isNaN(k)?k:50})}d.call(i);return i},removeAnchor:function(){var b=this,a=this.getAnchor();if(a&&a.fn){Ext.EventManager.removeResizeListener(a.fn);if(a.scroll){Ext.EventManager.un(window,"scroll",a.fn)}delete a.fn}return b},getAnchor:function(){var b=Ext.Element.data,c=this.dom;if(!c){return}var a=b(c,"_anchor");if(!a){a=b(c,"_anchor",{})}return a},getAlignToXY:function(g,A,B){g=Ext.get(g);if(!g||!g.dom){throw"Element.alignToXY with an element that doesn't exist"}B=B||[0,0];A=(!A||A=="?"?"tl-bl?":(!(/-/).test(A)&&A!==""?"tl-"+A:A||"tl-bl")).toLowerCase();var K=this,H=K.dom,M,L,n,l,s,F,v,t=Ext.lib.Dom.getViewWidth()-10,G=Ext.lib.Dom.getViewHeight()-10,b,i,j,k,u,z,N=document,J=N.documentElement,q=N.body,E=(J.scrollLeft||q.scrollLeft||0)+5,D=(J.scrollTop||q.scrollTop||0)+5,I=false,e="",a="",C=A.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!C){throw"Element.alignTo with an invalid alignment "+A}e=C[1];a=C[2];I=!!C[3];M=K.getAnchorXY(e,true);L=g.getAnchorXY(a,false);n=L[0]-M[0]+B[0];l=L[1]-M[1]+B[1];if(I){s=K.getWidth();F=K.getHeight();v=g.getRegion();b=e.charAt(0);i=e.charAt(e.length-1);j=a.charAt(0);k=a.charAt(a.length-1);u=((b=="t"&&j=="b")||(b=="b"&&j=="t"));z=((i=="r"&&k=="l")||(i=="l"&&k=="r"));if(n+s>t+E){n=z?v.left-s:t+E-s}if(n<E){n=z?v.right:E}if(l+F>G+D){l=u?v.top-F:G+D-F}if(l<D){l=u?v.bottom:D}}return[n,l]},alignTo:function(c,a,e,b){var d=this;return d.setXY(d.getAlignToXY(c,a,e),d.preanim&&!!b?d.preanim(arguments,3):false)},adjustForConstraints:function(c,a,b){return this.getConstrainToXY(a||document,false,b,c)||c},getConstrainToXY:function(b,a,c,e){var d={top:0,left:0,bottom:0,right:0};return function(i,A,l,n){i=Ext.get(i);l=l?Ext.applyIf(l,d):d;var z,D,v=0,u=0;if(i.dom==document.body||i.dom==document){z=Ext.lib.Dom.getViewWidth();D=Ext.lib.Dom.getViewHeight()}else{z=i.dom.clientWidth;D=i.dom.clientHeight;if(!A){var t=i.getXY();v=t[0];u=t[1]}}var r=i.getScroll();v+=l.left+r.left;u+=l.top+r.top;z-=l.right;D-=l.bottom;var B=v+z,g=u+D,j=n||(!A?this.getXY():[this.getLeft(true),this.getTop(true)]),p=j[0],o=j[1],k=this.getConstrainOffset(),q=this.dom.offsetWidth+k,C=this.dom.offsetHeight+k;var m=false;if((p+q)>B){p=B-q;m=true}if((o+C)>g){o=g-C;m=true}if(p<v){p=v;m=true}if(o<u){o=u;m=true}return m?[p,o]:false}}(),getConstrainOffset:function(){return 0},getCenterXY:function(){return this.getAlignToXY(document,"c-c")},center:function(a){return this.alignTo(a||document,"c-c")}});Ext.Element.addMethods({select:function(a,b){return Ext.Element.select(a,b,this.dom)}});Ext.apply(Ext.Element.prototype,function(){var c=Ext.getDom,a=Ext.get,b=Ext.DomHelper;return{insertSibling:function(i,g,h){var j=this,e,d=(g||"before").toLowerCase()=="after",k;if(Ext.isArray(i)){k=j;Ext.each(i,function(l){e=Ext.fly(k,"_internal").insertSibling(l,g,h);if(d){k=e}});return e}i=i||{};if(i.nodeType||i.dom){e=j.dom.parentNode.insertBefore(c(i),d?j.dom.nextSibling:j.dom);if(!h){e=a(e)}}else{if(d&&!j.dom.nextSibling){e=b.append(j.dom.parentNode,i,!h)}else{e=b[d?"insertAfter":"insertBefore"](j.dom,i,!h)}}return e}}}());Ext.Element.boxMarkup='<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>';Ext.Element.addMethods(function(){var a="_internal",b=/(\d+\.?\d+)px/;return{applyStyles:function(c){Ext.DomHelper.applyStyles(this.dom,c);return this},getStyles:function(){var c={};Ext.each(arguments,function(d){c[d]=this.getStyle(d)},this);return c},setOverflow:function(c){var d=this.dom;if(c=="auto"&&Ext.isMac&&Ext.isGecko2){d.style.overflow="hidden";(function(){d.style.overflow="auto"}).defer(1)}else{d.style.overflow=c}},boxWrap:function(c){c=c||"x-box";var d=Ext.get(this.insertHtml("beforeBegin","<div class='"+c+"'>"+String.format(Ext.Element.boxMarkup,c)+"</div>"));Ext.DomQuery.selectNode("."+c+"-mc",d.dom).appendChild(this.dom);return d},setSize:function(e,c,d){var g=this;if(typeof e=="object"){c=e.height;e=e.width}e=g.adjustWidth(e);c=g.adjustHeight(c);if(!d||!g.anim){g.dom.style.width=g.addUnits(e);g.dom.style.height=g.addUnits(c)}else{g.anim({width:{to:e},height:{to:c}},g.preanim(arguments,2))}return g},getComputedHeight:function(){var d=this,c=Math.max(d.dom.offsetHeight,d.dom.clientHeight);if(!c){c=parseFloat(d.getStyle("height"))||0;if(!d.isBorderBox()){c+=d.getFrameWidth("tb")}}return c},getComputedWidth:function(){var c=Math.max(this.dom.offsetWidth,this.dom.clientWidth);if(!c){c=parseFloat(this.getStyle("width"))||0;if(!this.isBorderBox()){c+=this.getFrameWidth("lr")}}return c},getFrameWidth:function(d,c){return c&&this.isBorderBox()?0:(this.getPadding(d)+this.getBorderWidth(d))},addClassOnOver:function(c){this.hover(function(){Ext.fly(this,a).addClass(c)},function(){Ext.fly(this,a).removeClass(c)});return this},addClassOnFocus:function(c){this.on("focus",function(){Ext.fly(this,a).addClass(c)},this.dom);this.on("blur",function(){Ext.fly(this,a).removeClass(c)},this.dom);return this},addClassOnClick:function(c){var d=this.dom;this.on("mousedown",function(){Ext.fly(d,a).addClass(c);var g=Ext.getDoc(),e=function(){Ext.fly(d,a).removeClass(c);g.removeListener("mouseup",e)};g.on("mouseup",e)});return this},getViewSize:function(){var g=document,h=this.dom,c=(h==g||h==g.body);if(c){var e=Ext.lib.Dom;return{width:e.getViewWidth(),height:e.getViewHeight()}}else{return{width:h.clientWidth,height:h.clientHeight}}},getStyleSize:function(){var j=this,c,i,l=document,m=this.dom,e=(m==l||m==l.body),g=m.style;if(e){var k=Ext.lib.Dom;return{width:k.getViewWidth(),height:k.getViewHeight()}}if(g.width&&g.width!="auto"){c=parseFloat(g.width);if(j.isBorderBox()){c-=j.getFrameWidth("lr")}}if(g.height&&g.height!="auto"){i=parseFloat(g.height);if(j.isBorderBox()){i-=j.getFrameWidth("tb")}}return{width:c||j.getWidth(true),height:i||j.getHeight(true)}},getSize:function(c){return{width:this.getWidth(c),height:this.getHeight(c)}},repaint:function(){var c=this.dom;this.addClass("x-repaint");setTimeout(function(){Ext.fly(c).removeClass("x-repaint")},1);return this},unselectable:function(){this.dom.unselectable="on";return this.swallowEvent("selectstart",true).addClass("x-unselectable")},getMargins:function(d){var e=this,c,g={t:"top",l:"left",r:"right",b:"bottom"},h={};if(!d){for(c in e.margins){h[g[c]]=parseFloat(e.getStyle(e.margins[c]))||0}return h}else{return e.addStyles.call(e,d,e.margins)}}}}());Ext.Element.addMethods({setBox:function(e,g,b){var d=this,a=e.width,c=e.height;if((g&&!d.autoBoxAdjust)&&!d.isBorderBox()){a-=(d.getBorderWidth("lr")+d.getPadding("lr"));c-=(d.getBorderWidth("tb")+d.getPadding("tb"))}d.setBounds(e.x,e.y,a,c,d.animTest.call(d,arguments,b,2));return d},getBox:function(j,p){var m=this,v,e,o,d=m.getBorderWidth,q=m.getPadding,g,a,u,n;if(!p){v=m.getXY()}else{e=parseInt(m.getStyle("left"),10)||0;o=parseInt(m.getStyle("top"),10)||0;v=[e,o]}var c=m.dom,s=c.offsetWidth,i=c.offsetHeight,k;if(!j){k={x:v[0],y:v[1],0:v[0],1:v[1],width:s,height:i}}else{g=d.call(m,"l")+q.call(m,"l");a=d.call(m,"r")+q.call(m,"r");u=d.call(m,"t")+q.call(m,"t");n=d.call(m,"b")+q.call(m,"b");k={x:v[0]+g,y:v[1]+u,0:v[0]+g,1:v[1]+u,width:s-(g+a),height:i-(u+n)}}k.right=k.x+k.width;k.bottom=k.y+k.height;return k},move:function(j,b,c){var g=this,m=g.getXY(),k=m[0],i=m[1],d=[k-b,i],l=[k+b,i],h=[k,i-b],a=[k,i+b],e={l:d,left:d,r:l,right:l,t:h,top:h,up:h,b:a,bottom:a,down:a};j=j.toLowerCase();g.moveTo(e[j][0],e[j][1],g.animTest.call(g,arguments,c,2))},setLeftTop:function(d,c){var b=this,a=b.dom.style;a.left=b.addUnits(d);a.top=b.addUnits(c);return b},getRegion:function(){return Ext.lib.Dom.getRegion(this.dom)},setBounds:function(b,g,d,a,c){var e=this;if(!c||!e.anim){e.setSize(d,a);e.setLocation(b,g)}else{e.anim({points:{to:[b,g]},width:{to:e.adjustWidth(d)},height:{to:e.adjustHeight(a)}},e.preanim(arguments,4),"motion")}return e},setRegion:function(b,a){return this.setBounds(b.left,b.top,b.right-b.left,b.bottom-b.top,this.animTest.call(this,arguments,a,1))}});Ext.Element.addMethods({scrollTo:function(b,d,a){var e=/top/i.test(b),c=this,g=c.dom,h;if(!a||!c.anim){h="scroll"+(e?"Top":"Left");g[h]=d}else{h="scroll"+(e?"Left":"Top");c.anim({scroll:{to:e?[g[h],d]:[d,g[h]]}},c.preanim(arguments,2),"scroll")}return c},scrollIntoView:function(e,i){var p=Ext.getDom(e)||Ext.getBody().dom,h=this.dom,g=this.getOffsetsTo(p),k=g[0]+p.scrollLeft,u=g[1]+p.scrollTop,q=u+h.offsetHeight,d=k+h.offsetWidth,a=p.clientHeight,m=parseInt(p.scrollTop,10),s=parseInt(p.scrollLeft,10),j=m+a,n=s+p.clientWidth;if(h.offsetHeight>a||u<m){p.scrollTop=u}else{if(q>j){p.scrollTop=q-a}}p.scrollTop=p.scrollTop;if(i!==false){if(h.offsetWidth>p.clientWidth||k<s){p.scrollLeft=k}else{if(d>n){p.scrollLeft=d-p.clientWidth}}p.scrollLeft=p.scrollLeft}return this},scrollChildIntoView:function(b,a){Ext.fly(b,"_scrollChildIntoView").scrollIntoView(this,a)},scroll:function(m,b,d){if(!this.isScrollable()){return false}var e=this.dom,g=e.scrollLeft,p=e.scrollTop,n=e.scrollWidth,k=e.scrollHeight,i=e.clientWidth,a=e.clientHeight,c=false,o,j={l:Math.min(g+b,n-i),r:o=Math.max(g-b,0),t:Math.max(p-b,0),b:Math.min(p+b,k-a)};j.d=j.b;j.u=j.t;m=m.substr(0,1);if((o=j[m])>-1){c=true;this.scrollTo(m=="l"||m=="r"?"left":"top",o,this.preanim(arguments,2))}return c}});Ext.Element.addMethods(function(){var d="visibility",b="display",a="hidden",h="none",c="x-masked",g="x-masked-relative",e=Ext.Element.data;return{isVisible:function(i){var j=!this.isStyle(d,a)&&!this.isStyle(b,h),k=this.dom.parentNode;if(i!==true||!j){return j}while(k&&!(/^body/i.test(k.tagName))){if(!Ext.fly(k,"_isVisible").isVisible()){return false}k=k.parentNode}return true},isDisplayed:function(){return !this.isStyle(b,h)},enableDisplayMode:function(i){this.setVisibilityMode(Ext.Element.DISPLAY);if(!Ext.isEmpty(i)){e(this.dom,"originalDisplay",i)}return this},mask:function(j,n){var p=this,l=p.dom,o=Ext.DomHelper,m="ext-el-mask-msg",i,q;if(!/^body/i.test(l.tagName)&&p.getStyle("position")=="static"){p.addClass(g)}if(i=e(l,"maskMsg")){i.remove()}if(i=e(l,"mask")){i.remove()}q=o.append(l,{cls:"ext-el-mask"},true);e(l,"mask",q);p.addClass(c);q.setDisplayed(true);if(typeof j=="string"){var k=o.append(l,{cls:m,cn:{tag:"div"}},true);e(l,"maskMsg",k);k.dom.className=n?m+" "+n:m;k.dom.firstChild.innerHTML=j;k.setDisplayed(true);k.center(p)}if(Ext.isIE&&!(Ext.isIE7&&Ext.isStrict)&&p.getStyle("height")=="auto"){q.setSize(undefined,p.getHeight())}return q},unmask:function(){var k=this,l=k.dom,i=e(l,"mask"),j=e(l,"maskMsg");if(i){if(j){j.remove();e(l,"maskMsg",undefined)}i.remove();e(l,"mask",undefined);k.removeClass([c,g])}},isMasked:function(){var i=e(this.dom,"mask");return i&&i.isVisible()},createShim:function(){var i=document.createElement("iframe"),j;i.frameBorder="0";i.className="ext-shim";i.src=Ext.SSL_SECURE_URL;j=Ext.get(this.dom.parentNode.insertBefore(i,this.dom));j.autoBoxAdjust=false;return j}}}());Ext.Element.addMethods({addKeyListener:function(b,d,c){var a;if(typeof b!="object"||Ext.isArray(b)){a={key:b,fn:d,scope:c}}else{a={key:b.key,shift:b.shift,ctrl:b.ctrl,alt:b.alt,fn:d,scope:c}}return new Ext.KeyMap(this,a)},addKeyMap:function(a){return new Ext.KeyMap(this,a)}});Ext.CompositeElementLite.importElementMethods();Ext.apply(Ext.CompositeElementLite.prototype,{addElements:function(c,a){if(!c){return this}if(typeof c=="string"){c=Ext.Element.selectorFunction(c,a)}var b=this.elements;Ext.each(c,function(d){b.push(Ext.get(d))});return this},first:function(){return this.item(0)},last:function(){return this.item(this.getCount()-1)},contains:function(a){return this.indexOf(a)!=-1},removeElement:function(d,e){var c=this,a=this.elements,b;Ext.each(d,function(g){if((b=(a[g]||a[g=c.indexOf(g)]))){if(e){if(b.dom){b.remove()}else{Ext.removeNode(b)}}a.splice(g,1)}});return this}});Ext.CompositeElement=Ext.extend(Ext.CompositeElementLite,{constructor:function(b,a){this.elements=[];this.add(b,a)},getElement:function(a){return a},transformElement:function(a){return Ext.get(a)}});Ext.Element.select=function(a,d,b){var c;if(typeof a=="string"){c=Ext.Element.selectorFunction(a,b)}else{if(a.length!==undefined){c=a}else{throw"Invalid selector"}}return(d===true)?new Ext.CompositeElement(c):new Ext.CompositeElementLite(c)};Ext.select=Ext.Element.select;Ext.UpdateManager=Ext.Updater=Ext.extend(Ext.util.Observable,function(){var b="beforeupdate",d="update",c="failure";function a(h){var i=this;i.transaction=null;if(h.argument.form&&h.argument.reset){try{h.argument.form.reset()}catch(j){}}if(i.loadScripts){i.renderer.render(i.el,h,i,g.createDelegate(i,[h]))}else{i.renderer.render(i.el,h,i);g.call(i,h)}}function g(h,i,j){this.fireEvent(i||d,this.el,h);if(Ext.isFunction(h.argument.callback)){h.argument.callback.call(h.argument.scope,this.el,Ext.isEmpty(j)?true:false,h,h.argument.options)}}function e(h){g.call(this,h,c,!!(this.transaction=null))}return{constructor:function(i,h){var j=this;i=Ext.get(i);if(!h&&i.updateManager){return i.updateManager}j.el=i;j.defaultUrl=null;j.addEvents(b,d,c);Ext.apply(j,Ext.Updater.defaults);j.transaction=null;j.refreshDelegate=j.refresh.createDelegate(j);j.updateDelegate=j.update.createDelegate(j);j.formUpdateDelegate=(j.formUpdate||function(){}).createDelegate(j);j.renderer=j.renderer||j.getDefaultRenderer();Ext.Updater.superclass.constructor.call(j)},setRenderer:function(h){this.renderer=h},getRenderer:function(){return this.renderer},getDefaultRenderer:function(){return new Ext.Updater.BasicRenderer()},setDefaultUrl:function(h){this.defaultUrl=h},getEl:function(){return this.el},update:function(i,n,p,l){var k=this,h,j;if(k.fireEvent(b,k.el,i,n)!==false){if(Ext.isObject(i)){h=i;i=h.url;n=n||h.params;p=p||h.callback;l=l||h.discardUrl;j=h.scope;if(!Ext.isEmpty(h.nocache)){k.disableCaching=h.nocache}if(!Ext.isEmpty(h.text)){k.indicatorText='<div class="loading-indicator">'+h.text+"</div>"}if(!Ext.isEmpty(h.scripts)){k.loadScripts=h.scripts}if(!Ext.isEmpty(h.timeout)){k.timeout=h.timeout}}k.showLoading();if(!l){k.defaultUrl=i}if(Ext.isFunction(i)){i=i.call(k)}var m=Ext.apply({},{url:i,params:(Ext.isFunction(n)&&j)?n.createDelegate(j):n,success:a,failure:e,scope:k,callback:undefined,timeout:(k.timeout*1000),disableCaching:k.disableCaching,argument:{options:h,url:i,form:null,callback:p,scope:j||window,params:n}},h);k.transaction=Ext.Ajax.request(m)}},formUpdate:function(k,h,j,l){var i=this;if(i.fireEvent(b,i.el,k,h)!==false){if(Ext.isFunction(h)){h=h.call(i)}k=Ext.getDom(k);i.transaction=Ext.Ajax.request({form:k,url:h,success:a,failure:e,scope:i,timeout:(i.timeout*1000),argument:{url:h,form:k,callback:l,reset:j}});i.showLoading.defer(1,i)}},startAutoRefresh:function(i,j,l,m,h){var k=this;if(h){k.update(j||k.defaultUrl,l,m,true)}if(k.autoRefreshProcId){clearInterval(k.autoRefreshProcId)}k.autoRefreshProcId=setInterval(k.update.createDelegate(k,[j||k.defaultUrl,l,m,true]),i*1000)},stopAutoRefresh:function(){if(this.autoRefreshProcId){clearInterval(this.autoRefreshProcId);delete this.autoRefreshProcId}},isAutoRefreshing:function(){return !!this.autoRefreshProcId},showLoading:function(){if(this.showLoadIndicator){this.el.dom.innerHTML=this.indicatorText}},abort:function(){if(this.transaction){Ext.Ajax.abort(this.transaction)}},isUpdating:function(){return this.transaction?Ext.Ajax.isLoading(this.transaction):false},refresh:function(h){if(this.defaultUrl){this.update(this.defaultUrl,null,h,true)}}}}());Ext.Updater.defaults={timeout:30,disableCaching:false,showLoadIndicator:true,indicatorText:'<div class="loading-indicator">Loading...</div>',loadScripts:false,sslBlankUrl:Ext.SSL_SECURE_URL};Ext.Updater.updateElement=function(d,c,e,b){var a=Ext.get(d).getUpdater();Ext.apply(a,b);a.update(c,e,b?b.callback:null)};Ext.Updater.BasicRenderer=function(){};Ext.Updater.BasicRenderer.prototype={render:function(c,a,b,d){c.update(a.responseText,b.loadScripts,d)}};(function(){Date.useStrict=false;function b(d){var c=Array.prototype.slice.call(arguments,1);return d.replace(/\{(\d+)\}/g,function(e,g){return c[g]})}Date.formatCodeToRegex=function(d,c){var e=Date.parseCodes[d];if(e){e=typeof e=="function"?e():e;Date.parseCodes[d]=e}return e?Ext.applyIf({c:e.c?b(e.c,c||"{0}"):e.c},e):{g:0,c:null,s:Ext.escapeRe(d)}};var a=Date.formatCodeToRegex;Ext.apply(Date,{parseFunctions:{"M$":function(d,c){var e=new RegExp("\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/");var g=(d||"").match(e);return g?new Date(((g[1]||"")+g[2])*1):null}},parseRegexes:[],formatFunctions:{"M$":function(){return"\\/Date("+this.getTime()+")\\/"}},y2kYear:50,MILLI:"ms",SECOND:"s",MINUTE:"mi",HOUR:"h",DAY:"d",MONTH:"mo",YEAR:"y",defaults:{},dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],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},getShortMonthName:function(c){return Date.monthNames[c].substring(0,3)},getShortDayName:function(c){return Date.dayNames[c].substring(0,3)},getMonthNumber:function(c){return Date.monthNumbers[c.substring(0,1).toUpperCase()+c.substring(1,3).toLowerCase()]},formatContainsHourInfo:(function(){var d=/(\\.)/g,c=/([gGhHisucUOPZ]|M\$)/;return function(e){return c.test(e.replace(d,""))}})(),formatCodes:{d:"String.leftPad(this.getDate(), 2, '0')",D:"Date.getShortDayName(this.getDay())",j:"this.getDate()",l:"Date.dayNames[this.getDay()]",N:"(this.getDay() ? this.getDay() : 7)",S:"this.getSuffix()",w:"this.getDay()",z:"this.getDayOfYear()",W:"String.leftPad(this.getWeekOfYear(), 2, '0')",F:"Date.monthNames[this.getMonth()]",m:"String.leftPad(this.getMonth() + 1, 2, '0')",M:"Date.getShortMonthName(this.getMonth())",n:"(this.getMonth() + 1)",t:"this.getDaysInMonth()",L:"(this.isLeapYear() ? 1 : 0)",o:"(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",Y:"String.leftPad(this.getFullYear(), 4, '0')",y:"('' + this.getFullYear()).substring(2, 4)",a:"(this.getHours() < 12 ? 'am' : 'pm')",A:"(this.getHours() < 12 ? 'AM' : 'PM')",g:"((this.getHours() % 12) ? this.getHours() % 12 : 12)",G:"this.getHours()",h:"String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",H:"String.leftPad(this.getHours(), 2, '0')",i:"String.leftPad(this.getMinutes(), 2, '0')",s:"String.leftPad(this.getSeconds(), 2, '0')",u:"String.leftPad(this.getMilliseconds(), 3, '0')",O:"this.getGMTOffset()",P:"this.getGMTOffset(true)",T:"this.getTimezone()",Z:"(this.getTimezoneOffset() * -60)",c:function(){for(var k="Y-m-dTH:i:sP",h=[],g=0,d=k.length;g<d;++g){var j=k.charAt(g);h.push(j=="T"?"'T'":Date.getFormatCode(j))}return h.join(" + ")},U:"Math.round(this.getTime() / 1000)"},isValid:function(o,c,n,k,g,j,e){k=k||0;g=g||0;j=j||0;e=e||0;var l=new Date(o<100?100:o,c-1,n,k,g,j,e).add(Date.YEAR,o<100?o-100:0);return o==l.getFullYear()&&c==l.getMonth()+1&&n==l.getDate()&&k==l.getHours()&&g==l.getMinutes()&&j==l.getSeconds()&&e==l.getMilliseconds()},parseDate:function(d,g,c){var e=Date.parseFunctions;if(e[g]==null){Date.createParser(g)}return e[g](d,Ext.isDefined(c)?c:Date.useStrict)},getFormatCode:function(d){var c=Date.formatCodes[d];if(c){c=typeof c=="function"?c():c;Date.formatCodes[d]=c}return c||("'"+String.escape(d)+"'")},createFormat:function(h){var g=[],c=false,e="";for(var d=0;d<h.length;++d){e=h.charAt(d);if(!c&&e=="\\"){c=true}else{if(c){c=false;g.push("'"+String.escape(e)+"'")}else{g.push(Date.getFormatCode(e))}}}Date.formatFunctions[h]=new Function("return "+g.join("+"))},createParser:function(){var c=["var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,","def = Date.defaults,","results = String(input).match(Date.parseRegexes[{0}]);","if(results){","{1}","if(u != null){","v = new Date(u * 1000);","}else{","dt = (new Date()).clearTime();","y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));","m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));","d = Ext.num(d, Ext.num(def.d, dt.getDate()));","h = Ext.num(h, Ext.num(def.h, dt.getHours()));","i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));","s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));","ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));","if(z >= 0 && y >= 0){","v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);","v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);","}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){","v = null;","}else{","v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);","}","}","}","if(v){","if(zz != null){","v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);","}else if(o){","v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));","}","}","return v;"].join("\n");return function(m){var e=Date.parseRegexes.length,o=1,g=[],l=[],k=false,d="",j=0,h,n;for(;j<m.length;++j){d=m.charAt(j);if(!k&&d=="\\"){k=true}else{if(k){k=false;l.push(String.escape(d))}else{h=a(d,o);o+=h.g;l.push(h.s);if(h.g&&h.c){if(h.calcLast){n=h.c}else{g.push(h.c)}}}}}if(n){g.push(n)}Date.parseRegexes[e]=new RegExp("^"+l.join("")+"$","i");Date.parseFunctions[m]=new Function("input","strict",b(c,e,g.join("")))}}(),parseCodes:{d:{g:1,c:"d = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},j:{g:1,c:"d = parseInt(results[{0}], 10);\n",s:"(\\d{1,2})"},D:function(){for(var c=[],d=0;d<7;c.push(Date.getShortDayName(d)),++d){}return{g:0,c:null,s:"(?:"+c.join("|")+")"}},l:function(){return{g:0,c:null,s:"(?:"+Date.dayNames.join("|")+")"}},N:{g:0,c:null,s:"[1-7]"},S:{g:0,c:null,s:"(?:st|nd|rd|th)"},w:{g:0,c:null,s:"[0-6]"},z:{g:1,c:"z = parseInt(results[{0}], 10);\n",s:"(\\d{1,3})"},W:{g:0,c:null,s:"(?:\\d{2})"},F:function(){return{g:1,c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",s:"("+Date.monthNames.join("|")+")"}},M:function(){for(var c=[],d=0;d<12;c.push(Date.getShortMonthName(d)),++d){}return Ext.applyIf({s:"("+c.join("|")+")"},a("F"))},m:{g:1,c:"m = parseInt(results[{0}], 10) - 1;\n",s:"(\\d{2})"},n:{g:1,c:"m = parseInt(results[{0}], 10) - 1;\n",s:"(\\d{1,2})"},t:{g:0,c:null,s:"(?:\\d{2})"},L:{g:0,c:null,s:"(?:1|0)"},o:function(){return a("Y")},Y:{g:1,c:"y = parseInt(results[{0}], 10);\n",s:"(\\d{4})"},y:{g:1,c:"var ty = parseInt(results[{0}], 10);\ny = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"},a:function(){return a("A")},A:{calcLast:true,g:1,c:"if (/(am)/i.test(results[{0}])) {\nif (!h || h == 12) { h = 0; }\n} else { if (!h || h < 12) { h = (h || 0) + 12; }}",s:"(AM|PM|am|pm)"},g:function(){return a("G")},G:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{1,2})"},h:function(){return a("H")},H:{g:1,c:"h = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},i:{g:1,c:"i = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},s:{g:1,c:"s = parseInt(results[{0}], 10);\n",s:"(\\d{2})"},u:{g:1,c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",s:"(\\d+)"},O:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),","mn = o.substring(3,5) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{4})"},P:{g:1,c:["o = results[{0}];","var sn = o.substring(0,1),","hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),","mn = o.substring(4,6) % 60;","o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"].join("\n"),s:"([+-]\\d{2}:\\d{2})"},T:{g:0,c:null,s:"[A-Z]{1,4}"},Z:{g:1,c:"zz = results[{0}] * 1;\nzz = (-43200 <= zz && zz <= 50400)? zz : null;\n",s:"([+-]?\\d{1,5})"},c:function(){var e=[],c=[a("Y",1),a("m",2),a("d",3),a("h",4),a("i",5),a("s",6),{c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},{c:["if(results[8]) {","if(results[8] == 'Z'){","zz = 0;","}else if (results[8].indexOf(':') > -1){",a("P",8).c,"}else{",a("O",8).c,"}","}"].join("\n")}];for(var g=0,d=c.length;g<d;++g){e.push(c[g].c)}return{g:1,c:e.join(""),s:[c[0].s,"(?:","-",c[1].s,"(?:","-",c[2].s,"(?:","(?:T| )?",c[3].s,":",c[4].s,"(?::",c[5].s,")?","(?:(?:\\.|,)(\\d+))?","(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",")?",")?",")?"].join("")}},U:{g:1,c:"u = parseInt(results[{0}], 10);\n",s:"(-?\\d+)"}}})}());Ext.apply(Date.prototype,{dateFormat:function(a){if(Date.formatFunctions[a]==null){Date.createFormat(a)}return Date.formatFunctions[a].call(this)},getTimezone:function(){return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/,"$1$2").replace(/[^A-Z]/g,"")},getGMTOffset:function(a){return(this.getTimezoneOffset()>0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+(a?":":"")+String.leftPad(Math.abs(this.getTimezoneOffset()%60),2,"0")},getDayOfYear:function(){var b=0,e=this.clone(),a=this.getMonth(),c;for(c=0,e.setDate(1),e.setMonth(0);c<a;e.setMonth(++c)){b+=e.getDaysInMonth()}return b+this.getDate()-1},getWeekOfYear:function(){var a=86400000,b=7*a;return function(){var d=Date.UTC(this.getFullYear(),this.getMonth(),this.getDate()+3)/a,c=Math.floor(d/7),e=new Date(c*b).getUTCFullYear();return c-Math.floor(Date.UTC(e,0,7)/b)+1}}(),isLeapYear:function(){var a=this.getFullYear();return !!((a&3)==0&&(a%100||(a%400==0&&a)))},getFirstDayOfMonth:function(){var a=(this.getDay()-(this.getDate()-1))%7;return(a<0)?(a+7):a},getLastDayOfMonth:function(){return this.getLastDateOfMonth().getDay()},getFirstDateOfMonth:function(){return new Date(this.getFullYear(),this.getMonth(),1)},getLastDateOfMonth:function(){return new Date(this.getFullYear(),this.getMonth(),this.getDaysInMonth())},getDaysInMonth:function(){var a=[31,28,31,30,31,30,31,31,30,31,30,31];return function(){var b=this.getMonth();return b==1&&this.isLeapYear()?29:a[b]}}(),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"}},clone:function(){return new Date(this.getTime())},isDST:function(){return new Date(this.getFullYear(),0,1).getTimezoneOffset()!=this.getTimezoneOffset()},clearTime:function(g){if(g){return this.clone().clearTime()}var b=this.getDate();this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);if(this.getDate()!=b){for(var a=1,e=this.add(Date.HOUR,a);e.getDate()!=b;a++,e=this.add(Date.HOUR,a)){}this.setDate(b);this.setHours(e.getHours())}return this},add:function(b,c){var e=this.clone();if(!b||c===0){return e}switch(b.toLowerCase()){case Date.MILLI:e.setMilliseconds(this.getMilliseconds()+c);break;case Date.SECOND:e.setSeconds(this.getSeconds()+c);break;case Date.MINUTE:e.setMinutes(this.getMinutes()+c);break;case Date.HOUR:e.setHours(this.getHours()+c);break;case Date.DAY:e.setDate(this.getDate()+c);break;case Date.MONTH:var a=this.getDate();if(a>28){a=Math.min(a,this.getFirstDateOfMonth().add("mo",c).getLastDateOfMonth().getDate())}e.setDate(a);e.setMonth(this.getMonth()+c);break;case Date.YEAR:e.setFullYear(this.getFullYear()+c);break}return e},between:function(c,a){var b=this.getTime();return c.getTime()<=b&&b<=a.getTime()}});Date.prototype.format=Date.prototype.dateFormat;if(Ext.isSafari&&(navigator.userAgent.match(/WebKit\/(\d+)/)[1]||NaN)<420){Ext.apply(Date.prototype,{_xMonth:Date.prototype.setMonth,_xDate:Date.prototype.setDate,setMonth:function(a){if(a<=-1){var d=Math.ceil(-a),c=Math.ceil(d/12),b=(d%12)?12-d%12:0;this.setFullYear(this.getFullYear()-c);return this._xMonth(b)}else{return this._xMonth(a)}},setDate:function(a){return this.setTime(this.getTime()-(this.getDate()-a)*86400000)}})}Ext.util.MixedCollection=function(b,a){this.items=[];this.map={};this.keys=[];this.length=0;this.addEvents("clear","add","replace","remove","sort");this.allowFunctions=b===true;if(a){this.getKey=a}Ext.util.MixedCollection.superclass.constructor.call(this)};Ext.extend(Ext.util.MixedCollection,Ext.util.Observable,{allowFunctions:false,add:function(b,c){if(arguments.length==1){c=arguments[0];b=this.getKey(c)}if(typeof b!="undefined"&&b!==null){var a=this.map[b];if(typeof a!="undefined"){return this.replace(b,c)}this.map[b]=c}this.length++;this.items.push(c);this.keys.push(b);this.fireEvent("add",this.length-1,c,b);return c},getKey:function(a){return a.id},replace:function(c,d){if(arguments.length==1){d=arguments[0];c=this.getKey(d)}var a=this.map[c];if(typeof c=="undefined"||c===null||typeof a=="undefined"){return this.add(c,d)}var b=this.indexOfKey(c);this.items[b]=d;this.map[c]=d;this.fireEvent("replace",c,a,d);return d},addAll:function(e){if(arguments.length>1||Ext.isArray(e)){var b=arguments.length>1?arguments:e;for(var d=0,a=b.length;d<a;d++){this.add(b[d])}}else{for(var c in e){if(this.allowFunctions||typeof e[c]!="function"){this.add(c,e[c])}}}},each:function(e,d){var b=[].concat(this.items);for(var c=0,a=b.length;c<a;c++){if(e.call(d||b[c],b[c],c,a)===false){break}}},eachKey:function(d,c){for(var b=0,a=this.keys.length;b<a;b++){d.call(c||window,this.keys[b],this.items[b],b,a)}},find:function(d,c){for(var b=0,a=this.items.length;b<a;b++){if(d.call(c||window,this.items[b],this.keys[b])){return this.items[b]}}return null},insert:function(a,b,c){if(arguments.length==2){c=arguments[1];b=this.getKey(c)}if(this.containsKey(b)){this.suspendEvents();this.removeKey(b);this.resumeEvents()}if(a>=this.length){return this.add(b,c)}this.length++;this.items.splice(a,0,c);if(typeof b!="undefined"&&b!==null){this.map[b]=c}this.keys.splice(a,0,b);this.fireEvent("add",a,c,b);return c},remove:function(a){return this.removeAt(this.indexOf(a))},removeAt:function(a){if(a<this.length&&a>=0){this.length--;var c=this.items[a];this.items.splice(a,1);var b=this.keys[a];if(typeof b!="undefined"){delete this.map[b]}this.keys.splice(a,1);this.fireEvent("remove",c,b);return c}return false},removeKey:function(a){return this.removeAt(this.indexOfKey(a))},getCount:function(){return this.length},indexOf:function(a){return this.items.indexOf(a)},indexOfKey:function(a){return this.keys.indexOf(a)},item:function(b){var a=this.map[b],c=a!==undefined?a:(typeof b=="number")?this.items[b]:undefined;return typeof c!="function"||this.allowFunctions?c:null},itemAt:function(a){return this.items[a]},key:function(a){return this.map[a]},contains:function(a){return this.indexOf(a)!=-1},containsKey:function(a){return typeof this.map[a]!="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(k,a,j){var d,e,b=String(a).toUpperCase()=="DESC"?-1:1,h=[],l=this.keys,g=this.items;j=j||function(i,c){return i-c};for(d=0,e=g.length;d<e;d++){h[h.length]={key:l[d],value:g[d],index:d}}h.sort(function(i,c){var m=j(i[k],c[k])*b;if(m===0){m=(i.index<c.index?-1:1)}return m});for(d=0,e=h.length;d<e;d++){g[d]=h[d].value;l[d]=h[d].key}this.fireEvent("sort",this)},sort:function(a,b){this._sort("value",a,b)},reorder:function(d){this.suspendEvents();var b=this.items,c=0,g=b.length,a=[],e=[],h;for(h in d){a[d[h]]=b[h]}for(c=0;c<g;c++){if(d[c]==undefined){e.push(b[c])}}for(c=0;c<g;c++){if(a[c]==undefined){a[c]=e.shift()}}this.clear();this.addAll(a);this.resumeEvents();this.fireEvent("sort",this)},keySort:function(a,b){this._sort("key",a,b||function(d,c){var g=String(d).toUpperCase(),e=String(c).toUpperCase();return g>e?1:(g<e?-1:0)})},getRange:function(e,a){var b=this.items;if(b.length<1){return[]}e=e||0;a=Math.min(typeof a=="undefined"?this.length-1:a,this.length-1);var c,d=[];if(e<=a){for(c=e;c<=a;c++){d[d.length]=b[c]}}else{for(c=e;c>=a;c--){d[d.length]=b[c]}}return d},filter:function(c,b,d,a){if(Ext.isEmpty(b,false)){return this.clone()}b=this.createValueMatcher(b,d,a);return this.filterBy(function(e){return e&&b.test(e[c])})},filterBy:function(g,e){var h=new Ext.util.MixedCollection();h.getKey=this.getKey;var b=this.keys,d=this.items;for(var c=0,a=d.length;c<a;c++){if(g.call(e||this,d[c],b[c])){h.add(b[c],d[c])}}return h},findIndex:function(c,b,e,d,a){if(Ext.isEmpty(b,false)){return -1}b=this.createValueMatcher(b,d,a);return this.findIndexBy(function(g){return g&&b.test(g[c])},null,e)},findIndexBy:function(g,e,h){var b=this.keys,d=this.items;for(var c=(h||0),a=d.length;c<a;c++){if(g.call(e||this,d[c],b[c])){return c}}return -1},createValueMatcher:function(c,e,a,b){if(!c.exec){var d=Ext.escapeRe;c=String(c);if(e===true){c=d(c)}else{c="^"+d(c);if(b===true){c+="$"}}c=new RegExp(c,a?"":"i")}return c},clone:function(){var e=new Ext.util.MixedCollection();var b=this.keys,d=this.items;for(var c=0,a=d.length;c<a;c++){e.add(b[c],d[c])}e.getKey=this.getKey;return e}});Ext.util.MixedCollection.prototype.get=Ext.util.MixedCollection.prototype.item;Ext.AbstractManager=Ext.extend(Object,{typeName:"type",constructor:function(a){Ext.apply(this,a||{});this.all=new Ext.util.MixedCollection();this.types={}},get:function(a){return this.all.get(a)},register:function(a){this.all.add(a)},unregister:function(a){this.all.remove(a)},registerType:function(b,a){this.types[b]=a;a[this.typeName]=b},isRegistered:function(a){return this.types[a]!==undefined},create:function(a,d){var b=a[this.typeName]||a.type||d,c=this.types[b];if(c==undefined){throw new Error(String.format("The '{0}' type has not been registered with this manager",b))}return new c(a)},onAvailable:function(d,c,b){var a=this.all;a.on("add",function(e,g){if(g.id==d){c.call(b||g,g);a.un("add",c,b)}})}});Ext.util.Format=function(){var trimRe=/^\s+|\s+$/g,stripTagsRE=/<\/?[^>]+>/gi,stripScriptsRe=/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,nl2brRe=/\r?\n/g;return{ellipsis:function(value,len,word){if(value&&value.length>len){if(word){var vs=value.substr(0,len-2),index=Math.max(vs.lastIndexOf(" "),vs.lastIndexOf("."),vs.lastIndexOf("!"),vs.lastIndexOf("?"));if(index==-1||index<(len-15)){return value.substr(0,len-3)+"..."}else{return vs.substr(0,index)+"..."}}else{return value.substr(0,len-3)+"..."}}return value},undef:function(value){return value!==undefined?value:""},defaultValue:function(value,defaultValue){if(!defaultValue&&defaultValue!==0){defaultValue=""}return value!==undefined&&value!==""?value:defaultValue},htmlEncode:function(value){return !value?value:String(value).replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;")},htmlDecode:function(value){return !value?value:String(value).replace(/&gt;/g,">").replace(/&lt;/g,"<").replace(/&quot;/g,'"').replace(/&amp;/g,"&")},trim:function(value){return String(value).replace(trimRe,"")},substr:function(value,start,length){return String(value).substr(start,length)},lowercase:function(value){return String(value).toLowerCase()},uppercase:function(value){return String(value).toUpperCase()},capitalize:function(value){return !value?value:value.charAt(0).toUpperCase()+value.substr(1).toLowerCase()},call:function(value,fn){if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);args.unshift(value);return eval(fn).apply(window,args)}else{return eval(fn).call(window,value)}},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);v=String(v);var ps=v.split("."),whole=ps[0],sub=ps[1]?"."+ps[1]:".00",r=/(\d+)(\d{3})/;while(r.test(whole)){whole=whole.replace(r,"$1,$2")}v=whole+sub;if(v.charAt(0)=="-"){return"-$"+v.substr(1)}return"$"+v},date:function(v,format){if(!v){return""}if(!Ext.isDate(v)){v=new Date(Date.parse(v))}return v.dateFormat(format||"m/d/Y")},dateRenderer:function(format){return function(v){return Ext.util.Format.date(v,format)}},stripTags:function(v){return !v?v:String(v).replace(stripTagsRE,"")},stripScripts:function(v){return !v?v:String(v).replace(stripScriptsRe,"")},fileSize:function(size){if(size<1024){return size+" bytes"}else{if(size<1048576){return(Math.round(((size*10)/1024))/10)+" KB"}else{return(Math.round(((size*10)/1048576))/10)+" MB"}}},math:function(){var fns={};return function(v,a){if(!fns[a]){fns[a]=new Function("v","return v "+a+";")}return fns[a](v)}}(),round:function(value,precision){var result=Number(value);if(typeof precision=="number"){precision=Math.pow(10,precision);result=Math.round(value*precision)/precision}return result},number:function(v,format){if(!format){return v}v=Ext.num(v,NaN);if(isNaN(v)){return""}var comma=",",dec=".",i18n=false,neg=v<0;v=Math.abs(v);if(format.substr(format.length-2)=="/i"){format=format.substr(0,format.length-2);i18n=true;comma=".";dec=","}var hasComma=format.indexOf(comma)!=-1,psplit=(i18n?format.replace(/[^\d\,]/g,""):format.replace(/[^\d\.]/g,"")).split(dec);if(1<psplit.length){v=v.toFixed(psplit[1].length)}else{if(2<psplit.length){throw ("NumberFormatException: invalid format, formats should have no more than 1 period: "+format)}else{v=v.toFixed(0)}}var fnum=v.toString();psplit=fnum.split(".");if(hasComma){var cnum=psplit[0],parr=[],j=cnum.length,m=Math.floor(j/3),n=cnum.length%3||3,i;for(i=0;i<j;i+=n){if(i!=0){n=3}parr[parr.length]=cnum.substr(i,n);m-=1}fnum=parr.join(comma);if(psplit[1]){fnum+=dec+psplit[1]}}else{if(psplit[1]){fnum=psplit[0]+dec+psplit[1]}}return(neg?"-":"")+format.replace(/[\d,?\.?]+/,fnum)},numberRenderer:function(format){return function(v){return Ext.util.Format.number(v,format)}},plural:function(v,s,p){return v+" "+(v==1?s:(p?p:s+"s"))},nl2br:function(v){return Ext.isEmpty(v)?"":v.replace(nl2brRe,"<br/>")}}}();Ext.XTemplate=function(){Ext.XTemplate.superclass.constructor.apply(this,arguments);var y=this,j=y.html,q=/<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,d=/^<tpl\b[^>]*?for="(.*?)"/,v=/^<tpl\b[^>]*?if="(.*?)"/,x=/^<tpl\b[^>]*?exec="(.*?)"/,r,p=0,k=[],o="values",w="parent",l="xindex",n="xcount",e="return ",c="with(values){ ";j=["<tpl>",j,"</tpl>"].join("");while((r=j.match(q))){var b=r[0].match(d),a=r[0].match(v),A=r[0].match(x),g=null,h=null,t=null,z=b&&b[1]?b[1]:"";if(a){g=a&&a[1]?a[1]:null;if(g){h=new Function(o,w,l,n,c+e+(Ext.util.Format.htmlDecode(g))+"; }")}}if(A){g=A&&A[1]?A[1]:null;if(g){t=new Function(o,w,l,n,c+(Ext.util.Format.htmlDecode(g))+"; }")}}if(z){switch(z){case".":z=new Function(o,w,c+e+o+"; }");break;case"..":z=new Function(o,w,c+e+w+"; }");break;default:z=new Function(o,w,c+e+z+"; }")}}k.push({id:p,target:z,exec:t,test:h,body:r[1]||""});j=j.replace(r[0],"{xtpl"+p+"}");++p}for(var u=k.length-1;u>=0;--u){y.compileTpl(k[u])}y.master=k[k.length-1];y.tpls=k};Ext.extend(Ext.XTemplate,Ext.Template,{re:/\{([\w\-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,codeRe:/\{\[((?:\\\]|.|\n)*?)\]\}/g,applySubTemplate:function(a,k,j,d,c){var h=this,g,m=h.tpls[a],l,b=[];if((m.test&&!m.test.call(h,k,j,d,c))||(m.exec&&m.exec.call(h,k,j,d,c))){return""}l=m.target?m.target.call(h,k,j):k;g=l.length;j=m.target?k:j;if(m.target&&Ext.isArray(l)){for(var e=0,g=l.length;e<g;e++){b[b.length]=m.compiled.call(h,l[e],j,e+1,g)}return b.join("")}return m.compiled.call(h,l,j,d,c)},compileTpl:function(tpl){var fm=Ext.util.Format,useF=this.disableFormats!==true,sep=Ext.isGecko?"+":",",body;function fn(m,name,format,args,math){if(name.substr(0,4)=="xtpl"){return"'"+sep+"this.applySubTemplate("+name.substr(4)+", values, parent, xindex, xcount)"+sep+"'"}var v;if(name==="."){v="values"}else{if(name==="#"){v="xindex"}else{if(name.indexOf(".")!=-1){v=name}else{v="values['"+name+"']"}}}if(math){v="("+v+math+")"}if(format&&useF){args=args?","+args:"";if(format.substr(0,5)!="this."){format="fm."+format+"("}else{format='this.call("'+format.substr(5)+'", ';args=", values"}}else{args="";format="("+v+" === undefined ? '' : "}return"'"+sep+format+v+args+")"+sep+"'"}function codeFn(m,code){return"'"+sep+"("+code.replace(/\\'/g,"'")+")"+sep+"'"}if(Ext.isGecko){body="tpl.compiled = function(values, parent, xindex, xcount){ return '"+tpl.body.replace(/(\r\n|\n)/g,"\\n").replace(/'/g,"\\'").replace(this.re,fn).replace(this.codeRe,codeFn)+"';};"}else{body=["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];body.push(tpl.body.replace(/(\r\n|\n)/g,"\\n").replace(/'/g,"\\'").replace(this.re,fn).replace(this.codeRe,codeFn));body.push("'].join('');};");body=body.join("")}eval(body);return this},applyTemplate:function(a){return this.master.compiled.call(this,a,{},1,1)},compile:function(){return this}});Ext.XTemplate.prototype.apply=Ext.XTemplate.prototype.applyTemplate;Ext.XTemplate.from=function(a){a=Ext.getDom(a);return new Ext.XTemplate(a.value||a.innerHTML)};Ext.util.CSS=function(){var d=null;var c=document;var b=/(-[a-z])/gi;var a=function(e,g){return g.charAt(1).toUpperCase()};return{createStyleSheet:function(i,l){var h;var g=c.getElementsByTagName("head")[0];var k=c.createElement("style");k.setAttribute("type","text/css");if(l){k.setAttribute("id",l)}if(Ext.isIE){g.appendChild(k);h=k.styleSheet;h.cssText=i}else{try{k.appendChild(c.createTextNode(i))}catch(j){k.cssText=i}g.appendChild(k);h=k.styleSheet?k.styleSheet:(k.sheet||c.styleSheets[c.styleSheets.length-1])}this.cacheStyleSheet(h);return h},removeStyleSheet:function(g){var e=c.getElementById(g);if(e){e.parentNode.removeChild(e)}},swapStyleSheet:function(h,e){this.removeStyleSheet(h);var g=c.createElement("link");g.setAttribute("rel","stylesheet");g.setAttribute("type","text/css");g.setAttribute("id",h);g.setAttribute("href",e);c.getElementsByTagName("head")[0].appendChild(g)},refreshCache:function(){return this.getRules(true)},cacheStyleSheet:function(h){if(!d){d={}}try{var k=h.cssRules||h.rules;for(var g=k.length-1;g>=0;--g){d[k[g].selectorText.toLowerCase()]=k[g]}}catch(i){}},getRules:function(h){if(d===null||h){d={};var k=c.styleSheets;for(var j=0,g=k.length;j<g;j++){try{this.cacheStyleSheet(k[j])}catch(l){}}}return d},getRule:function(e,h){var g=this.getRules(h);if(!Ext.isArray(e)){return g[e.toLowerCase()]}for(var j=0;j<e.length;j++){if(g[e[j]]){return g[e[j].toLowerCase()]}}return null},updateRule:function(e,j,h){if(!Ext.isArray(e)){var k=this.getRule(e);if(k){k.style[j.replace(b,a)]=h;return true}}else{for(var g=0;g<e.length;g++){if(this.updateRule(e[g],j,h)){return true}}}return false}}}();Ext.util.ClickRepeater=Ext.extend(Ext.util.Observable,{constructor:function(b,a){this.el=Ext.get(b);this.el.unselectable();Ext.apply(this,a);this.addEvents("mousedown","click","mouseup");if(!this.disabled){this.disabled=true;this.enable()}if(this.handler){this.on("click",this.handler,this.scope||this)}Ext.util.ClickRepeater.superclass.constructor.call(this)},interval:20,delay:250,preventDefault:true,stopDefault:false,timer:0,enable:function(){if(this.disabled){this.el.on("mousedown",this.handleMouseDown,this);if(Ext.isIE){this.el.on("dblclick",this.handleDblClick,this)}if(this.preventDefault||this.stopDefault){this.el.on("click",this.eventOptions,this)}}this.disabled=false},disable:function(a){if(a||!this.disabled){clearTimeout(this.timer);if(this.pressClass){this.el.removeClass(this.pressClass)}Ext.getDoc().un("mouseup",this.handleMouseUp,this);this.el.removeAllListeners()}this.disabled=true},setDisabled:function(a){this[a?"disable":"enable"]()},eventOptions:function(a){if(this.preventDefault){a.preventDefault()}if(this.stopDefault){a.stopEvent()}},destroy:function(){this.disable(true);Ext.destroy(this.el);this.purgeListeners()},handleDblClick:function(a){clearTimeout(this.timer);this.el.blur();this.fireEvent("mousedown",this,a);this.fireEvent("click",this,a)},handleMouseDown:function(a){clearTimeout(this.timer);this.el.blur();if(this.pressClass){this.el.addClass(this.pressClass)}this.mousedownTime=new Date();Ext.getDoc().on("mouseup",this.handleMouseUp,this);this.el.on("mouseout",this.handleMouseOut,this);this.fireEvent("mousedown",this,a);this.fireEvent("click",this,a);if(this.accelerate){this.delay=400}this.timer=this.click.defer(this.delay||this.interval,this,[a])},click:function(a){this.fireEvent("click",this,a);this.timer=this.click.defer(this.accelerate?this.easeOutExpo(this.mousedownTime.getElapsed(),400,-390,12000):this.interval,this,[a])},easeOutExpo:function(e,a,h,g){return(e==g)?a+h:h*(-Math.pow(2,-10*e/g)+1)+a},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,this);if(this.pressClass){this.el.addClass(this.pressClass)}this.click()},handleMouseUp:function(a){clearTimeout(this.timer);this.el.un("mouseover",this.handleMouseReturn,this);this.el.un("mouseout",this.handleMouseOut,this);Ext.getDoc().un("mouseup",this.handleMouseUp,this);this.el.removeClass(this.pressClass);this.fireEvent("mouseup",this,a)}});Ext.KeyNav=function(b,a){this.el=Ext.get(b);Ext.apply(this,a);if(!this.disabled){this.disabled=true;this.enable()}};Ext.KeyNav.prototype={disabled:false,defaultEventAction:"stopEvent",forceKeyDown:false,relay:function(c){var a=c.getKey(),b=this.keyToHandler[a];if(b&&this[b]){if(this.doRelay(c,this[b],b)!==true){c[this.defaultEventAction]()}}},doRelay:function(c,b,a){return b.call(this.scope||this,c,a)},enter:false,left:false,right:false,up:false,down:false,tab:false,esc:false,pageUp:false,pageDown:false,del:false,home:false,end:false,space: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",32:"space"},stopKeyUp:function(b){var a=b.getKey();if(a>=37&&a<=40){b.stopEvent()}},destroy:function(){this.disable()},enable:function(){if(this.disabled){if(Ext.isSafari2){this.el.on("keyup",this.stopKeyUp,this)}this.el.on(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=false}},disable:function(){if(!this.disabled){if(Ext.isSafari2){this.el.un("keyup",this.stopKeyUp,this)}this.el.un(this.isKeydown()?"keydown":"keypress",this.relay,this);this.disabled=true}},setDisabled:function(a){this[a?"disable":"enable"]()},isKeydown:function(){return this.forceKeyDown||Ext.EventManager.useKeydown}};Ext.KeyMap=function(c,b,a){this.el=Ext.get(c);this.eventName=a||"keydown";this.bindings=[];if(b){this.addBinding(b)}this.enable()};Ext.KeyMap.prototype={stopEvent:false,addBinding:function(b){if(Ext.isArray(b)){Ext.each(b,function(j){this.addBinding(j)},this);return}var k=b.key,g=b.fn||b.handler,l=b.scope;if(b.stopEvent){this.stopEvent=b.stopEvent}if(typeof k=="string"){var h=[];var e=k.toUpperCase();for(var c=0,d=e.length;c<d;c++){h.push(e.charCodeAt(c))}k=h}var a=Ext.isArray(k);var i=function(o){if(this.checkModifiers(b,o)){var m=o.getKey();if(a){for(var n=0,j=k.length;n<j;n++){if(k[n]==m){if(this.stopEvent){o.stopEvent()}g.call(l||window,m,o);return}}}else{if(m==k){if(this.stopEvent){o.stopEvent()}g.call(l||window,m,o)}}}};this.bindings.push(i)},checkModifiers:function(b,h){var j,d,g=["shift","ctrl","alt"];for(var c=0,a=g.length;c<a;++c){d=g[c];j=b[d];if(!(j===undefined||(j===h[d+"Key"]))){return false}}return true},on:function(b,d,c){var h,a,e,g;if(typeof b=="object"&&!Ext.isArray(b)){h=b.key;a=b.shift;e=b.ctrl;g=b.alt}else{h=b}this.addBinding({key:h,shift:a,ctrl:e,alt:g,fn:d,scope:c})},handleKeyDown:function(g){if(this.enabled){var c=this.bindings;for(var d=0,a=c.length;d<a;d++){c[d].call(this,g)}}},isEnabled:function(){return this.enabled},enable:function(){if(!this.enabled){this.el.on(this.eventName,this.handleKeyDown,this);this.enabled=true}},disable:function(){if(this.enabled){this.el.removeListener(this.eventName,this.handleKeyDown,this);this.enabled=false}},setDisabled:function(a){this[a?"disable":"enable"]()}};Ext.util.TextMetrics=function(){var a;return{measure:function(b,c,d){if(!a){a=Ext.util.TextMetrics.Instance(b,d)}a.bind(b);a.setFixedWidth(d||"auto");return a.getSize(c)},createInstance:function(b,c){return Ext.util.TextMetrics.Instance(b,c)}}}();Ext.util.TextMetrics.Instance=function(b,d){var c=new Ext.Element(document.createElement("div"));document.body.appendChild(c.dom);c.position("absolute");c.setLeftTop(-1000,-1000);c.hide();if(d){c.setWidth(d)}var a={getSize:function(g){c.update(g);var e=c.getSize();c.update("");return e},bind:function(e){c.setStyle(Ext.fly(e).getStyles("font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"))},setFixedWidth:function(e){c.setWidth(e)},getWidth:function(e){c.dom.style.width="auto";return this.getSize(e).width},getHeight:function(e){return this.getSize(e).height}};a.bind(b);return a};Ext.Element.addMethods({getTextWidth:function(c,b,a){return(Ext.util.TextMetrics.measure(this.dom,Ext.value(c,this.dom.innerHTML,true)).width).constrain(b||0,a||1000000)}});Ext.util.Cookies={set:function(c,e){var a=arguments;var i=arguments.length;var b=(i>2)?a[2]:null;var h=(i>3)?a[3]:"/";var d=(i>4)?a[4]:null;var g=(i>5)?a[5]:false;document.cookie=c+"="+escape(e)+((b===null)?"":("; expires="+b.toGMTString()))+((h===null)?"":("; path="+h))+((d===null)?"":("; domain="+d))+((g===true)?"; secure":"")},get:function(d){var b=d+"=";var g=b.length;var a=document.cookie.length;var e=0;var c=0;while(e<a){c=e+g;if(document.cookie.substring(e,c)==b){return Ext.util.Cookies.getCookieVal(c)}e=document.cookie.indexOf(" ",e)+1;if(e===0){break}}return null},clear:function(a){if(Ext.util.Cookies.get(a)){document.cookie=a+"=; expires=Thu, 01-Jan-70 00:00:01 GMT"}},getCookieVal:function(b){var a=document.cookie.indexOf(";",b);if(a==-1){a=document.cookie.length}return unescape(document.cookie.substring(b,a))}};Ext.handleError=function(a){throw a};Ext.Error=function(a){this.message=(this.lang[a])?this.lang[a]:a};Ext.Error.prototype=new Error();Ext.apply(Ext.Error.prototype,{lang:{},name:"Ext.Error",getName:function(){return this.name},getMessage:function(){return this.message},toJson:function(){return Ext.encode(this)}});Ext.ComponentMgr=function(){var c=new Ext.util.MixedCollection();var b={};var a={};return{register:function(d){c.add(d)},unregister:function(d){c.remove(d)},get:function(d){return c.get(d)},onAvailable:function(g,e,d){c.on("add",function(h,i){if(i.id==g){e.call(d||i,i);c.un("add",e,d)}})},all:c,types:b,ptypes:a,isRegistered:function(d){return b[d]!==undefined},isPluginRegistered:function(d){return a[d]!==undefined},registerType:function(e,d){b[e]=d;d.xtype=e},create:function(d,e){return d.render?d:new b[d.xtype||e](d)},registerPlugin:function(e,d){a[e]=d;d.ptype=e},createPlugin:function(e,g){var d=a[e.ptype||g];if(d.init){return d}else{return new d(e)}}}}();Ext.reg=Ext.ComponentMgr.registerType;Ext.preg=Ext.ComponentMgr.registerPlugin;Ext.create=Ext.ComponentMgr.create;Ext.Component=function(b){b=b||{};if(b.initialConfig){if(b.isAction){this.baseAction=b}b=b.initialConfig}else{if(b.tagName||b.dom||Ext.isString(b)){b={applyTo:b,id:b.id||b}}}this.initialConfig=b;Ext.apply(this,b);this.addEvents("added","disable","enable","beforeshow","show","beforehide","hide","removed","beforerender","render","afterrender","beforedestroy","destroy","beforestaterestore","staterestore","beforestatesave","statesave");this.getId();Ext.ComponentMgr.register(this);Ext.Component.superclass.constructor.call(this);if(this.baseAction){this.baseAction.addComponent(this)}this.initComponent();if(this.plugins){if(Ext.isArray(this.plugins)){for(var c=0,a=this.plugins.length;c<a;c++){this.plugins[c]=this.initPlugin(this.plugins[c])}}else{this.plugins=this.initPlugin(this.plugins)}}if(this.stateful!==false){this.initState()}if(this.applyTo){this.applyToMarkup(this.applyTo);delete this.applyTo}else{if(this.renderTo){this.render(this.renderTo);delete this.renderTo}}};Ext.Component.AUTO_ID=1000;Ext.extend(Ext.Component,Ext.util.Observable,{disabled:false,hidden:false,autoEl:"div",disabledClass:"x-item-disabled",allowDomMove:true,autoShow:false,hideMode:"display",hideParent:false,rendered:false,tplWriteMode:"overwrite",bubbleEvents:[],ctype:"Ext.Component",actionMode:"el",getActionEl:function(){return this[this.actionMode]},initPlugin:function(a){if(a.ptype&&!Ext.isFunction(a.init)){a=Ext.ComponentMgr.createPlugin(a)}else{if(Ext.isString(a)){a=Ext.ComponentMgr.createPlugin({ptype:a})}}a.init(this);return a},initComponent:function(){if(this.listeners){this.on(this.listeners);delete this.listeners}this.enableBubble(this.bubbleEvents)},render:function(b,a){if(!this.rendered&&this.fireEvent("beforerender",this)!==false){if(!b&&this.el){this.el=Ext.get(this.el);b=this.el.dom.parentNode;this.allowDomMove=false}this.container=Ext.get(b);if(this.ctCls){this.container.addClass(this.ctCls)}this.rendered=true;if(a!==undefined){if(Ext.isNumber(a)){a=this.container.dom.childNodes[a]}else{a=Ext.getDom(a)}}this.onRender(this.container,a||null);if(this.autoShow){this.el.removeClass(["x-hidden","x-hide-"+this.hideMode])}if(this.cls){this.el.addClass(this.cls);delete this.cls}if(this.style){this.el.applyStyles(this.style);delete this.style}if(this.overCls){this.el.addClassOnOver(this.overCls)}this.fireEvent("render",this);var c=this.getContentTarget();if(this.html){c.update(Ext.DomHelper.markup(this.html));delete this.html}if(this.contentEl){var d=Ext.getDom(this.contentEl);Ext.fly(d).removeClass(["x-hidden","x-hide-display"]);c.appendChild(d)}if(this.tpl){if(!this.tpl.compile){this.tpl=new Ext.XTemplate(this.tpl)}if(this.data){this.tpl[this.tplWriteMode](c,this.data);delete this.data}}this.afterRender(this.container);if(this.hidden){this.doHide()}if(this.disabled){this.disable(true)}if(this.stateful!==false){this.initStateEvents()}this.fireEvent("afterrender",this)}return this},update:function(b,d,a){var c=this.getContentTarget();if(this.tpl&&typeof b!=="string"){this.tpl[this.tplWriteMode](c,b||{})}else{var e=Ext.isObject(b)?Ext.DomHelper.markup(b):b;c.update(e,d,a)}},onAdded:function(a,b){this.ownerCt=a;this.initRef();this.fireEvent("added",this,a,b)},onRemoved:function(){this.removeRef();this.fireEvent("removed",this,this.ownerCt);delete this.ownerCt},initRef:function(){if(this.ref&&!this.refOwner){var d=this.ref.split("/"),c=d.length,b=0,a=this;while(a&&b<c){a=a.ownerCt;++b}if(a){a[this.refName=d[--b]]=this;this.refOwner=a}}},removeRef:function(){if(this.refOwner&&this.refName){delete this.refOwner[this.refName];delete this.refOwner}},initState:function(){if(Ext.state.Manager){var b=this.getStateId();if(b){var a=Ext.state.Manager.get(b);if(a){if(this.fireEvent("beforestaterestore",this,a)!==false){this.applyState(Ext.apply({},a));this.fireEvent("staterestore",this,a)}}}}},getStateId:function(){return this.stateId||((/^(ext-comp-|ext-gen)/).test(String(this.id))?null:this.id)},initStateEvents:function(){if(this.stateEvents){for(var a=0,b;b=this.stateEvents[a];a++){this.on(b,this.saveState,this,{delay:100})}}},applyState:function(a){if(a){Ext.apply(this,a)}},getState:function(){return null},saveState:function(){if(Ext.state.Manager&&this.stateful!==false){var b=this.getStateId();if(b){var a=this.getState();if(this.fireEvent("beforestatesave",this,a)!==false){Ext.state.Manager.set(b,a);this.fireEvent("statesave",this,a)}}}},applyToMarkup:function(a){this.allowDomMove=false;this.el=Ext.get(a);this.render(this.el.dom.parentNode)},addClass:function(a){if(this.el){this.el.addClass(a)}else{this.cls=this.cls?this.cls+" "+a:a}return this},removeClass:function(a){if(this.el){this.el.removeClass(a)}else{if(this.cls){this.cls=this.cls.split(" ").remove(a).join(" ")}}return this},onRender:function(b,a){if(!this.el&&this.autoEl){if(Ext.isString(this.autoEl)){this.el=document.createElement(this.autoEl)}else{var c=document.createElement("div");Ext.DomHelper.overwrite(c,this.autoEl);this.el=c.firstChild}if(!this.el.id){this.el.id=this.getId()}}if(this.el){this.el=Ext.get(this.el);if(this.allowDomMove!==false){b.dom.insertBefore(this.el.dom,a);if(c){Ext.removeNode(c);c=null}}}},getAutoCreate:function(){var a=Ext.isObject(this.autoCreate)?this.autoCreate:Ext.apply({},this.defaultAutoCreate);if(this.id&&!a.id){a.id=this.id}return a},afterRender:Ext.emptyFn,destroy:function(){if(!this.isDestroyed){if(this.fireEvent("beforedestroy",this)!==false){this.destroying=true;this.beforeDestroy();if(this.ownerCt&&this.ownerCt.remove){this.ownerCt.remove(this,false)}if(this.rendered){this.el.remove();if(this.actionMode=="container"||this.removeMode=="container"){this.container.remove()}}if(this.focusTask&&this.focusTask.cancel){this.focusTask.cancel()}this.onDestroy();Ext.ComponentMgr.unregister(this);this.fireEvent("destroy",this);this.purgeListeners();this.destroying=false;this.isDestroyed=true}}},deleteMembers:function(){var b=arguments;for(var c=0,a=b.length;c<a;++c){delete this[b[c]]}},beforeDestroy:Ext.emptyFn,onDestroy:Ext.emptyFn,getEl:function(){return this.el},getContentTarget:function(){return this.el},getId:function(){return this.id||(this.id="ext-comp-"+(++Ext.Component.AUTO_ID))},getItemId:function(){return this.itemId||this.getId()},focus:function(b,a){if(a){this.focusTask=new Ext.util.DelayedTask(this.focus,this,[b,false]);this.focusTask.delay(Ext.isNumber(a)?a:10);return this}if(this.rendered&&!this.isDestroyed){this.el.focus();if(b===true){this.el.dom.select()}}return this},blur:function(){if(this.rendered){this.el.blur()}return this},disable:function(a){if(this.rendered){this.onDisable()}this.disabled=true;if(a!==true){this.fireEvent("disable",this)}return this},onDisable:function(){this.getActionEl().addClass(this.disabledClass);this.el.dom.disabled=true},enable:function(){if(this.rendered){this.onEnable()}this.disabled=false;this.fireEvent("enable",this);return this},onEnable:function(){this.getActionEl().removeClass(this.disabledClass);this.el.dom.disabled=false},setDisabled:function(a){return this[a?"disable":"enable"]()},show:function(){if(this.fireEvent("beforeshow",this)!==false){this.hidden=false;if(this.autoRender){this.render(Ext.isBoolean(this.autoRender)?Ext.getBody():this.autoRender)}if(this.rendered){this.onShow()}this.fireEvent("show",this)}return this},onShow:function(){this.getVisibilityEl().removeClass("x-hide-"+this.hideMode)},hide:function(){if(this.fireEvent("beforehide",this)!==false){this.doHide();this.fireEvent("hide",this)}return this},doHide:function(){this.hidden=true;if(this.rendered){this.onHide()}},onHide:function(){this.getVisibilityEl().addClass("x-hide-"+this.hideMode)},getVisibilityEl:function(){return this.hideParent?this.container:this.getActionEl()},setVisible:function(a){return this[a?"show":"hide"]()},isVisible:function(){return this.rendered&&this.getVisibilityEl().isVisible()},cloneConfig:function(b){b=b||{};var c=b.id||Ext.id();var a=Ext.applyIf(b,this.initialConfig);a.id=c;return new this.constructor(a)},getXType:function(){return this.constructor.xtype},isXType:function(b,a){if(Ext.isFunction(b)){b=b.xtype}else{if(Ext.isObject(b)){b=b.constructor.xtype}}return !a?("/"+this.getXTypes()+"/").indexOf("/"+b+"/")!=-1:this.constructor.xtype==b},getXTypes:function(){var a=this.constructor;if(!a.xtypes){var d=[],b=this;while(b&&b.constructor.xtype){d.unshift(b.constructor.xtype);b=b.constructor.superclass}a.xtypeChain=d;a.xtypes=d.join("/")}return a.xtypes},findParentBy:function(a){for(var b=this.ownerCt;(b!=null)&&!a(b,this);b=b.ownerCt){}return b||null},findParentByType:function(b,a){return this.findParentBy(function(d){return d.isXType(b,a)})},bubble:function(c,b,a){var d=this;while(d){if(c.apply(b||d,a||[d])===false){break}d=d.ownerCt}return this},getPositionEl:function(){return this.positionEl||this.el},purgeListeners:function(){Ext.Component.superclass.purgeListeners.call(this);if(this.mons){this.on("beforedestroy",this.clearMons,this,{single:true})}},clearMons:function(){Ext.each(this.mons,function(a){a.item.un(a.ename,a.fn,a.scope)},this);this.mons=[]},createMons:function(){if(!this.mons){this.mons=[];this.on("beforedestroy",this.clearMons,this,{single:true})}},mon:function(g,b,d,c,a){this.createMons();if(Ext.isObject(b)){var j=/^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;var i=b;for(var h in i){if(j.test(h)){continue}if(Ext.isFunction(i[h])){this.mons.push({item:g,ename:h,fn:i[h],scope:i.scope});g.on(h,i[h],i.scope,i)}else{this.mons.push({item:g,ename:h,fn:i[h],scope:i.scope});g.on(h,i[h])}}return}this.mons.push({item:g,ename:b,fn:d,scope:c});g.on(b,d,c,a)},mun:function(h,c,g,e){var j,d;this.createMons();for(var b=0,a=this.mons.length;b<a;++b){d=this.mons[b];if(h===d.item&&c==d.ename&&g===d.fn&&e===d.scope){this.mons.splice(b,1);h.un(c,g,e);j=true;break}}return j},nextSibling:function(){if(this.ownerCt){var a=this.ownerCt.items.indexOf(this);if(a!=-1&&a+1<this.ownerCt.items.getCount()){return this.ownerCt.items.itemAt(a+1)}}return null},previousSibling:function(){if(this.ownerCt){var a=this.ownerCt.items.indexOf(this);if(a>0){return this.ownerCt.items.itemAt(a-1)}}return null},getBubbleTarget:function(){return this.ownerCt}});Ext.reg("component",Ext.Component);Ext.Action=Ext.extend(Object,{constructor:function(a){this.initialConfig=a;this.itemId=a.itemId=(a.itemId||a.id||Ext.id());this.items=[]},isAction:true,setText:function(a){this.initialConfig.text=a;this.callEach("setText",[a])},getText:function(){return this.initialConfig.text},setIconClass:function(a){this.initialConfig.iconCls=a;this.callEach("setIconClass",[a])},getIconClass:function(){return this.initialConfig.iconCls},setDisabled:function(a){this.initialConfig.disabled=a;this.callEach("setDisabled",[a])},enable:function(){this.setDisabled(false)},disable:function(){this.setDisabled(true)},isDisabled:function(){return this.initialConfig.disabled},setHidden:function(a){this.initialConfig.hidden=a;this.callEach("setVisible",[!a])},show:function(){this.setHidden(false)},hide:function(){this.setHidden(true)},isHidden:function(){return this.initialConfig.hidden},setHandler:function(b,a){this.initialConfig.handler=b;this.initialConfig.scope=a;this.callEach("setHandler",[b,a])},each:function(b,a){Ext.each(this.items,b,a)},callEach:function(e,b){var d=this.items;for(var c=0,a=d.length;c<a;c++){d[c][e].apply(d[c],b)}},addComponent:function(a){this.items.push(a);a.on("destroy",this.removeComponent,this)},removeComponent:function(a){this.items.remove(a)},execute:function(){this.initialConfig.handler.apply(this.initialConfig.scope||window,arguments)}});(function(){Ext.Layer=function(d,c){d=d||{};var e=Ext.DomHelper,h=d.parentEl,g=h?Ext.getDom(h):document.body;if(c){this.dom=Ext.getDom(c)}if(!this.dom){var i=d.dh||{tag:"div",cls:"x-layer"};this.dom=e.append(g,i)}if(d.cls){this.addClass(d.cls)}this.constrain=d.constrain!==false;this.setVisibilityMode(Ext.Element.VISIBILITY);if(d.id){this.id=this.dom.id=d.id}else{this.id=Ext.id(this.dom)}this.zindex=d.zindex||this.getZIndex();this.position("absolute",this.zindex);if(d.shadow){this.shadowOffset=d.shadowOffset||4;this.shadow=new Ext.Shadow({offset:this.shadowOffset,mode:d.shadow})}else{this.shadowOffset=0}this.useShim=d.shim!==false&&Ext.useShims;this.useDisplay=d.useDisplay;this.hide()};var a=Ext.Element.prototype;var b=[];Ext.extend(Ext.Layer,Ext.Element,{getZIndex:function(){return this.zindex||parseInt((this.getShim()||this).getStyle("z-index"),10)||11000},getShim:function(){if(!this.useShim){return null}if(this.shim){return this.shim}var d=b.shift();if(!d){d=this.createShim();d.enableDisplayMode("block");d.dom.style.display="none";d.dom.style.visibility="visible"}var c=this.dom.parentNode;if(d.dom.parentNode!=c){c.insertBefore(d.dom,this.dom)}d.setStyle("z-index",this.getZIndex()-2);this.shim=d;return d},hideShim:function(){if(this.shim){this.shim.setDisplayed(false);b.push(this.shim);delete this.shim}},disableShadow:function(){if(this.shadow){this.shadowDisabled=true;this.shadow.hide();this.lastShadowOffset=this.shadowOffset;this.shadowOffset=0}},enableShadow:function(c){if(this.shadow){this.shadowDisabled=false;if(Ext.isDefined(this.lastShadowOffset)){this.shadowOffset=this.lastShadowOffset;delete this.lastShadowOffset}if(c){this.sync(true)}}},sync:function(d){var n=this.shadow;if(!this.updating&&this.isVisible()&&(n||this.useShim)){var i=this.getShim(),m=this.getWidth(),j=this.getHeight(),e=this.getLeft(true),o=this.getTop(true);if(n&&!this.shadowDisabled){if(d&&!n.isVisible()){n.show(this)}else{n.realign(e,o,m,j)}if(i){if(d){i.show()}var k=n.el.getXY(),g=i.dom.style,c=n.el.getSize();g.left=(k[0])+"px";g.top=(k[1])+"px";g.width=(c.width)+"px";g.height=(c.height)+"px"}}else{if(i){if(d){i.show()}i.setSize(m,j);i.setLeftTop(e,o)}}}},destroy:function(){this.hideShim();if(this.shadow){this.shadow.hide()}this.removeAllListeners();Ext.removeNode(this.dom);delete this.dom},remove:function(){this.destroy()},beginUpdate:function(){this.updating=true},endUpdate:function(){this.updating=false;this.sync(true)},hideUnders:function(c){if(this.shadow){this.shadow.hide()}this.hideShim()},constrainXY:function(){if(this.constrain){var j=Ext.lib.Dom.getViewWidth(),d=Ext.lib.Dom.getViewHeight();var o=Ext.getDoc().getScroll();var n=this.getXY();var k=n[0],i=n[1];var c=this.shadowOffset;var l=this.dom.offsetWidth+c,e=this.dom.offsetHeight+c;var g=false;if((k+l)>j+o.left){k=j-l-c;g=true}if((i+e)>d+o.top){i=d-e-c;g=true}if(k<o.left){k=o.left;g=true}if(i<o.top){i=o.top;g=true}if(g){if(this.avoidY){var m=this.avoidY;if(i<=m&&(i+e)>=m){i=m-e-5}}n=[k,i];this.storeXY(n);a.setXY.call(this,n);this.sync()}}return this},getConstrainOffset:function(){return this.shadowOffset},isVisible:function(){return this.visible},showAction:function(){this.visible=true;if(this.useDisplay===true){this.setDisplayed("")}else{if(this.lastXY){a.setXY.call(this,this.lastXY)}else{if(this.lastLT){a.setLeftTop.call(this,this.lastLT[0],this.lastLT[1])}}}},hideAction:function(){this.visible=false;if(this.useDisplay===true){this.setDisplayed(false)}else{this.setLeftTop(-10000,-10000)}},setVisible:function(i,h,k,l,j){if(i){this.showAction()}if(h&&i){var g=function(){this.sync(true);if(l){l()}}.createDelegate(this);a.setVisible.call(this,true,true,k,g,j)}else{if(!i){this.hideUnders(true)}var g=l;if(h){g=function(){this.hideAction();if(l){l()}}.createDelegate(this)}a.setVisible.call(this,i,h,k,g,j);if(i){this.sync(true)}else{if(!h){this.hideAction()}}}return this},storeXY:function(c){delete this.lastLT;this.lastXY=c},storeLeftTop:function(d,c){delete this.lastXY;this.lastLT=[d,c]},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()}},setLeft:function(c){this.storeLeftTop(c,this.getTop(true));a.setLeft.apply(this,arguments);this.sync();return this},setTop:function(c){this.storeLeftTop(this.getLeft(true),c);a.setTop.apply(this,arguments);this.sync();return this},setLeftTop:function(d,c){this.storeLeftTop(d,c);a.setLeftTop.apply(this,arguments);this.sync();return this},setXY:function(j,h,k,l,i){this.fixDisplay();this.beforeAction();this.storeXY(j);var g=this.createCB(l);a.setXY.call(this,j,h,k,g,i);if(!h){g()}return this},createCB:function(e){var d=this;return function(){d.constrainXY();d.sync(true);if(e){e()}}},setX:function(g,h,j,k,i){this.setXY([g,this.getY()],h,j,k,i);return this},setY:function(k,g,i,j,h){this.setXY([this.getX(),k],g,i,j,h);return this},setSize:function(j,k,i,m,n,l){this.beforeAction();var g=this.createCB(n);a.setSize.call(this,j,k,i,m,g,l);if(!i){g()}return this},setWidth:function(i,h,k,l,j){this.beforeAction();var g=this.createCB(l);a.setWidth.call(this,i,h,k,g,j);if(!h){g()}return this},setHeight:function(j,i,l,m,k){this.beforeAction();var g=this.createCB(m);a.setHeight.call(this,j,i,l,g,k);if(!i){g()}return this},setBounds:function(o,m,p,i,n,k,l,j){this.beforeAction();var g=this.createCB(l);if(!n){this.storeXY([o,m]);a.setXY.call(this,[o,m]);a.setSize.call(this,p,i,n,k,g,j);g()}else{a.setBounds.call(this,o,m,p,i,n,k,g,j)}return this},setZIndex:function(c){this.zindex=c;this.setStyle("z-index",c+2);if(this.shadow){this.shadow.setZIndex(c+1)}if(this.shim){this.shim.setStyle("z-index",c)}return this}})})();Ext.Shadow=function(d){Ext.apply(this,d);if(typeof this.mode!="string"){this.mode=this.defaultMode}var e=this.offset,c={h:0},b=Math.floor(this.offset/2);switch(this.mode.toLowerCase()){case"drop":c.w=0;c.l=c.t=e;c.t-=1;if(Ext.isIE9m){c.l-=this.offset+b;c.t-=this.offset+b;c.w-=b;c.h-=b;c.t+=1}break;case"sides":c.w=(e*2);c.l=-e;c.t=e-1;if(Ext.isIE9m){c.l-=(this.offset-b);c.t-=this.offset+b;c.l+=1;c.w-=(this.offset-b)*2;c.w-=b+1;c.h-=1}break;case"frame":c.w=c.h=(e*2);c.l=c.t=-e;c.t+=1;c.h-=2;if(Ext.isIE9m){c.l-=(this.offset-b);c.t-=(this.offset-b);c.l+=1;c.w-=(this.offset+b+1);c.h-=(this.offset+b);c.h+=1}break}this.adjusts=c};Ext.Shadow.prototype={offset:4,defaultMode:"drop",show:function(a){a=Ext.get(a);if(!this.el){this.el=Ext.Shadow.Pool.pull();if(this.el.dom.nextSibling!=a.dom){this.el.insertBefore(a)}}this.el.setStyle("z-index",this.zIndex||parseInt(a.getStyle("z-index"),10)-1);if(Ext.isIE9m){this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")"}this.realign(a.getLeft(true),a.getTop(true),a.getWidth(),a.getHeight());this.el.dom.style.display="block"},isVisible:function(){return this.el?true:false},realign:function(b,r,q,g){if(!this.el){return}var n=this.adjusts,k=this.el.dom,u=k.style,i=0,p=(q+n.w),e=(g+n.h),j=p+"px",o=e+"px",m,c;u.left=(b+n.l)+"px";u.top=(r+n.t)+"px";if(u.width!=j||u.height!=o){u.width=j;u.height=o;if(!Ext.isIE9m){m=k.childNodes;c=Math.max(0,(p-12))+"px";m[0].childNodes[1].style.width=c;m[1].childNodes[1].style.width=c;m[2].childNodes[1].style.width=c;m[1].style.height=Math.max(0,(e-12))+"px"}}},hide:function(){if(this.el){this.el.dom.style.display="none";Ext.Shadow.Pool.push(this.el);delete this.el}},setZIndex:function(a){this.zIndex=a;if(this.el){this.el.setStyle("z-index",a)}}};Ext.Shadow.Pool=function(){var b=[],a=Ext.isIE9m?'<div class="x-ie-shadow"></div>':'<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 c=b.shift();if(!c){c=Ext.get(Ext.DomHelper.insertHtml("beforeBegin",document.body.firstChild,a));c.autoBoxAdjust=false}return c},push:function(c){b.push(c)}}}();Ext.BoxComponent=Ext.extend(Ext.Component,{initComponent:function(){Ext.BoxComponent.superclass.initComponent.call(this);this.addEvents("resize","move")},boxReady:false,deferHeight:false,setSize:function(b,d){if(typeof b=="object"){d=b.height;b=b.width}if(Ext.isDefined(b)&&Ext.isDefined(this.boxMinWidth)&&(b<this.boxMinWidth)){b=this.boxMinWidth}if(Ext.isDefined(d)&&Ext.isDefined(this.boxMinHeight)&&(d<this.boxMinHeight)){d=this.boxMinHeight}if(Ext.isDefined(b)&&Ext.isDefined(this.boxMaxWidth)&&(b>this.boxMaxWidth)){b=this.boxMaxWidth}if(Ext.isDefined(d)&&Ext.isDefined(this.boxMaxHeight)&&(d>this.boxMaxHeight)){d=this.boxMaxHeight}if(!this.boxReady){this.width=b;this.height=d;return this}if(this.cacheSizes!==false&&this.lastSize&&this.lastSize.width==b&&this.lastSize.height==d){return this}this.lastSize={width:b,height:d};var c=this.adjustSize(b,d),g=c.width,a=c.height,e;if(g!==undefined||a!==undefined){e=this.getResizeEl();if(!this.deferHeight&&g!==undefined&&a!==undefined){e.setSize(g,a)}else{if(!this.deferHeight&&a!==undefined){e.setHeight(a)}else{if(g!==undefined){e.setWidth(g)}}}this.onResize(g,a,b,d);this.fireEvent("resize",this,g,a,b,d)}return this},setWidth:function(a){return this.setSize(a)},setHeight:function(a){return this.setSize(undefined,a)},getSize:function(){return this.getResizeEl().getSize()},getWidth:function(){return this.getResizeEl().getWidth()},getHeight:function(){return this.getResizeEl().getHeight()},getOuterSize:function(){var a=this.getResizeEl();return{width:a.getWidth()+a.getMargins("lr"),height:a.getHeight()+a.getMargins("tb")}},getPosition:function(a){var b=this.getPositionEl();if(a===true){return[b.getLeft(true),b.getTop(true)]}return this.xy||b.getXY()},getBox:function(a){var c=this.getPosition(a);var b=this.getSize();b.x=c[0];b.y=c[1];return b},updateBox:function(a){this.setSize(a.width,a.height);this.setPagePosition(a.x,a.y);return this},getResizeEl:function(){return this.resizeEl||this.el},setAutoScroll:function(a){if(this.rendered){this.getContentTarget().setOverflow(a?"auto":"")}this.autoScroll=a;return this},setPosition:function(a,g){if(a&&typeof a[1]=="number"){g=a[1];a=a[0]}this.x=a;this.y=g;if(!this.boxReady){return this}var b=this.adjustPosition(a,g);var e=b.x,d=b.y;var c=this.getPositionEl();if(e!==undefined||d!==undefined){if(e!==undefined&&d!==undefined){c.setLeftTop(e,d)}else{if(e!==undefined){c.setLeft(e)}else{if(d!==undefined){c.setTop(d)}}}this.onPosition(e,d);this.fireEvent("move",this,e,d)}return this},setPagePosition:function(a,c){if(a&&typeof a[1]=="number"){c=a[1];a=a[0]}this.pageX=a;this.pageY=c;if(!this.boxReady){return}if(a===undefined||c===undefined){return}var b=this.getPositionEl().translatePoints(a,c);this.setPosition(b.left,b.top);return this},afterRender:function(){Ext.BoxComponent.superclass.afterRender.call(this);if(this.resizeEl){this.resizeEl=Ext.get(this.resizeEl)}if(this.positionEl){this.positionEl=Ext.get(this.positionEl)}this.boxReady=true;Ext.isDefined(this.autoScroll)&&this.setAutoScroll(this.autoScroll);this.setSize(this.width,this.height);if(this.x||this.y){this.setPosition(this.x,this.y)}else{if(this.pageX||this.pageY){this.setPagePosition(this.pageX,this.pageY)}}},syncSize:function(){delete this.lastSize;this.setSize(this.autoWidth?undefined:this.getResizeEl().getWidth(),this.autoHeight?undefined:this.getResizeEl().getHeight());return this},onResize:function(d,b,a,c){},onPosition:function(a,b){},adjustSize:function(a,b){if(this.autoWidth){a="auto"}if(this.autoHeight){b="auto"}return{width:a,height:b}},adjustPosition:function(a,b){return{x:a,y:b}}});Ext.reg("box",Ext.BoxComponent);Ext.Spacer=Ext.extend(Ext.BoxComponent,{autoEl:"div"});Ext.reg("spacer",Ext.Spacer);Ext.SplitBar=function(c,e,b,d,a){this.el=Ext.get(c,true);this.el.unselectable();this.resizingEl=Ext.get(e,true);this.orientation=b||Ext.SplitBar.HORIZONTAL;this.minSize=0;this.maxSize=2000;this.animate=false;this.useShim=false;this.shim=null;if(!a){this.proxy=Ext.SplitBar.createProxy(this.orientation)}else{this.proxy=Ext.get(a).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=d||(this.el.getX()>this.resizingEl.getX()?Ext.SplitBar.LEFT:Ext.SplitBar.RIGHT);this.el.addClass("x-splitbar-h")}else{this.placement=d||(this.el.getY()>this.resizingEl.getY()?Ext.SplitBar.TOP:Ext.SplitBar.BOTTOM);this.el.addClass("x-splitbar-v")}this.addEvents("resize","moved","beforeresize","beforeapply");Ext.SplitBar.superclass.constructor.call(this)};Ext.extend(Ext.SplitBar,Ext.util.Observable,{onStartProxyDrag:function(a,e){this.fireEvent("beforeresize",this);this.overlay=Ext.DomHelper.append(document.body,{cls:"x-drag-overlay",html:"&#160;"},true);this.overlay.unselectable();this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();Ext.get(this.proxy).setDisplayed("block");var c=this.adapter.getElementSize(this);this.activeMinSize=this.getMinimumSize();this.activeMaxSize=this.getMaximumSize();var d=c-this.activeMinSize;var b=Math.max(this.activeMaxSize-c,0);if(this.orientation==Ext.SplitBar.HORIZONTAL){this.dd.resetConstraints();this.dd.setXConstraint(this.placement==Ext.SplitBar.LEFT?d:b,this.placement==Ext.SplitBar.LEFT?b:d,this.tickSize);this.dd.setYConstraint(0,0)}else{this.dd.resetConstraints();this.dd.setXConstraint(0,0);this.dd.setYConstraint(this.placement==Ext.SplitBar.TOP?d:b,this.placement==Ext.SplitBar.TOP?b:d,this.tickSize)}this.dragSpecs.startSize=c;this.dragSpecs.startPoint=[a,e];Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd,a,e)},onEndProxyDrag:function(c){Ext.get(this.proxy).setDisplayed(false);var b=Ext.lib.Event.getXY(c);if(this.overlay){Ext.destroy(this.overlay);delete this.overlay}var a;if(this.orientation==Ext.SplitBar.HORIZONTAL){a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.LEFT?b[0]-this.dragSpecs.startPoint[0]:this.dragSpecs.startPoint[0]-b[0])}else{a=this.dragSpecs.startSize+(this.placement==Ext.SplitBar.TOP?b[1]-this.dragSpecs.startPoint[1]:this.dragSpecs.startPoint[1]-b[1])}a=Math.min(Math.max(a,this.activeMinSize),this.activeMaxSize);if(a!=this.dragSpecs.startSize){if(this.fireEvent("beforeapply",this,a)!==false){this.adapter.setElementSize(this,a);this.fireEvent("moved",this,a);this.fireEvent("resize",this,a)}}},getAdapter:function(){return this.adapter},setAdapter:function(a){this.adapter=a;this.adapter.init(this)},getMinimumSize:function(){return this.minSize},setMinimumSize:function(a){this.minSize=a},getMaximumSize:function(){return this.maxSize},setMaximumSize:function(a){this.maxSize=a},setCurrentSize:function(b){var a=this.animate;this.animate=false;this.adapter.setElementSize(this,b);this.animate=a},destroy:function(a){Ext.destroy(this.shim,Ext.get(this.proxy));this.dd.unreg();if(a){this.el.remove()}this.purgeListeners()}});Ext.SplitBar.createProxy=function(b){var c=new Ext.Element(document.createElement("div"));document.body.appendChild(c.dom);c.unselectable();var a="x-splitbar-proxy";c.addClass(a+" "+(b==Ext.SplitBar.HORIZONTAL?a+"-h":a+"-v"));return c.dom};Ext.SplitBar.BasicLayoutAdapter=function(){};Ext.SplitBar.BasicLayoutAdapter.prototype={init:function(a){},getElementSize:function(a){if(a.orientation==Ext.SplitBar.HORIZONTAL){return a.resizingEl.getWidth()}else{return a.resizingEl.getHeight()}},setElementSize:function(b,a,c){if(b.orientation==Ext.SplitBar.HORIZONTAL){if(!b.animate){b.resizingEl.setWidth(a);if(c){c(b,a)}}else{b.resizingEl.setWidth(a,true,0.1,c,"easeOut")}}else{if(!b.animate){b.resizingEl.setHeight(a);if(c){c(b,a)}}else{b.resizingEl.setHeight(a,true,0.1,c,"easeOut")}}}};Ext.SplitBar.AbsoluteLayoutAdapter=function(a){this.basic=new Ext.SplitBar.BasicLayoutAdapter();this.container=Ext.get(a)};Ext.SplitBar.AbsoluteLayoutAdapter.prototype={init:function(a){this.basic.init(a)},getElementSize:function(a){return this.basic.getElementSize(a)},setElementSize:function(b,a,c){this.basic.setElementSize(b,a,this.moveSplitter.createDelegate(this,[b]))},moveSplitter:function(a){var b=Ext.SplitBar;switch(a.placement){case b.LEFT:a.el.setX(a.resizingEl.getRight());break;case b.RIGHT:a.el.setStyle("right",(this.container.getWidth()-a.resizingEl.getLeft())+"px");break;case b.TOP:a.el.setY(a.resizingEl.getBottom());break;case b.BOTTOM:a.el.setY(a.resizingEl.getTop()-a.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.Container=Ext.extend(Ext.BoxComponent,{bufferResize:50,autoDestroy:true,forceLayout:false,defaultType:"panel",resizeEvent:"resize",bubbleEvents:["add","remove"],initComponent:function(){Ext.Container.superclass.initComponent.call(this);this.addEvents("afterlayout","beforeadd","beforeremove","add","remove");var a=this.items;if(a){delete this.items;this.add(a)}},initItems:function(){if(!this.items){this.items=new Ext.util.MixedCollection(false,this.getComponentId);this.getLayout()}},setLayout:function(a){if(this.layout&&this.layout!=a){this.layout.setContainer(null)}this.layout=a;this.initItems();a.setContainer(this)},afterRender:function(){Ext.Container.superclass.afterRender.call(this);if(!this.layout){this.layout="auto"}if(Ext.isObject(this.layout)&&!this.layout.layout){this.layoutConfig=this.layout;this.layout=this.layoutConfig.type}if(Ext.isString(this.layout)){this.layout=new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig)}this.setLayout(this.layout);if(this.activeItem!==undefined&&this.layout.setActiveItem){var a=this.activeItem;delete this.activeItem;this.layout.setActiveItem(a)}if(!this.ownerCt){this.doLayout(false,true)}if(this.monitorResize===true){Ext.EventManager.onWindowResize(this.doLayout,this,[false])}},getLayoutTarget:function(){return this.el},getComponentId:function(a){return a.getItemId()},add:function(b){this.initItems();var e=arguments.length>1;if(e||Ext.isArray(b)){var a=[];Ext.each(e?arguments:b,function(h){a.push(this.add(h))},this);return a}var g=this.lookupComponent(this.applyDefaults(b));var d=this.items.length;if(this.fireEvent("beforeadd",this,g,d)!==false&&this.onBeforeAdd(g)!==false){this.items.add(g);g.onAdded(this,d);this.onAdd(g);this.fireEvent("add",this,g,d)}return g},onAdd:function(a){},onAdded:function(a,b){this.ownerCt=a;this.initRef();this.cascade(function(d){d.initRef()});this.fireEvent("added",this,a,b)},insert:function(e,b){var d=arguments,h=d.length,a=[],g,j;this.initItems();if(h>2){for(g=h-1;g>=1;--g){a.push(this.insert(e,d[g]))}return a}j=this.lookupComponent(this.applyDefaults(b));e=Math.min(e,this.items.length);if(this.fireEvent("beforeadd",this,j,e)!==false&&this.onBeforeAdd(j)!==false){if(j.ownerCt==this){this.items.remove(j)}this.items.insert(e,j);j.onAdded(this,e);this.onAdd(j);this.fireEvent("add",this,j,e)}return j},applyDefaults:function(b){var a=this.defaults;if(a){if(Ext.isFunction(a)){a=a.call(this,b)}if(Ext.isString(b)){b=Ext.ComponentMgr.get(b);Ext.apply(b,a)}else{if(!b.events){Ext.applyIf(b.isAction?b.initialConfig:b,a)}else{Ext.apply(b,a)}}}return b},onBeforeAdd:function(a){if(a.ownerCt){a.ownerCt.remove(a,false)}if(this.hideBorders===true){a.border=(a.border===true)}},remove:function(a,b){this.initItems();var d=this.getComponent(a);if(d&&this.fireEvent("beforeremove",this,d)!==false){this.doRemove(d,b);this.fireEvent("remove",this,d)}return d},onRemove:function(a){},doRemove:function(e,d){var b=this.layout,a=b&&this.rendered;if(a){b.onRemove(e)}this.items.remove(e);e.onRemoved();this.onRemove(e);if(d===true||(d!==false&&this.autoDestroy)){e.destroy()}if(a){b.afterRemove(e)}},removeAll:function(c){this.initItems();var e,g=[],b=[];this.items.each(function(h){g.push(h)});for(var d=0,a=g.length;d<a;++d){e=g[d];this.remove(e,c);if(e.ownerCt!==this){b.push(e)}}return b},getComponent:function(a){if(Ext.isObject(a)){a=a.getItemId()}return this.items.get(a)},lookupComponent:function(a){if(Ext.isString(a)){return Ext.ComponentMgr.get(a)}else{if(!a.events){return this.createComponent(a)}}return a},createComponent:function(a,d){if(a.render){return a}var b=Ext.create(Ext.apply({ownerCt:this},a),d||this.defaultType);delete b.initialConfig.ownerCt;delete b.ownerCt;return b},canLayout:function(){var a=this.getVisibilityEl();return a&&a.dom&&!a.isStyle("display","none")},doLayout:function(g,e){var k=this.rendered,j=e||this.forceLayout;if(this.collapsed||!this.canLayout()){this.deferLayout=this.deferLayout||!g;if(!j){return}g=g&&!this.deferLayout}else{delete this.deferLayout}if(k&&this.layout){this.layout.layout()}if(g!==true&&this.items){var d=this.items.items;for(var b=0,a=d.length;b<a;b++){var h=d[b];if(h.doLayout){h.doLayout(false,j)}}}if(k){this.onLayout(g,j)}this.hasLayout=true;delete this.forceLayout},onLayout:Ext.emptyFn,shouldBufferLayout:function(){var a=this.hasLayout;if(this.ownerCt){return a?!this.hasLayoutPending():false}return a},hasLayoutPending:function(){var a=false;this.ownerCt.bubble(function(b){if(b.layoutPending){a=true;return false}});return a},onShow:function(){Ext.Container.superclass.onShow.call(this);if(Ext.isDefined(this.deferLayout)){delete this.deferLayout;this.doLayout(true)}},getLayout:function(){if(!this.layout){var a=new Ext.layout.AutoLayout(this.layoutConfig);this.setLayout(a)}return this.layout},beforeDestroy:function(){var a;if(this.items){while(a=this.items.first()){this.doRemove(a,true)}}if(this.monitorResize){Ext.EventManager.removeResizeListener(this.doLayout,this)}Ext.destroy(this.layout);Ext.Container.superclass.beforeDestroy.call(this)},cascade:function(g,e,b){if(g.apply(e||this,b||[this])!==false){if(this.items){var d=this.items.items;for(var c=0,a=d.length;c<a;c++){if(d[c].cascade){d[c].cascade(g,e,b)}else{g.apply(e||d[c],b||[d[c]])}}}}return this},findById:function(c){var a=null,b=this;this.cascade(function(d){if(b!=d&&d.id===c){a=d;return false}});return a},findByType:function(b,a){return this.findBy(function(d){return d.isXType(b,a)})},find:function(b,a){return this.findBy(function(d){return d[b]===a})},findBy:function(d,c){var a=[],b=this;this.cascade(function(e){if(b!=e&&d.call(c||e,e,b)===true){a.push(e)}});return a},get:function(a){return this.getComponent(a)}});Ext.Container.LAYOUTS={};Ext.reg("container",Ext.Container);Ext.layout.ContainerLayout=Ext.extend(Object,{monitorResize:false,activeItem:null,constructor:function(a){this.id=Ext.id(null,"ext-layout-");Ext.apply(this,a)},type:"container",IEMeasureHack:function(k,g){var a=k.dom.childNodes,b=a.length,n,m=[],l,h,j;for(h=0;h<b;h++){n=a[h];l=Ext.get(n);if(l){m[h]=l.getStyle("display");l.setStyle({display:"none"})}}j=k?k.getViewSize(g):{};for(h=0;h<b;h++){n=a[h];l=Ext.get(n);if(l){l.setStyle({display:m[h]})}}return j},getLayoutTargetSize:Ext.EmptyFn,layout:function(){var a=this.container,b=a.getLayoutTarget();if(!(this.hasLayout||Ext.isEmpty(this.targetCls))){b.addClass(this.targetCls)}this.onLayout(a,b);a.fireEvent("afterlayout",a,this)},onLayout:function(a,b){this.renderAll(a,b)},isValidParent:function(b,a){return a&&b.getPositionEl().dom.parentNode==(a.dom||a)},renderAll:function(e,g){var b=e.items.items,d,h,a=b.length;for(d=0;d<a;d++){h=b[d];if(h&&(!h.rendered||!this.isValidParent(h,g))){this.renderItem(h,d,g)}}},renderItem:function(d,a,b){if(d){if(!d.rendered){d.render(b,a);this.configureItem(d)}else{if(!this.isValidParent(d,b)){if(Ext.isNumber(a)){a=b.dom.childNodes[a]}b.dom.insertBefore(d.getPositionEl().dom,a||null);d.container=b;this.configureItem(d)}}}},getRenderedItems:function(g){var e=g.getLayoutTarget(),h=g.items.items,a=h.length,d,j,b=[];for(d=0;d<a;d++){if((j=h[d]).rendered&&this.isValidParent(j,e)&&j.shouldLayout!==false){b.push(j)}}return b},configureItem:function(b){if(this.extraCls){var a=b.getPositionEl?b.getPositionEl():b;a.addClass(this.extraCls)}if(b.doLayout&&this.forceLayout){b.doLayout()}if(this.renderHidden&&b!=this.activeItem){b.hide()}},onRemove:function(b){if(this.activeItem==b){delete this.activeItem}if(b.rendered&&this.extraCls){var a=b.getPositionEl?b.getPositionEl():b;a.removeClass(this.extraCls)}},afterRemove:function(a){if(a.removeRestore){a.removeMode="container";delete a.removeRestore}},onResize:function(){var c=this.container,a;if(c.collapsed){return}if(a=c.bufferResize&&c.shouldBufferLayout()){if(!this.resizeTask){this.resizeTask=new Ext.util.DelayedTask(this.runLayout,this);this.resizeBuffer=Ext.isNumber(a)?a:50}c.layoutPending=true;this.resizeTask.delay(this.resizeBuffer)}else{this.runLayout()}},runLayout:function(){var a=this.container;this.layout();a.onLayout();delete a.layoutPending},setContainer:function(b){if(this.monitorResize&&b!=this.container){var a=this.container;if(a){a.un(a.resizeEvent,this.onResize,this)}if(b){b.on(b.resizeEvent,this.onResize,this)}}this.container=b},parseMargins:function(b){if(Ext.isNumber(b)){b=b.toString()}var c=b.split(" "),a=c.length;if(a==1){c[1]=c[2]=c[3]=c[0]}else{if(a==2){c[2]=c[0];c[3]=c[1]}else{if(a==3){c[3]=c[1]}}}return{top:parseInt(c[0],10)||0,right:parseInt(c[1],10)||0,bottom:parseInt(c[2],10)||0,left:parseInt(c[3],10)||0}},fieldTpl:(function(){var a=new Ext.Template('<div class="x-form-item {itemCls}" tabIndex="-1">','<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>','<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">','</div><div class="{clearCls}"></div>',"</div>");a.disableFormats=true;return a.compile()})(),destroy:function(){if(this.resizeTask&&this.resizeTask.cancel){this.resizeTask.cancel()}if(this.container){this.container.un(this.container.resizeEvent,this.onResize,this)}if(!Ext.isEmpty(this.targetCls)){var a=this.container.getLayoutTarget();if(a){a.removeClass(this.targetCls)}}}});Ext.layout.AutoLayout=Ext.extend(Ext.layout.ContainerLayout,{type:"auto",monitorResize:true,onLayout:function(d,g){Ext.layout.AutoLayout.superclass.onLayout.call(this,d,g);var e=this.getRenderedItems(d),a=e.length,b,h;for(b=0;b<a;b++){h=e[b];if(h.doLayout){h.doLayout(true)}}}});Ext.Container.LAYOUTS.auto=Ext.layout.AutoLayout;Ext.layout.FitLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"fit",getLayoutTargetSize:function(){var a=this.container.getLayoutTarget();if(!a){return{}}return a.getStyleSize()},onLayout:function(a,b){Ext.layout.FitLayout.superclass.onLayout.call(this,a,b);if(!a.collapsed){this.setItemSize(this.activeItem||a.items.itemAt(0),this.getLayoutTargetSize())}},setItemSize:function(b,a){if(b&&a.height>0){b.setSize(a)}}});Ext.Container.LAYOUTS.fit=Ext.layout.FitLayout;Ext.layout.CardLayout=Ext.extend(Ext.layout.FitLayout,{deferredRender:false,layoutOnCardChange:false,renderHidden:true,type:"card",setActiveItem:function(d){var a=this.activeItem,b=this.container;d=b.getComponent(d);if(d&&a!=d){if(a){a.hide();if(a.hidden!==true){return false}a.fireEvent("deactivate",a)}var c=d.doLayout&&(this.layoutOnCardChange||!d.rendered);this.activeItem=d;delete d.deferLayout;d.show();this.layout();if(c){d.doLayout()}d.fireEvent("activate",d)}},renderAll:function(a,b){if(this.deferredRender){this.renderItem(this.activeItem,undefined,b)}else{Ext.layout.CardLayout.superclass.renderAll.call(this,a,b)}}});Ext.Container.LAYOUTS.card=Ext.layout.CardLayout;Ext.layout.AnchorLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"anchor",defaultAnchor:"100%",parseAnchorRE:/^(r|right|b|bottom)$/i,getLayoutTargetSize:function(){var b=this.container.getLayoutTarget(),a={};if(b){a=b.getViewSize();if(Ext.isIE9m&&Ext.isStrict&&a.width==0){a=b.getStyleSize()}a.width-=b.getPadding("lr");a.height-=b.getPadding("tb")}return a},onLayout:function(m,w){Ext.layout.AnchorLayout.superclass.onLayout.call(this,m,w);var p=this.getLayoutTargetSize(),k=p.width,o=p.height,q=w.getStyle("overflow"),n=this.getRenderedItems(m),t=n.length,g=[],j,a,v,l,h,c,e,d,u=0,s,b;if(k<20&&o<20){return}if(m.anchorSize){if(typeof m.anchorSize=="number"){a=m.anchorSize}else{a=m.anchorSize.width;v=m.anchorSize.height}}else{a=m.initialConfig.width;v=m.initialConfig.height}for(s=0;s<t;s++){l=n[s];b=l.getPositionEl();if(!l.anchor&&l.items&&!Ext.isNumber(l.width)&&!(Ext.isIE6&&Ext.isStrict)){l.anchor=this.defaultAnchor}if(l.anchor){h=l.anchorSpec;if(!h){d=l.anchor.split(" ");l.anchorSpec=h={right:this.parseAnchor(d[0],l.initialConfig.width,a),bottom:this.parseAnchor(d[1],l.initialConfig.height,v)}}c=h.right?this.adjustWidthAnchor(h.right(k)-b.getMargins("lr"),l):undefined;e=h.bottom?this.adjustHeightAnchor(h.bottom(o)-b.getMargins("tb"),l):undefined;if(c||e){g.push({component:l,width:c||undefined,height:e||undefined})}}}for(s=0,t=g.length;s<t;s++){j=g[s];j.component.setSize(j.width,j.height)}if(q&&q!="hidden"&&!this.adjustmentPass){var r=this.getLayoutTargetSize();if(r.width!=p.width||r.height!=p.height){this.adjustmentPass=true;this.onLayout(m,w)}}delete this.adjustmentPass},parseAnchor:function(c,h,b){if(c&&c!="none"){var e;if(this.parseAnchorRE.test(c)){var g=b-h;return function(a){if(a!==e){e=a;return a-g}}}else{if(c.indexOf("%")!=-1){var d=parseFloat(c.replace("%",""))*0.01;return function(a){if(a!==e){e=a;return Math.floor(a*d)}}}else{c=parseInt(c,10);if(!isNaN(c)){return function(a){if(a!==e){e=a;return a+c}}}}}}return false},adjustWidthAnchor:function(b,a){return b},adjustHeightAnchor:function(b,a){return b}});Ext.Container.LAYOUTS.anchor=Ext.layout.AnchorLayout;Ext.layout.ColumnLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"column",extraCls:"x-column",scrollOffset:0,targetCls:"x-column-layout-ct",isValidParent:function(b,a){return this.innerCt&&b.getPositionEl().dom.parentNode==this.innerCt.dom},getLayoutTargetSize:function(){var b=this.container.getLayoutTarget(),a;if(b){a=b.getViewSize();if(Ext.isIE9m&&Ext.isStrict&&a.width==0){a=b.getStyleSize()}a.width-=b.getPadding("lr");a.height-=b.getPadding("tb")}return a},renderAll:function(a,b){if(!this.innerCt){this.innerCt=b.createChild({cls:"x-column-inner"});this.innerCt.createChild({cls:"x-clear"})}Ext.layout.ColumnLayout.superclass.renderAll.call(this,a,this.innerCt)},onLayout:function(e,k){var g=e.items.items,j=g.length,n,b,a,o=[];this.renderAll(e,k);var r=this.getLayoutTargetSize();if(Ext.isIE9m&&(r.width<1&&r.height<1)){return}var p=r.width-this.scrollOffset,d=r.height,q=p;this.innerCt.setWidth(p);for(b=0;b<j;b++){n=g[b];a=n.getPositionEl().getMargins("lr");o[b]=a;if(!n.columnWidth){q-=(n.getWidth()+a)}}q=q<0?0:q;for(b=0;b<j;b++){n=g[b];a=o[b];if(n.columnWidth){n.setSize(Math.floor(n.columnWidth*q)-a)}}if(Ext.isIE9m){if(b=k.getStyle("overflow")&&b!="hidden"&&!this.adjustmentPass){var l=this.getLayoutTargetSize();if(l.width!=r.width){this.adjustmentPass=true;this.onLayout(e,k)}}}delete this.adjustmentPass}});Ext.Container.LAYOUTS.column=Ext.layout.ColumnLayout;Ext.layout.BorderLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,rendered:false,type:"border",targetCls:"x-border-layout-ct",getLayoutTargetSize:function(){var a=this.container.getLayoutTarget();return a?a.getViewSize():{}},onLayout:function(g,I){var j,B,F,o,x=g.items.items,C=x.length;if(!this.rendered){j=[];for(B=0;B<C;B++){F=x[B];o=F.region;if(F.collapsed){j.push(F)}F.collapsed=false;if(!F.rendered){F.render(I,B);F.getPositionEl().addClass("x-border-panel")}this[o]=o!="center"&&F.split?new Ext.layout.BorderLayout.SplitRegion(this,F.initialConfig,o):new Ext.layout.BorderLayout.Region(this,F.initialConfig,o);this[o].render(I,F)}this.rendered=true}var v=this.getLayoutTargetSize();if(v.width<20||v.height<20){if(j){this.restoreCollapsed=j}return}else{if(this.restoreCollapsed){j=this.restoreCollapsed;delete this.restoreCollapsed}}var t=v.width,D=v.height,r=t,A=D,p=0,q=0,y=this.north,u=this.south,l=this.west,E=this.east,F=this.center,H,z,d,G;if(!F&&Ext.layout.BorderLayout.WARN!==false){throw"No center region defined in BorderLayout "+g.id}if(y&&y.isVisible()){H=y.getSize();z=y.getMargins();H.width=t-(z.left+z.right);H.x=z.left;H.y=z.top;p=H.height+H.y+z.bottom;A-=p;y.applyLayout(H)}if(u&&u.isVisible()){H=u.getSize();z=u.getMargins();H.width=t-(z.left+z.right);H.x=z.left;G=(H.height+z.top+z.bottom);H.y=D-G+z.top;A-=G;u.applyLayout(H)}if(l&&l.isVisible()){H=l.getSize();z=l.getMargins();H.height=A-(z.top+z.bottom);H.x=z.left;H.y=p+z.top;d=(H.width+z.left+z.right);q+=d;r-=d;l.applyLayout(H)}if(E&&E.isVisible()){H=E.getSize();z=E.getMargins();H.height=A-(z.top+z.bottom);d=(H.width+z.left+z.right);H.x=t-d+z.left;H.y=p+z.top;r-=d;E.applyLayout(H)}if(F){z=F.getMargins();var k={x:q+z.left,y:p+z.top,width:r-(z.left+z.right),height:A-(z.top+z.bottom)};F.applyLayout(k)}if(j){for(B=0,C=j.length;B<C;B++){j[B].collapse(false)}}if(Ext.isIE9m&&Ext.isStrict){I.repaint()}if(B=I.getStyle("overflow")&&B!="hidden"&&!this.adjustmentPass){var a=this.getLayoutTargetSize();if(a.width!=v.width||a.height!=v.height){this.adjustmentPass=true;this.onLayout(g,I)}}delete this.adjustmentPass},destroy:function(){var b=["north","south","east","west"],a,c;for(a=0;a<b.length;a++){c=this[b[a]];if(c){if(c.destroy){c.destroy()}else{if(c.split){c.split.destroy(true)}}}}Ext.layout.BorderLayout.superclass.destroy.call(this)}});Ext.layout.BorderLayout.Region=function(b,a,c){Ext.apply(this,a);this.layout=b;this.position=c;this.state={};if(typeof this.margins=="string"){this.margins=this.layout.parseMargins(this.margins)}this.margins=Ext.applyIf(this.margins||{},this.defaultMargins);if(this.collapsible){if(typeof this.cmargins=="string"){this.cmargins=this.layout.parseMargins(this.cmargins)}if(this.collapseMode=="mini"&&!this.cmargins){this.cmargins={left:0,top:0,right:0,bottom:0}}else{this.cmargins=Ext.applyIf(this.cmargins||{},c=="north"||c=="south"?this.defaultNSCMargins:this.defaultEWCMargins)}}};Ext.layout.BorderLayout.Region.prototype={collapsible:false,split:false,floatable:true,minWidth:50,minHeight:50,defaultMargins:{left:0,top:0,right:0,bottom:0},defaultNSCMargins:{left:5,top:5,right:5,bottom:5},defaultEWCMargins:{left:5,top:0,right:5,bottom:0},floatingZIndex:100,isCollapsed:false,render:function(b,c){this.panel=c;c.el.enableDisplayMode();this.targetEl=b;this.el=c.el;var a=c.getState,d=this.position;c.getState=function(){return Ext.apply(a.call(c)||{},this.state)}.createDelegate(this);if(d!="center"){c.allowQueuedExpand=false;c.on({beforecollapse:this.beforeCollapse,collapse:this.onCollapse,beforeexpand:this.beforeExpand,expand:this.onExpand,hide:this.onHide,show:this.onShow,scope:this});if(this.collapsible||this.floatable){c.collapseEl="el";c.slideAnchor=this.getSlideAnchor()}if(c.tools&&c.tools.toggle){c.tools.toggle.addClass("x-tool-collapse-"+d);c.tools.toggle.addClassOnOver("x-tool-collapse-"+d+"-over")}}},getCollapsedEl:function(){if(!this.collapsedEl){if(!this.toolTemplate){var b=new Ext.Template('<div class="x-tool x-tool-{id}">&#160;</div>');b.disableFormats=true;b.compile();Ext.layout.BorderLayout.Region.prototype.toolTemplate=b}this.collapsedEl=this.targetEl.createChild({cls:"x-layout-collapsed x-layout-collapsed-"+this.position,id:this.panel.id+"-xcollapsed"});this.collapsedEl.enableDisplayMode("block");if(this.collapseMode=="mini"){this.collapsedEl.addClass("x-layout-cmini-"+this.position);this.miniCollapsedEl=this.collapsedEl.createChild({cls:"x-layout-mini x-layout-mini-"+this.position,html:"&#160;"});this.miniCollapsedEl.addClassOnOver("x-layout-mini-over");this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this.onExpandClick,this,{stopEvent:true})}else{if(this.collapsible!==false&&!this.hideCollapseTool){var a=this.expandToolEl=this.toolTemplate.append(this.collapsedEl.dom,{id:"expand-"+this.position},true);a.addClassOnOver("x-tool-expand-"+this.position+"-over");a.on("click",this.onExpandClick,this,{stopEvent:true})}if(this.floatable!==false||this.titleCollapse){this.collapsedEl.addClassOnOver("x-layout-collapsed-over");this.collapsedEl.on("click",this[this.floatable?"collapseClick":"onExpandClick"],this)}}}return this.collapsedEl},onExpandClick:function(a){if(this.isSlid){this.panel.expand(false)}else{this.panel.expand()}},onCollapseClick:function(a){this.panel.collapse()},beforeCollapse:function(c,a){this.lastAnim=a;if(this.splitEl){this.splitEl.hide()}this.getCollapsedEl().show();var b=this.panel.getEl();this.originalZIndex=b.getStyle("z-index");b.setStyle("z-index",100);this.isCollapsed=true;this.layout.layout()},onCollapse:function(a){this.panel.el.setStyle("z-index",1);if(this.lastAnim===false||this.panel.animCollapse===false){this.getCollapsedEl().dom.style.visibility="visible"}else{this.getCollapsedEl().slideIn(this.panel.slideAnchor,{duration:0.2})}this.state.collapsed=true;this.panel.saveState()},beforeExpand:function(a){if(this.isSlid){this.afterSlideIn()}var b=this.getCollapsedEl();this.el.show();if(this.position=="east"||this.position=="west"){this.panel.setSize(undefined,b.getHeight())}else{this.panel.setSize(b.getWidth(),undefined)}b.hide();b.dom.style.visibility="hidden";this.panel.el.setStyle("z-index",this.floatingZIndex)},onExpand:function(){this.isCollapsed=false;if(this.splitEl){this.splitEl.show()}this.layout.layout();this.panel.el.setStyle("z-index",this.originalZIndex);this.state.collapsed=false;this.panel.saveState()},collapseClick:function(a){if(this.isSlid){a.stopPropagation();this.slideIn()}else{a.stopPropagation();this.slideOut()}},onHide:function(){if(this.isCollapsed){this.getCollapsedEl().hide()}else{if(this.splitEl){this.splitEl.hide()}}},onShow:function(){if(this.isCollapsed){this.getCollapsedEl().show()}else{if(this.splitEl){this.splitEl.show()}}},isVisible:function(){return !this.panel.hidden},getMargins:function(){return this.isCollapsed&&this.cmargins?this.cmargins:this.margins},getSize:function(){return this.isCollapsed?this.getCollapsedEl().getSize():this.panel.getSize()},setPanel:function(a){this.panel=a},getMinWidth:function(){return this.minWidth},getMinHeight:function(){return this.minHeight},applyLayoutCollapsed:function(a){var b=this.getCollapsedEl();b.setLeftTop(a.x,a.y);b.setSize(a.width,a.height)},applyLayout:function(a){if(this.isCollapsed){this.applyLayoutCollapsed(a)}else{this.panel.setPosition(a.x,a.y);this.panel.setSize(a.width,a.height)}},beforeSlide:function(){this.panel.beforeEffect()},afterSlide:function(){this.panel.afterEffect()},initAutoHide:function(){if(this.autoHide!==false){if(!this.autoHideHd){this.autoHideSlideTask=new Ext.util.DelayedTask(this.slideIn,this);this.autoHideHd={mouseout:function(a){if(!a.within(this.el,true)){this.autoHideSlideTask.delay(500)}},mouseover:function(a){this.autoHideSlideTask.cancel()},scope:this}}this.el.on(this.autoHideHd);this.collapsedEl.on(this.autoHideHd)}},clearAutoHide:function(){if(this.autoHide!==false){this.el.un("mouseout",this.autoHideHd.mouseout);this.el.un("mouseover",this.autoHideHd.mouseover);this.collapsedEl.un("mouseout",this.autoHideHd.mouseout);this.collapsedEl.un("mouseover",this.autoHideHd.mouseover)}},clearMonitor:function(){Ext.getDoc().un("click",this.slideInIf,this)},slideOut:function(){if(this.isSlid||this.el.hasActiveFx()){return}this.isSlid=true;var b=this.panel.tools,c,a;if(b&&b.toggle){b.toggle.hide()}this.el.show();a=this.panel.collapsed;this.panel.collapsed=false;if(this.position=="east"||this.position=="west"){c=this.panel.deferHeight;this.panel.deferHeight=false;this.panel.setSize(undefined,this.collapsedEl.getHeight());this.panel.deferHeight=c}else{this.panel.setSize(this.collapsedEl.getWidth(),undefined)}this.panel.collapsed=a;this.restoreLT=[this.el.dom.style.left,this.el.dom.style.top];this.el.alignTo(this.collapsedEl,this.getCollapseAnchor());this.el.setStyle("z-index",this.floatingZIndex+2);this.panel.el.replaceClass("x-panel-collapsed","x-panel-floating");if(this.animFloat!==false){this.beforeSlide();this.el.slideIn(this.getSlideAnchor(),{callback:function(){this.afterSlide();this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)},scope:this,block:true})}else{this.initAutoHide();Ext.getDoc().on("click",this.slideInIf,this)}},afterSlideIn:function(){this.clearAutoHide();this.isSlid=false;this.clearMonitor();this.el.setStyle("z-index","");this.panel.el.replaceClass("x-panel-floating","x-panel-collapsed");this.el.dom.style.left=this.restoreLT[0];this.el.dom.style.top=this.restoreLT[1];var a=this.panel.tools;if(a&&a.toggle){a.toggle.show()}},slideIn:function(a){if(!this.isSlid||this.el.hasActiveFx()){Ext.callback(a);return}this.isSlid=false;if(this.animFloat!==false){this.beforeSlide();this.el.slideOut(this.getSlideAnchor(),{callback:function(){this.el.hide();this.afterSlide();this.afterSlideIn();Ext.callback(a)},scope:this,block:true})}else{this.el.hide();this.afterSlideIn()}},slideInIf:function(a){if(!a.within(this.el)){this.slideIn()}},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 a=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 b=this.collapsedEl,a=this.cmargins;switch(this.position){case"west":return[-(a.right+b.getWidth()+a.left),0];break;case"east":return[a.right+b.getWidth()+a.left,0];break;case"north":return[0,-(a.top+a.bottom+b.getHeight())];break;case"south":return[0,a.top+a.bottom+b.getHeight()];break}},destroy:function(){if(this.autoHideSlideTask&&this.autoHideSlideTask.cancel){this.autoHideSlideTask.cancel()}Ext.destroyMembers(this,"miniCollapsedEl","collapsedEl","expandToolEl")}};Ext.layout.BorderLayout.SplitRegion=function(b,a,c){Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this,b,a,c);this.applyLayout=this.applyFns[c]};Ext.extend(Ext.layout.BorderLayout.SplitRegion,Ext.layout.BorderLayout.Region,{splitTip:"Drag to resize.",collapsibleSplitTip:"Drag to resize. Double click to hide.",useSplitTips:false,splitSettings:{north:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.TOP,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},south:{orientation:Ext.SplitBar.VERTICAL,placement:Ext.SplitBar.BOTTOM,maxFn:"getVMaxSize",minProp:"minHeight",maxProp:"maxHeight"},east:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.RIGHT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"},west:{orientation:Ext.SplitBar.HORIZONTAL,placement:Ext.SplitBar.LEFT,maxFn:"getHMaxSize",minProp:"minWidth",maxProp:"maxWidth"}},applyFns:{west:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;this.panel.setPosition(c.x,c.y);var a=d.offsetWidth;b.left=(c.x+c.width-a)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},east:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetWidth;this.panel.setPosition(c.x+a,c.y);b.left=(c.x)+"px";b.top=(c.y)+"px";b.height=Math.max(0,c.height)+"px";this.panel.setSize(c.width-a,c.height)},north:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y);b.left=(c.x)+"px";b.top=(c.y+c.height-a)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)},south:function(c){if(this.isCollapsed){return this.applyLayoutCollapsed(c)}var d=this.splitEl.dom,b=d.style;var a=d.offsetHeight;this.panel.setPosition(c.x,c.y+a);b.left=(c.x)+"px";b.top=(c.y)+"px";b.width=Math.max(0,c.width)+"px";this.panel.setSize(c.width,c.height-a)}},render:function(a,c){Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this,a,c);var d=this.position;this.splitEl=a.createChild({cls:"x-layout-split x-layout-split-"+d,html:"&#160;",id:this.panel.id+"-xsplit"});if(this.collapseMode=="mini"){this.miniSplitEl=this.splitEl.createChild({cls:"x-layout-mini x-layout-mini-"+d,html:"&#160;"});this.miniSplitEl.addClassOnOver("x-layout-mini-over");this.miniSplitEl.on("click",this.onCollapseClick,this,{stopEvent:true})}var b=this.splitSettings[d];this.split=new Ext.SplitBar(this.splitEl.dom,c.el,b.orientation);this.split.tickSize=this.tickSize;this.split.placement=b.placement;this.split.getMaximumSize=this[b.maxFn].createDelegate(this);this.split.minSize=this.minSize||this[b.minProp];this.split.on("beforeapply",this.onSplitMove,this);this.split.useShim=this.useShim===true;this.maxSize=this.maxSize||this[b.maxProp];if(c.hidden){this.splitEl.hide()}if(this.useSplitTips){this.splitEl.dom.title=this.collapsible?this.collapsibleSplitTip:this.splitTip}if(this.collapsible){this.splitEl.on("dblclick",this.onCollapseClick,this)}},getSize:function(){if(this.isCollapsed){return this.collapsedEl.getSize()}var a=this.panel.getSize();if(this.position=="north"||this.position=="south"){a.height+=this.splitEl.dom.offsetHeight}else{a.width+=this.splitEl.dom.offsetWidth}return a},getHMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getWidth()+a.el.getWidth())-a.getMinWidth())},getVMaxSize:function(){var b=this.maxSize||10000;var a=this.layout.center;return Math.min(b,(this.el.getHeight()+a.el.getHeight())-a.getMinHeight())},onSplitMove:function(b,a){var c=this.panel.getSize();this.lastSplitSize=a;if(this.position=="north"||this.position=="south"){this.panel.setSize(c.width,a);this.state.height=a}else{this.panel.setSize(a,c.height);this.state.width=a}this.layout.layout();this.panel.saveState();return false},getSplitBar:function(){return this.split},destroy:function(){Ext.destroy(this.miniSplitEl,this.split,this.splitEl);Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.border=Ext.layout.BorderLayout;Ext.layout.FormLayout=Ext.extend(Ext.layout.AnchorLayout,{labelSeparator:":",trackLabels:true,type:"form",onRemove:function(d){Ext.layout.FormLayout.superclass.onRemove.call(this,d);if(this.trackLabels){d.un("show",this.onFieldShow,this);d.un("hide",this.onFieldHide,this)}var b=d.getPositionEl(),a=d.getItemCt&&d.getItemCt();if(d.rendered&&a){if(b&&b.dom){b.insertAfter(a)}Ext.destroy(a);Ext.destroyMembers(d,"label","itemCt");if(d.customItemCt){Ext.destroyMembers(d,"getItemCt","customItemCt")}}},setContainer:function(a){Ext.layout.FormLayout.superclass.setContainer.call(this,a);a.labelAlign=a.labelAlign||this.labelAlign;if(a.labelAlign){a.addClass("x-form-label-"+a.labelAlign)}if(a.hideLabels||this.hideLabels){Ext.apply(this,{labelStyle:"display:none",elementStyle:"padding-left:0;",labelAdjust:0})}else{this.labelSeparator=Ext.isDefined(a.labelSeparator)?a.labelSeparator:this.labelSeparator;a.labelWidth=a.labelWidth||this.labelWidth||100;if(Ext.isNumber(a.labelWidth)){var b=a.labelPad||this.labelPad;b=Ext.isNumber(b)?b:5;Ext.apply(this,{labelAdjust:a.labelWidth+b,labelStyle:"width:"+a.labelWidth+"px;",elementStyle:"padding-left:"+(a.labelWidth+b)+"px"})}if(a.labelAlign=="top"){Ext.apply(this,{labelStyle:"width:auto;",labelAdjust:0,elementStyle:"padding-left:0;"})}}},isHide:function(a){return a.hideLabel||this.container.hideLabels},onFieldShow:function(a){a.getItemCt().removeClass("x-hide-"+a.hideMode);if(a.isComposite){a.doLayout()}},onFieldHide:function(a){a.getItemCt().addClass("x-hide-"+a.hideMode)},getLabelStyle:function(e){var b="",c=[this.labelStyle,e];for(var d=0,a=c.length;d<a;++d){if(c[d]){b+=c[d];if(b.substr(-1,1)!=";"){b+=";"}}}return b},renderItem:function(e,a,d){if(e&&(e.isFormField||e.fieldLabel)&&e.inputType!="hidden"){var b=this.getTemplateArgs(e);if(Ext.isNumber(a)){a=d.dom.childNodes[a]||null}if(a){e.itemCt=this.fieldTpl.insertBefore(a,b,true)}else{e.itemCt=this.fieldTpl.append(d,b,true)}if(!e.getItemCt){Ext.apply(e,{getItemCt:function(){return e.itemCt},customItemCt:true})}e.label=e.getItemCt().child("label.x-form-item-label");if(!e.rendered){e.render("x-form-el-"+e.id)}else{if(!this.isValidParent(e,d)){Ext.fly("x-form-el-"+e.id).appendChild(e.getPositionEl())}}if(this.trackLabels){if(e.hidden){this.onFieldHide(e)}e.on({scope:this,show:this.onFieldShow,hide:this.onFieldHide})}this.configureItem(e)}else{Ext.layout.FormLayout.superclass.renderItem.apply(this,arguments)}},getTemplateArgs:function(c){var a=!c.fieldLabel||c.hideLabel,b=(c.itemCls||this.container.itemCls||"")+(c.hideLabel?" x-hide-label":"");if(Ext.isIE9&&Ext.isIEQuirks&&c instanceof Ext.form.TextField){b+=" x-input-wrapper"}return{id:c.id,label:c.fieldLabel,itemCls:b,clearCls:c.clearCls||"x-form-clear-left",labelStyle:this.getLabelStyle(c.labelStyle),elementStyle:this.elementStyle||"",labelSeparator:a?"":(Ext.isDefined(c.labelSeparator)?c.labelSeparator:this.labelSeparator)}},adjustWidthAnchor:function(a,d){if(d.label&&!this.isHide(d)&&(this.container.labelAlign!="top")){var b=Ext.isIE6||Ext.isIEQuirks;return a-this.labelAdjust+(b?-3:0)}return a},adjustHeightAnchor:function(a,b){if(b.label&&!this.isHide(b)&&(this.container.labelAlign=="top")){return a-b.label.getHeight()}return a},isValidParent:function(b,a){return a&&this.container.getEl().contains(b.getPositionEl())}});Ext.Container.LAYOUTS.form=Ext.layout.FormLayout;Ext.layout.AccordionLayout=Ext.extend(Ext.layout.FitLayout,{fill:true,autoWidth:true,titleCollapse:true,hideCollapseTool:false,collapseFirst:false,animate:false,sequence:false,activeOnTop:false,type:"accordion",renderItem:function(a){if(this.animate===false){a.animCollapse=false}a.collapsible=true;if(this.autoWidth){a.autoWidth=true}if(this.titleCollapse){a.titleCollapse=true}if(this.hideCollapseTool){a.hideCollapseTool=true}if(this.collapseFirst!==undefined){a.collapseFirst=this.collapseFirst}if(!this.activeItem&&!a.collapsed){this.setActiveItem(a,true)}else{if(this.activeItem&&this.activeItem!=a){a.collapsed=true}}Ext.layout.AccordionLayout.superclass.renderItem.apply(this,arguments);a.header.addClass("x-accordion-hd");a.on("beforeexpand",this.beforeExpand,this)},onRemove:function(a){Ext.layout.AccordionLayout.superclass.onRemove.call(this,a);if(a.rendered){a.header.removeClass("x-accordion-hd")}a.un("beforeexpand",this.beforeExpand,this)},beforeExpand:function(c,b){var a=this.activeItem;if(a){if(this.sequence){delete this.activeItem;if(!a.collapsed){a.collapse({callback:function(){c.expand(b||true)},scope:this});return false}}else{a.collapse(this.animate)}}this.setActive(c);if(this.activeOnTop){c.el.dom.parentNode.insertBefore(c.el.dom,c.el.dom.parentNode.firstChild)}this.layout()},setItemSize:function(g,e){if(this.fill&&g){var d=0,c,b=this.getRenderedItems(this.container),a=b.length,h;for(c=0;c<a;c++){if((h=b[c])!=g&&!h.hidden){d+=h.header.getHeight()}}e.height-=d;g.setSize(e)}},setActiveItem:function(a){this.setActive(a,true)},setActive:function(c,b){var a=this.activeItem;c=this.container.getComponent(c);if(a!=c){if(c.rendered&&c.collapsed&&b){c.expand()}else{if(a){a.fireEvent("deactivate",a)}this.activeItem=c;c.fireEvent("activate",c)}}}});Ext.Container.LAYOUTS.accordion=Ext.layout.AccordionLayout;Ext.layout.Accordion=Ext.layout.AccordionLayout;Ext.layout.TableLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:false,type:"table",targetCls:"x-table-layout-ct",tableAttrs:null,setContainer:function(a){Ext.layout.TableLayout.superclass.setContainer.call(this,a);this.currentRow=0;this.currentColumn=0;this.cells=[]},onLayout:function(d,g){var e=d.items.items,a=e.length,h,b;if(!this.table){g.addClass("x-table-layout-ct");this.table=g.createChild(Ext.apply({tag:"table",cls:"x-table-layout",cellspacing:0,cn:{tag:"tbody"}},this.tableAttrs),null,true)}this.renderAll(d,g)},getRow:function(a){var b=this.table.tBodies[0].childNodes[a];if(!b){b=document.createElement("tr");this.table.tBodies[0].appendChild(b)}return b},getNextCell:function(j){var a=this.getNextNonSpan(this.currentColumn,this.currentRow);var g=this.currentColumn=a[0],e=this.currentRow=a[1];for(var i=e;i<e+(j.rowspan||1);i++){if(!this.cells[i]){this.cells[i]=[]}for(var d=g;d<g+(j.colspan||1);d++){this.cells[i][d]=true}}var h=document.createElement("td");if(j.cellId){h.id=j.cellId}var b="x-table-layout-cell";if(j.cellCls){b+=" "+j.cellCls}h.className=b;if(j.colspan){h.colSpan=j.colspan}if(j.rowspan){h.rowSpan=j.rowspan}this.getRow(e).appendChild(h);return h},getNextNonSpan:function(a,c){var b=this.columns;while((b&&a>=b)||(this.cells[c]&&this.cells[c][a])){if(b&&a>=b){c++;a=0}else{a++}}return[a,c]},renderItem:function(e,a,d){if(!this.table){this.table=d.createChild(Ext.apply({tag:"table",cls:"x-table-layout",cellspacing:0,cn:{tag:"tbody"}},this.tableAttrs),null,true)}if(e&&!e.rendered){e.render(this.getNextCell(e));this.configureItem(e)}else{if(e&&!this.isValidParent(e,d)){var b=this.getNextCell(e);b.insertBefore(e.getPositionEl().dom,null);e.container=Ext.get(b);this.configureItem(e)}}},isValidParent:function(b,a){return b.getPositionEl().up("table",5).dom.parentNode===(a.dom||a)},destroy:function(){delete this.table;Ext.layout.TableLayout.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.table=Ext.layout.TableLayout;Ext.layout.AbsoluteLayout=Ext.extend(Ext.layout.AnchorLayout,{extraCls:"x-abs-layout-item",type:"absolute",onLayout:function(a,b){b.position();this.paddingLeft=b.getPadding("l");this.paddingTop=b.getPadding("t");Ext.layout.AbsoluteLayout.superclass.onLayout.call(this,a,b)},adjustWidthAnchor:function(b,a){return b?b-a.getPosition(true)[0]+this.paddingLeft:b},adjustHeightAnchor:function(b,a){return b?b-a.getPosition(true)[1]+this.paddingTop:b}});Ext.Container.LAYOUTS.absolute=Ext.layout.AbsoluteLayout;Ext.layout.BoxLayout=Ext.extend(Ext.layout.ContainerLayout,{defaultMargins:{left:0,top:0,right:0,bottom:0},padding:"0",pack:"start",monitorResize:true,type:"box",scrollOffset:0,extraCls:"x-box-item",targetCls:"x-box-layout-ct",innerCls:"x-box-inner",constructor:function(a){Ext.layout.BoxLayout.superclass.constructor.call(this,a);if(Ext.isString(this.defaultMargins)){this.defaultMargins=this.parseMargins(this.defaultMargins)}var d=this.overflowHandler;if(typeof d=="string"){d={type:d}}var c="none";if(d&&d.type!=undefined){c=d.type}var b=Ext.layout.boxOverflow[c];if(b[this.type]){b=b[this.type]}this.overflowHandler=new b(this,d)},onLayout:function(b,h){Ext.layout.BoxLayout.superclass.onLayout.call(this,b,h);var d=this.getLayoutTargetSize(),i=this.getVisibleItems(b),c=this.calculateChildBoxes(i,d),g=c.boxes,j=c.meta;if(d.width>0){var k=this.overflowHandler,a=j.tooNarrow?"handleOverflow":"clearOverflow";var e=k[a](c,d);if(e){if(e.targetSize){d=e.targetSize}if(e.recalculate){i=this.getVisibleItems(b);c=this.calculateChildBoxes(i,d);g=c.boxes}}}this.layoutTargetLastSize=d;this.childBoxCache=c;this.updateInnerCtSize(d,c);this.updateChildBoxes(g);this.handleTargetOverflow(d,b,h)},updateChildBoxes:function(c){for(var b=0,e=c.length;b<e;b++){var d=c[b],a=d.component;if(d.dirtySize){a.setSize(d.width,d.height)}if(isNaN(d.left)||isNaN(d.top)){continue}a.setPosition(d.left,d.top)}},updateInnerCtSize:function(c,h){var i=this.align,g=this.padding,e=c.width,a=c.height;if(this.type=="hbox"){var b=e,d=h.meta.maxHeight+g.top+g.bottom;if(i=="stretch"){d=a}else{if(i=="middle"){d=Math.max(a,d)}}}else{var d=a,b=h.meta.maxWidth+g.left+g.right;if(i=="stretch"){b=e}else{if(i=="center"){b=Math.max(e,b)}}}this.innerCt.setSize(b||undefined,d||undefined)},handleTargetOverflow:function(d,a,c){var e=c.getStyle("overflow");if(e&&e!="hidden"&&!this.adjustmentPass){var b=this.getLayoutTargetSize();if(b.width!=d.width||b.height!=d.height){this.adjustmentPass=true;this.onLayout(a,c)}}delete this.adjustmentPass},isValidParent:function(b,a){return this.innerCt&&b.getPositionEl().dom.parentNode==this.innerCt.dom},getVisibleItems:function(g){var g=g||this.container,e=g.getLayoutTarget(),h=g.items.items,a=h.length,d,j,b=[];for(d=0;d<a;d++){if((j=h[d]).rendered&&this.isValidParent(j,e)&&j.hidden!==true&&j.collapsed!==true&&j.shouldLayout!==false){b.push(j)}}return b},renderAll:function(a,b){if(!this.innerCt){this.innerCt=b.createChild({cls:this.innerCls});this.padding=this.parseMargins(this.padding)}Ext.layout.BoxLayout.superclass.renderAll.call(this,a,this.innerCt)},getLayoutTargetSize:function(){var b=this.container.getLayoutTarget(),a;if(b){a=b.getViewSize();if(Ext.isIE9m&&Ext.isStrict&&a.width==0){a=b.getStyleSize()}a.width-=b.getPadding("lr");a.height-=b.getPadding("tb")}return a},renderItem:function(a){if(Ext.isString(a.margins)){a.margins=this.parseMargins(a.margins)}else{if(!a.margins){a.margins=this.defaultMargins}}Ext.layout.BoxLayout.superclass.renderItem.apply(this,arguments)},destroy:function(){Ext.destroy(this.overflowHandler);Ext.layout.BoxLayout.superclass.destroy.apply(this,arguments)}});Ext.layout.boxOverflow.None=Ext.extend(Object,{constructor:function(b,a){this.layout=b;Ext.apply(this,a||{})},handleOverflow:Ext.emptyFn,clearOverflow:Ext.emptyFn});Ext.layout.boxOverflow.none=Ext.layout.boxOverflow.None;Ext.layout.boxOverflow.Menu=Ext.extend(Ext.layout.boxOverflow.None,{afterCls:"x-strip-right",noItemsMenuText:'<div class="x-toolbar-no-items">(None)</div>',constructor:function(a){Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this,arguments);this.menuItems=[]},createInnerElements:function(){if(!this.afterCt){this.afterCt=this.layout.innerCt.insertSibling({cls:this.afterCls},"before")}},clearOverflow:function(a,g){var e=g.width+(this.afterCt?this.afterCt.getWidth():0),b=this.menuItems;this.hideTrigger();for(var c=0,d=b.length;c<d;c++){b.pop().component.show()}return{targetSize:{height:g.height,width:e}}},showTrigger:function(){this.createMenu();this.menuTrigger.show()},hideTrigger:function(){if(this.menuTrigger!=undefined){this.menuTrigger.hide()}},beforeMenuShow:function(h){var b=this.menuItems,a=b.length,g,e;var c=function(j,i){return j.isXType("buttongroup")&&!(i instanceof Ext.Toolbar.Separator)};this.clearMenu();h.removeAll();for(var d=0;d<a;d++){g=b[d].component;if(e&&(c(g,e)||c(e,g))){h.add("-")}this.addComponentToMenu(h,g);e=g}if(h.items.length<1){h.add(this.noItemsMenuText)}},createMenuConfig:function(c,a){var b=Ext.apply({},c.initialConfig),d=c.toggleGroup;Ext.copyTo(b,c,["iconCls","icon","itemId","disabled","handler","scope","menu"]);Ext.apply(b,{text:c.overflowText||c.text,hideOnClick:a});if(d||c.enableToggle){Ext.apply(b,{group:d,checked:c.pressed,listeners:{checkchange:function(g,e){c.toggle(e)}}})}delete b.ownerCt;delete b.xtype;delete b.id;return b},addComponentToMenu:function(b,a){if(a instanceof Ext.Toolbar.Separator){b.add("-")}else{if(Ext.isFunction(a.isXType)){if(a.isXType("splitbutton")){b.add(this.createMenuConfig(a,true))}else{if(a.isXType("button")){b.add(this.createMenuConfig(a,!a.menu))}else{if(a.isXType("buttongroup")){a.items.each(function(c){this.addComponentToMenu(b,c)},this)}}}}}},clearMenu:function(){var a=this.moreMenu;if(a&&a.items){a.items.each(function(b){delete b.menu})}},createMenu:function(){if(!this.menuTrigger){this.createInnerElements();this.menu=new Ext.menu.Menu({ownerCt:this.layout.container,listeners:{scope:this,beforeshow:this.beforeMenuShow}});this.menuTrigger=new Ext.Button({iconCls:"x-toolbar-more-icon",cls:"x-toolbar-more",menu:this.menu,renderTo:this.afterCt})}},destroy:function(){Ext.destroy(this.menu,this.menuTrigger)}});Ext.layout.boxOverflow.menu=Ext.layout.boxOverflow.Menu;Ext.layout.boxOverflow.HorizontalMenu=Ext.extend(Ext.layout.boxOverflow.Menu,{constructor:function(){Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this,arguments);var c=this,b=c.layout,a=b.calculateChildBoxes;b.calculateChildBoxes=function(d,i){var l=a.apply(b,arguments),k=l.meta,e=c.menuItems;var j=0;for(var g=0,h=e.length;g<h;g++){j+=e[g].width}k.minimumWidth+=j;k.tooNarrow=k.minimumWidth>i.width;return l}},handleOverflow:function(d,h){this.showTrigger();var k=h.width-this.afterCt.getWidth(),l=d.boxes,e=0,r=false;for(var o=0,c=l.length;o<c;o++){e+=l[o].width}var a=k-e,g=0;for(var o=0,c=this.menuItems.length;o<c;o++){var n=this.menuItems[o],m=n.component,b=n.width;if(b<a){m.show();a-=b;g++;r=true}else{break}}if(r){this.menuItems=this.menuItems.slice(g)}else{for(var j=l.length-1;j>=0;j--){var q=l[j].component,p=l[j].left+l[j].width;if(p>=k){this.menuItems.unshift({component:q,width:l[j].width});q.hide()}else{break}}}if(this.menuItems.length==0){this.hideTrigger()}return{targetSize:{height:h.height,width:k},recalculate:r}}});Ext.layout.boxOverflow.menu.hbox=Ext.layout.boxOverflow.HorizontalMenu;Ext.layout.boxOverflow.Scroller=Ext.extend(Ext.layout.boxOverflow.None,{animateScroll:true,scrollIncrement:100,wheelIncrement:3,scrollRepeatInterval:400,scrollDuration:0.4,beforeCls:"x-strip-left",afterCls:"x-strip-right",scrollerCls:"x-strip-scroller",beforeScrollerCls:"x-strip-scroller-left",afterScrollerCls:"x-strip-scroller-right",createWheelListener:function(){this.layout.innerCt.on({scope:this,mousewheel:function(a){a.stopEvent();this.scrollBy(a.getWheelDelta()*this.wheelIncrement*-1,false)}})},handleOverflow:function(a,b){this.createInnerElements();this.showScrollers()},clearOverflow:function(){this.hideScrollers()},showScrollers:function(){this.createScrollers();this.beforeScroller.show();this.afterScroller.show();this.updateScrollButtons()},hideScrollers:function(){if(this.beforeScroller!=undefined){this.beforeScroller.hide();this.afterScroller.hide()}},createScrollers:function(){if(!this.beforeScroller&&!this.afterScroller){var a=this.beforeCt.createChild({cls:String.format("{0} {1} ",this.scrollerCls,this.beforeScrollerCls)});var b=this.afterCt.createChild({cls:String.format("{0} {1}",this.scrollerCls,this.afterScrollerCls)});a.addClassOnOver(this.beforeScrollerCls+"-hover");b.addClassOnOver(this.afterScrollerCls+"-hover");a.setVisibilityMode(Ext.Element.DISPLAY);b.setVisibilityMode(Ext.Element.DISPLAY);this.beforeRepeater=new Ext.util.ClickRepeater(a,{interval:this.scrollRepeatInterval,handler:this.scrollLeft,scope:this});this.afterRepeater=new Ext.util.ClickRepeater(b,{interval:this.scrollRepeatInterval,handler:this.scrollRight,scope:this});this.beforeScroller=a;this.afterScroller=b}},destroy:function(){Ext.destroy(this.beforeScroller,this.afterScroller,this.beforeRepeater,this.afterRepeater,this.beforeCt,this.afterCt)},scrollBy:function(b,a){this.scrollTo(this.getScrollPosition()+b,a)},getItem:function(a){if(Ext.isString(a)){a=Ext.getCmp(a)}else{if(Ext.isNumber(a)){a=this.items[a]}}return a},getScrollAnim:function(){return{duration:this.scrollDuration,callback:this.updateScrollButtons,scope:this}},updateScrollButtons:function(){if(this.beforeScroller==undefined||this.afterScroller==undefined){return}var d=this.atExtremeBefore()?"addClass":"removeClass",c=this.atExtremeAfter()?"addClass":"removeClass",a=this.beforeScrollerCls+"-disabled",b=this.afterScrollerCls+"-disabled";this.beforeScroller[d](a);this.afterScroller[c](b);this.scrolling=false},atExtremeBefore:function(){return this.getScrollPosition()===0},scrollLeft:function(a){this.scrollBy(-this.scrollIncrement,a)},scrollRight:function(a){this.scrollBy(this.scrollIncrement,a)},scrollToItem:function(d,b){d=this.getItem(d);if(d!=undefined){var a=this.getItemVisibility(d);if(!a.fullyVisible){var c=d.getBox(true,true),e=c.x;if(a.hiddenRight){e-=(this.layout.innerCt.getWidth()-c.width)}this.scrollTo(e,b)}}},getItemVisibility:function(e){var d=this.getItem(e).getBox(true,true),a=d.x,c=d.x+d.width,g=this.getScrollPosition(),b=this.layout.innerCt.getWidth()+g;return{hiddenLeft:a<g,hiddenRight:c>b,fullyVisible:a>g&&c<b}}});Ext.layout.boxOverflow.scroller=Ext.layout.boxOverflow.Scroller;Ext.layout.boxOverflow.VerticalScroller=Ext.extend(Ext.layout.boxOverflow.Scroller,{scrollIncrement:75,wheelIncrement:2,handleOverflow:function(a,b){Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this,arguments);return{targetSize:{height:b.height-(this.beforeCt.getHeight()+this.afterCt.getHeight()),width:b.width}}},createInnerElements:function(){var a=this.layout.innerCt;if(!this.beforeCt){this.beforeCt=a.insertSibling({cls:this.beforeCls},"before");this.afterCt=a.insertSibling({cls:this.afterCls},"after");this.createWheelListener()}},scrollTo:function(a,b){var d=this.getScrollPosition(),c=a.constrain(0,this.getMaxScrollBottom());if(c!=d&&!this.scrolling){if(b==undefined){b=this.animateScroll}this.layout.innerCt.scrollTo("top",c,b?this.getScrollAnim():false);if(b){this.scrolling=true}else{this.scrolling=false;this.updateScrollButtons()}}},getScrollPosition:function(){return parseInt(this.layout.innerCt.dom.scrollTop,10)||0},getMaxScrollBottom:function(){return this.layout.innerCt.dom.scrollHeight-this.layout.innerCt.getHeight()},atExtremeAfter:function(){return this.getScrollPosition()>=this.getMaxScrollBottom()}});Ext.layout.boxOverflow.scroller.vbox=Ext.layout.boxOverflow.VerticalScroller;Ext.layout.boxOverflow.HorizontalScroller=Ext.extend(Ext.layout.boxOverflow.Scroller,{handleOverflow:function(a,b){Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this,arguments);return{targetSize:{height:b.height,width:b.width-(this.beforeCt.getWidth()+this.afterCt.getWidth())}}},createInnerElements:function(){var a=this.layout.innerCt;if(!this.beforeCt){this.afterCt=a.insertSibling({cls:this.afterCls},"before");this.beforeCt=a.insertSibling({cls:this.beforeCls},"before");this.createWheelListener()}},scrollTo:function(a,b){var d=this.getScrollPosition(),c=a.constrain(0,this.getMaxScrollRight());if(c!=d&&!this.scrolling){if(b==undefined){b=this.animateScroll}this.layout.innerCt.scrollTo("left",c,b?this.getScrollAnim():false);if(b){this.scrolling=true}else{this.scrolling=false;this.updateScrollButtons()}}},getScrollPosition:function(){return parseInt(this.layout.innerCt.dom.scrollLeft,10)||0},getMaxScrollRight:function(){return this.layout.innerCt.dom.scrollWidth-this.layout.innerCt.getWidth()},atExtremeAfter:function(){return this.getScrollPosition()>=this.getMaxScrollRight()}});Ext.layout.boxOverflow.scroller.hbox=Ext.layout.boxOverflow.HorizontalScroller;Ext.layout.HBoxLayout=Ext.extend(Ext.layout.BoxLayout,{align:"top",type:"hbox",calculateChildBoxes:function(r,b){var F=r.length,R=this.padding,D=R.top,U=R.left,y=D+R.bottom,O=U+R.right,a=b.width-this.scrollOffset,e=b.height,o=Math.max(0,e-y),P=this.pack=="start",W=this.pack=="center",A=this.pack=="end",L=0,Q=0,T=0,l=0,X=0,H=[],k,J,M,V,w,j,S,I,c,x,q,N;for(S=0;S<F;S++){k=r[S];M=k.height;J=k.width;j=!k.hasLayout&&typeof k.doLayout=="function";if(typeof J!="number"){if(k.flex&&!J){T+=k.flex}else{if(!J&&j){k.doLayout()}V=k.getSize();J=V.width;M=V.height}}w=k.margins;x=w.left+w.right;L+=x+(J||0);l+=x+(k.flex?k.minWidth||0:J);X+=x+(k.minWidth||J||0);if(typeof M!="number"){if(j){k.doLayout()}M=k.getHeight()}Q=Math.max(Q,M+w.top+w.bottom);H.push({component:k,height:M||undefined,width:J||undefined})}var K=l-a,p=X>a;var n=Math.max(0,a-L-O);if(p){for(S=0;S<F;S++){H[S].width=r[S].minWidth||r[S].width||H[S].width}}else{if(K>0){var C=[];for(var E=0,v=F;E<v;E++){var B=r[E],t=B.minWidth||0;if(B.flex){H[E].width=t}else{C.push({minWidth:t,available:H[E].width-t,index:E})}}C.sort(function(Y,i){return Y.available>i.available?1:-1});for(var S=0,v=C.length;S<v;S++){var G=C[S].index;if(G==undefined){continue}var B=r[G],m=H[G],u=m.width,t=B.minWidth,d=Math.max(t,u-Math.ceil(K/(v-S))),g=u-d;H[G].width=d;K-=g}}else{var h=n,s=T;for(S=0;S<F;S++){k=r[S];I=H[S];w=k.margins;q=w.top+w.bottom;if(P&&k.flex&&!k.width){c=Math.ceil((k.flex/s)*h);h-=c;s-=k.flex;I.width=c;I.dirtySize=true}}}}if(W){U+=n/2}else{if(A){U+=n}}for(S=0;S<F;S++){k=r[S];I=H[S];w=k.margins;U+=w.left;q=w.top+w.bottom;I.left=U;I.top=D+w.top;switch(this.align){case"stretch":N=o-q;I.height=N.constrain(k.minHeight||0,k.maxHeight||1000000);I.dirtySize=true;break;case"stretchmax":N=Q-q;I.height=N.constrain(k.minHeight||0,k.maxHeight||1000000);I.dirtySize=true;break;case"middle":var z=o-I.height-q;if(z>0){I.top=D+q+(z/2)}}U+=I.width+w.right}return{boxes:H,meta:{maxHeight:Q,nonFlexWidth:L,desiredWidth:l,minimumWidth:X,shortfall:l-a,tooNarrow:p}}}});Ext.Container.LAYOUTS.hbox=Ext.layout.HBoxLayout;Ext.layout.VBoxLayout=Ext.extend(Ext.layout.BoxLayout,{align:"left",type:"vbox",calculateChildBoxes:function(o,b){var E=o.length,R=this.padding,C=R.top,V=R.left,x=C+R.bottom,O=V+R.right,a=b.width-this.scrollOffset,c=b.height,K=Math.max(0,a-O),P=this.pack=="start",X=this.pack=="center",z=this.pack=="end",k=0,u=0,U=0,L=0,m=0,G=[],h,I,N,W,t,g,T,H,S,w,n,d,r;for(T=0;T<E;T++){h=o[T];N=h.height;I=h.width;g=!h.hasLayout&&typeof h.doLayout=="function";if(typeof N!="number"){if(h.flex&&!N){U+=h.flex}else{if(!N&&g){h.doLayout()}W=h.getSize();I=W.width;N=W.height}}t=h.margins;n=t.top+t.bottom;k+=n+(N||0);L+=n+(h.flex?h.minHeight||0:N);m+=n+(h.minHeight||N||0);if(typeof I!="number"){if(g){h.doLayout()}I=h.getWidth()}u=Math.max(u,I+t.left+t.right);G.push({component:h,height:N||undefined,width:I||undefined})}var M=L-c,l=m>c;var q=Math.max(0,(c-k-x));if(l){for(T=0,r=E;T<r;T++){G[T].height=o[T].minHeight||o[T].height||G[T].height}}else{if(M>0){var J=[];for(var D=0,r=E;D<r;D++){var A=o[D],s=A.minHeight||0;if(A.flex){G[D].height=s}else{J.push({minHeight:s,available:G[D].height-s,index:D})}}J.sort(function(Y,i){return Y.available>i.available?1:-1});for(var T=0,r=J.length;T<r;T++){var F=J[T].index;if(F==undefined){continue}var A=o[F],j=G[F],v=j.height,s=A.minHeight,B=Math.max(s,v-Math.ceil(M/(r-T))),e=v-B;G[F].height=B;M-=e}}else{var Q=q,p=U;for(T=0;T<E;T++){h=o[T];H=G[T];t=h.margins;w=t.left+t.right;if(P&&h.flex&&!h.height){S=Math.ceil((h.flex/p)*Q);Q-=S;p-=h.flex;H.height=S;H.dirtySize=true}}}}if(X){C+=q/2}else{if(z){C+=q}}for(T=0;T<E;T++){h=o[T];H=G[T];t=h.margins;C+=t.top;w=t.left+t.right;H.left=V+t.left;H.top=C;switch(this.align){case"stretch":d=K-w;H.width=d.constrain(h.minWidth||0,h.maxWidth||1000000);H.dirtySize=true;break;case"stretchmax":d=u-w;H.width=d.constrain(h.minWidth||0,h.maxWidth||1000000);H.dirtySize=true;break;case"center":var y=K-H.width-w;if(y>0){H.left=V+w+(y/2)}}C+=H.height+t.bottom}return{boxes:G,meta:{maxWidth:u,nonFlexHeight:k,desiredHeight:L,minimumHeight:m,shortfall:L-c,tooNarrow:l}}}});Ext.Container.LAYOUTS.vbox=Ext.layout.VBoxLayout;Ext.layout.ToolbarLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"toolbar",triggerWidth:18,noItemsMenuText:'<div class="x-toolbar-no-items">(None)</div>',lastOverflow:false,tableHTML:['<table cellspacing="0" class="x-toolbar-ct">',"<tbody>","<tr>",'<td class="x-toolbar-left" align="{0}">','<table cellspacing="0">',"<tbody>",'<tr class="x-toolbar-left-row"></tr>',"</tbody>","</table>","</td>",'<td class="x-toolbar-right" align="right">','<table cellspacing="0" class="x-toolbar-right-ct">',"<tbody>","<tr>","<td>",'<table cellspacing="0">',"<tbody>",'<tr class="x-toolbar-right-row"></tr>',"</tbody>","</table>","</td>","<td>",'<table cellspacing="0">',"<tbody>",'<tr class="x-toolbar-extras-row"></tr>',"</tbody>","</table>","</td>","</tr>","</tbody>","</table>","</td>","</tr>","</tbody>","</table>"].join(""),onLayout:function(e,j){if(!this.leftTr){var h=e.buttonAlign=="center"?"center":"left";j.addClass("x-toolbar-layout-ct");j.insertHtml("beforeEnd",String.format(this.tableHTML,h));this.leftTr=j.child("tr.x-toolbar-left-row",true);this.rightTr=j.child("tr.x-toolbar-right-row",true);this.extrasTr=j.child("tr.x-toolbar-extras-row",true);if(this.hiddenItem==undefined){this.hiddenItems=[]}}var k=e.buttonAlign=="right"?this.rightTr:this.leftTr,l=e.items.items,d=0;for(var b=0,g=l.length,m;b<g;b++,d++){m=l[b];if(m.isFill){k=this.rightTr;d=-1}else{if(!m.rendered){m.render(this.insertCell(m,k,d));this.configureItem(m)}else{if(!m.xtbHidden&&!this.isValidParent(m,k.childNodes[d])){var a=this.insertCell(m,k,d);a.appendChild(m.getPositionEl().dom);m.container=Ext.get(a)}}}}this.cleanup(this.leftTr);this.cleanup(this.rightTr);this.cleanup(this.extrasTr);this.fitToSize(j)},cleanup:function(b){var e=b.childNodes,a,d;for(a=e.length-1;a>=0&&(d=e[a]);a--){if(!d.firstChild){b.removeChild(d)}}},insertCell:function(e,b,a){var d=document.createElement("td");d.className="x-toolbar-cell";b.insertBefore(d,b.childNodes[a]||null);return d},hideItem:function(a){this.hiddenItems.push(a);a.xtbHidden=true;a.xtbWidth=a.getPositionEl().dom.parentNode.offsetWidth;a.hide()},unhideItem:function(a){a.show();a.xtbHidden=false;this.hiddenItems.remove(a)},getItemWidth:function(a){return a.hidden?(a.xtbWidth||0):a.getPositionEl().dom.parentNode.offsetWidth},fitToSize:function(k){if(this.container.enableOverflow===false){return}var b=k.dom.clientWidth,j=k.dom.firstChild.offsetWidth,m=b-this.triggerWidth,a=this.lastWidth||0,c=this.hiddenItems,e=c.length!=0,n=b>=a;this.lastWidth=b;if(j>b||(e&&n)){var l=this.container.items.items,h=l.length,d=0,o;for(var g=0;g<h;g++){o=l[g];if(!o.isFill){d+=this.getItemWidth(o);if(d>m){if(!(o.hidden||o.xtbHidden)){this.hideItem(o)}}else{if(o.xtbHidden){this.unhideItem(o)}}}}}e=c.length!=0;if(e){this.initMore();if(!this.lastOverflow){this.container.fireEvent("overflowchange",this.container,true);this.lastOverflow=true}}else{if(this.more){this.clearMenu();this.more.destroy();delete this.more;if(this.lastOverflow){this.container.fireEvent("overflowchange",this.container,false);this.lastOverflow=false}}}},createMenuConfig:function(c,a){var b=Ext.apply({},c.initialConfig),d=c.toggleGroup;Ext.copyTo(b,c,["iconCls","icon","itemId","disabled","handler","scope","menu"]);Ext.apply(b,{text:c.overflowText||c.text,hideOnClick:a});if(d||c.enableToggle){Ext.apply(b,{group:d,checked:c.pressed,listeners:{checkchange:function(g,e){c.toggle(e)}}})}delete b.ownerCt;delete b.xtype;delete b.id;return b},addComponentToMenu:function(b,a){if(a instanceof Ext.Toolbar.Separator){b.add("-")}else{if(Ext.isFunction(a.isXType)){if(a.isXType("splitbutton")){b.add(this.createMenuConfig(a,true))}else{if(a.isXType("button")){b.add(this.createMenuConfig(a,!a.menu))}else{if(a.isXType("buttongroup")){a.items.each(function(c){this.addComponentToMenu(b,c)},this)}}}}}},clearMenu:function(){var a=this.moreMenu;if(a&&a.items){a.items.each(function(b){delete b.menu})}},beforeMoreShow:function(h){var b=this.container.items.items,a=b.length,g,e;var c=function(j,i){return j.isXType("buttongroup")&&!(i instanceof Ext.Toolbar.Separator)};this.clearMenu();h.removeAll();for(var d=0;d<a;d++){g=b[d];if(g.xtbHidden){if(e&&(c(g,e)||c(e,g))){h.add("-")}this.addComponentToMenu(h,g);e=g}}if(h.items.length<1){h.add(this.noItemsMenuText)}},initMore:function(){if(!this.more){this.moreMenu=new Ext.menu.Menu({ownerCt:this.container,listeners:{beforeshow:this.beforeMoreShow,scope:this}});this.more=new Ext.Button({iconCls:"x-toolbar-more-icon",cls:"x-toolbar-more",menu:this.moreMenu,ownerCt:this.container});var a=this.insertCell(this.more,this.extrasTr,100);this.more.render(a)}},destroy:function(){Ext.destroy(this.more,this.moreMenu);delete this.leftTr;delete this.rightTr;delete this.extrasTr;Ext.layout.ToolbarLayout.superclass.destroy.call(this)}});Ext.Container.LAYOUTS.toolbar=Ext.layout.ToolbarLayout;Ext.layout.MenuLayout=Ext.extend(Ext.layout.ContainerLayout,{monitorResize:true,type:"menu",setContainer:function(a){this.monitorResize=!a.floating;a.on("autosize",this.doAutoSize,this);Ext.layout.MenuLayout.superclass.setContainer.call(this,a)},renderItem:function(g,b,e){if(!this.itemTpl){this.itemTpl=Ext.layout.MenuLayout.prototype.itemTpl=new Ext.XTemplate('<li id="{itemId}" class="{itemCls}">','<tpl if="needsIcon">','<img alt="{altText}" src="{icon}" class="{iconCls}"/>',"</tpl>","</li>")}if(g&&!g.rendered){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}var d=this.getItemArgs(g);g.render(g.positionEl=b?this.itemTpl.insertBefore(b,d,true):this.itemTpl.append(e,d,true));g.positionEl.menuItemId=g.getItemId();if(!d.isMenuItem&&d.needsIcon){g.positionEl.addClass("x-menu-list-item-indent")}this.configureItem(g)}else{if(g&&!this.isValidParent(g,e)){if(Ext.isNumber(b)){b=e.dom.childNodes[b]}e.dom.insertBefore(g.getActionEl().dom,b||null)}}},getItemArgs:function(d){var a=d instanceof Ext.menu.Item,b=!(a||d instanceof Ext.menu.Separator);return{isMenuItem:a,needsIcon:b&&(d.icon||d.iconCls),icon:d.icon||Ext.BLANK_IMAGE_URL,iconCls:"x-menu-item-icon "+(d.iconCls||""),itemId:"x-menu-el-"+d.id,itemCls:"x-menu-list-item ",altText:d.altText||""}},isValidParent:function(b,a){return b.el.up("li.x-menu-list-item",5).dom.parentNode===(a.dom||a)},onLayout:function(a,b){Ext.layout.MenuLayout.superclass.onLayout.call(this,a,b);this.doAutoSize()},doAutoSize:function(){var c=this.container,a=c.width;if(c.floating){if(a){c.setWidth(a)}else{if(Ext.isIE9m){c.setWidth(Ext.isStrict&&(Ext.isIE7||Ext.isIE8||Ext.isIE9)?"auto":c.minWidth);var d=c.getEl(),b=d.dom.offsetWidth;c.setWidth(c.getLayoutTarget().getWidth()+d.getFrameWidth("lr"))}}}}});Ext.Container.LAYOUTS.menu=Ext.layout.MenuLayout;Ext.Viewport=Ext.extend(Ext.Container,{initComponent:function(){Ext.Viewport.superclass.initComponent.call(this);document.getElementsByTagName("html")[0].className+=" x-viewport";this.el=Ext.getBody();this.el.setHeight=Ext.emptyFn;this.el.setWidth=Ext.emptyFn;this.el.setSize=Ext.emptyFn;this.el.dom.scroll="no";this.allowDomMove=false;this.autoWidth=true;this.autoHeight=true;Ext.EventManager.onWindowResize(this.fireResize,this);this.renderTo=this.el},fireResize:function(a,b){this.fireEvent("resize",this,a,b,a,b)}});Ext.reg("viewport",Ext.Viewport);Ext.Panel=Ext.extend(Ext.Container,{baseCls:"x-panel",collapsedCls:"x-panel-collapsed",maskDisabled:true,animCollapse:Ext.enableFx,headerAsText:true,buttonAlign:"right",collapsed:false,collapseFirst:true,minButtonWidth:75,elements:"body",preventBodyReset:false,padding:undefined,resizeEvent:"bodyresize",toolTarget:"header",collapseEl:"bwrap",slideAnchor:"t",disabledClass:"",deferHeight:true,expandDefaults:{duration:0.25},collapseDefaults:{duration:0.25},initComponent:function(){Ext.Panel.superclass.initComponent.call(this);this.addEvents("bodyresize","titlechange","iconchange","collapse","expand","beforecollapse","beforeexpand","beforeclose","close","activate","deactivate");if(this.unstyled){this.baseCls="x-plain"}this.toolbars=[];if(this.tbar){this.elements+=",tbar";this.topToolbar=this.createToolbar(this.tbar);this.tbar=null}if(this.bbar){this.elements+=",bbar";this.bottomToolbar=this.createToolbar(this.bbar);this.bbar=null}if(this.header===true){this.elements+=",header";this.header=null}else{if(this.headerCfg||(this.title&&this.header!==false)){this.elements+=",header"}}if(this.footerCfg||this.footer===true){this.elements+=",footer";this.footer=null}if(this.buttons){this.fbar=this.buttons;this.buttons=null}if(this.fbar){this.createFbar(this.fbar)}if(this.autoLoad){this.on("render",this.doAutoLoad,this,{delay:10})}},createFbar:function(b){var a=this.minButtonWidth;this.elements+=",footer";this.fbar=this.createToolbar(b,{buttonAlign:this.buttonAlign,toolbarCls:"x-panel-fbar",enableOverflow:false,defaults:function(d){return{minWidth:d.minWidth||a}}});this.fbar.items.each(function(d){d.minWidth=d.minWidth||this.minButtonWidth},this);this.buttons=this.fbar.items.items},createToolbar:function(b,c){var a;if(Ext.isArray(b)){b={items:b}}a=b.events?Ext.apply(b,c):this.createComponent(Ext.apply({},b,c),"toolbar");this.toolbars.push(a);return a},createElement:function(a,c){if(this[a]){c.appendChild(this[a].dom);return}if(a==="bwrap"||this.elements.indexOf(a)!=-1){if(this[a+"Cfg"]){this[a]=Ext.fly(c).createChild(this[a+"Cfg"])}else{var b=document.createElement("div");b.className=this[a+"Cls"];this[a]=Ext.get(c.appendChild(b))}if(this[a+"CssClass"]){this[a].addClass(this[a+"CssClass"])}if(this[a+"Style"]){this[a].applyStyles(this[a+"Style"])}}},onRender:function(g,e){Ext.Panel.superclass.onRender.call(this,g,e);this.createClasses();var a=this.el,h=a.dom,k,i;if(this.collapsible&&!this.hideCollapseTool){this.tools=this.tools?this.tools.slice(0):[];this.tools[this.collapseFirst?"unshift":"push"]({id:"toggle",handler:this.toggleCollapse,scope:this})}if(this.tools){i=this.tools;this.elements+=(this.header!==false)?",header":""}this.tools={};a.addClass(this.baseCls);if(h.firstChild){this.header=a.down("."+this.headerCls);this.bwrap=a.down("."+this.bwrapCls);var j=this.bwrap?this.bwrap:a;this.tbar=j.down("."+this.tbarCls);this.body=j.down("."+this.bodyCls);this.bbar=j.down("."+this.bbarCls);this.footer=j.down("."+this.footerCls);this.fromMarkup=true}if(this.preventBodyReset===true){a.addClass("x-panel-reset")}if(this.cls){a.addClass(this.cls)}if(this.buttons){this.elements+=",footer"}if(this.frame){a.insertHtml("afterBegin",String.format(Ext.Element.boxMarkup,this.baseCls));this.createElement("header",h.firstChild.firstChild.firstChild);this.createElement("bwrap",h);k=this.bwrap.dom;var c=h.childNodes[1],b=h.childNodes[2];k.appendChild(c);k.appendChild(b);var l=k.firstChild.firstChild.firstChild;this.createElement("tbar",l);this.createElement("body",l);this.createElement("bbar",l);this.createElement("footer",k.lastChild.firstChild.firstChild);if(!this.footer){this.bwrap.dom.lastChild.className+=" x-panel-nofooter"}this.ft=Ext.get(this.bwrap.dom.lastChild);this.mc=Ext.get(l)}else{this.createElement("header",h);this.createElement("bwrap",h);k=this.bwrap.dom;this.createElement("tbar",k);this.createElement("body",k);this.createElement("bbar",k);this.createElement("footer",k);if(!this.header){this.body.addClass(this.bodyCls+"-noheader");if(this.tbar){this.tbar.addClass(this.tbarCls+"-noheader")}}}if(Ext.isDefined(this.padding)){this.body.setStyle("padding",this.body.addUnits(this.padding))}if(this.border===false){this.el.addClass(this.baseCls+"-noborder");this.body.addClass(this.bodyCls+"-noborder");if(this.header){this.header.addClass(this.headerCls+"-noborder")}if(this.footer){this.footer.addClass(this.footerCls+"-noborder")}if(this.tbar){this.tbar.addClass(this.tbarCls+"-noborder")}if(this.bbar){this.bbar.addClass(this.bbarCls+"-noborder")}}if(this.bodyBorder===false){this.body.addClass(this.bodyCls+"-noborder")}this.bwrap.enableDisplayMode("block");if(this.header){this.header.unselectable();if(this.headerAsText){this.header.dom.innerHTML='<span class="'+this.headerTextCls+'">'+this.header.dom.innerHTML+"</span>";if(this.iconCls){this.setIconClass(this.iconCls)}}}if(this.floating){this.makeFloating(this.floating)}if(this.collapsible&&this.titleCollapse&&this.header){this.mon(this.header,"click",this.toggleCollapse,this);this.header.setStyle("cursor","pointer")}if(i){this.addTool.apply(this,i)}if(this.fbar){this.footer.addClass("x-panel-btns");this.fbar.ownerCt=this;this.fbar.render(this.footer);this.footer.createChild({cls:"x-clear"})}if(this.tbar&&this.topToolbar){this.topToolbar.ownerCt=this;this.topToolbar.render(this.tbar)}if(this.bbar&&this.bottomToolbar){this.bottomToolbar.ownerCt=this;this.bottomToolbar.render(this.bbar)}},setIconClass:function(b){var a=this.iconCls;this.iconCls=b;if(this.rendered&&this.header){if(this.frame){this.header.addClass("x-panel-icon");this.header.replaceClass(a,this.iconCls)}else{var e=this.header,c=e.child("img.x-panel-inline-icon");if(c){Ext.fly(c).replaceClass(a,this.iconCls)}else{var d=e.child("span."+this.headerTextCls);if(d){Ext.DomHelper.insertBefore(d.dom,{tag:"img",alt:"",src:Ext.BLANK_IMAGE_URL,cls:"x-panel-inline-icon "+this.iconCls})}}}}this.fireEvent("iconchange",this,b,a)},makeFloating:function(a){this.floating=true;this.el=new Ext.Layer(Ext.apply({},a,{shadow:Ext.isDefined(this.shadow)?this.shadow:"sides",shadowOffset:this.shadowOffset,constrain:false,shim:this.shim===false?false:undefined}),this.el)},getTopToolbar:function(){return this.topToolbar},getBottomToolbar:function(){return this.bottomToolbar},getFooterToolbar:function(){return this.fbar},addButton:function(a,c,b){if(!this.fbar){this.createFbar([])}if(c){if(Ext.isString(a)){a={text:a}}a=Ext.apply({handler:c,scope:b},a)}return this.fbar.add(a)},addTool:function(){if(!this.rendered){if(!this.tools){this.tools=[]}Ext.each(arguments,function(a){this.tools.push(a)},this);return}if(!this[this.toolTarget]){return}if(!this.toolTemplate){var h=new Ext.Template('<div class="x-tool x-tool-{id}">&#160;</div>');h.disableFormats=true;h.compile();Ext.Panel.prototype.toolTemplate=h}for(var g=0,d=arguments,c=d.length;g<c;g++){var b=d[g];if(!this.tools[b.id]){var j="x-tool-"+b.id+"-over";var e=this.toolTemplate.insertFirst(this[this.toolTarget],b,true);this.tools[b.id]=e;e.enableDisplayMode("block");this.mon(e,"click",this.createToolHandler(e,b,j,this));if(b.on){this.mon(e,b.on)}if(b.hidden){e.hide()}if(b.qtip){if(Ext.isObject(b.qtip)){Ext.QuickTips.register(Ext.apply({target:e.id},b.qtip))}else{e.dom.qtip=b.qtip}}e.addClassOnOver(j)}}},onLayout:function(b,a){Ext.Panel.superclass.onLayout.apply(this,arguments);if(this.hasLayout&&this.toolbars.length>0){Ext.each(this.toolbars,function(c){c.doLayout(undefined,a)});this.syncHeight()}},syncHeight:function(){var b=this.toolbarHeight,c=this.body,a=this.lastSize.height,d;if(this.autoHeight||!Ext.isDefined(a)||a=="auto"){return}if(b!=this.getToolbarHeight()){b=Math.max(0,a-this.getFrameHeight());c.setHeight(b);d=c.getSize();this.toolbarHeight=this.getToolbarHeight();this.onBodyResize(d.width,d.height)}},onShow:function(){if(this.floating){return this.el.show()}Ext.Panel.superclass.onShow.call(this)},onHide:function(){if(this.floating){return this.el.hide()}Ext.Panel.superclass.onHide.call(this)},createToolHandler:function(c,a,d,b){return function(g){c.removeClass(d);if(a.stopEvent!==false){g.stopEvent()}if(a.handler){a.handler.call(a.scope||c,g,c,b,a)}}},afterRender:function(){if(this.floating&&!this.hidden){this.el.show()}if(this.title){this.setTitle(this.title)}Ext.Panel.superclass.afterRender.call(this);if(this.collapsed){this.collapsed=false;this.collapse(false)}this.initEvents()},getKeyMap:function(){if(!this.keyMap){this.keyMap=new Ext.KeyMap(this.el,this.keys)}return this.keyMap},initEvents:function(){if(this.keys){this.getKeyMap()}if(this.draggable){this.initDraggable()}if(this.toolbars.length>0){Ext.each(this.toolbars,function(a){a.doLayout();a.on({scope:this,afterlayout:this.syncHeight,remove:this.syncHeight})},this);this.syncHeight()}},initDraggable:function(){this.dd=new Ext.Panel.DD(this,Ext.isBoolean(this.draggable)?null:this.draggable)},beforeEffect:function(a){if(this.floating){this.el.beforeAction()}if(a!==false){this.el.addClass("x-panel-animated")}},afterEffect:function(a){this.syncShadow();this.el.removeClass("x-panel-animated")},createEffect:function(c,b,d){var e={scope:d,block:true};if(c===true){e.callback=b;return e}else{if(!c.callback){e.callback=b}else{e.callback=function(){b.call(d);Ext.callback(c.callback,c.scope)}}}return Ext.applyIf(e,c)},collapse:function(b){if(this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforecollapse",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.beforeEffect(a);this.onCollapse(a,b);return this},onCollapse:function(a,b){if(a){this[this.collapseEl].slideOut(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterCollapse,this),this.collapseDefaults))}else{this[this.collapseEl].hide(this.hideMode);this.afterCollapse(false)}},afterCollapse:function(a){this.collapsed=true;this.el.addClass(this.collapsedCls);if(a!==false){this[this.collapseEl].hide(this.hideMode)}this.afterEffect(a);this.cascade(function(b){if(b.lastSize){b.lastSize={width:undefined,height:undefined}}});this.fireEvent("collapse",this)},expand:function(b){if(!this.collapsed||this.el.hasFxBlock()||this.fireEvent("beforeexpand",this,b)===false){return}var a=b===true||(b!==false&&this.animCollapse);this.el.removeClass(this.collapsedCls);this.beforeEffect(a);this.onExpand(a,b);return this},onExpand:function(a,b){if(a){this[this.collapseEl].slideIn(this.slideAnchor,Ext.apply(this.createEffect(b||true,this.afterExpand,this),this.expandDefaults))}else{this[this.collapseEl].show(this.hideMode);this.afterExpand(false)}},afterExpand:function(a){this.collapsed=false;if(a!==false){this[this.collapseEl].show(this.hideMode)}this.afterEffect(a);if(this.deferLayout){delete this.deferLayout;this.doLayout(true)}this.fireEvent("expand",this)},toggleCollapse:function(a){this[this.collapsed?"expand":"collapse"](a);return this},onDisable:function(){if(this.rendered&&this.maskDisabled){this.el.mask()}Ext.Panel.superclass.onDisable.call(this)},onEnable:function(){if(this.rendered&&this.maskDisabled){this.el.unmask()}Ext.Panel.superclass.onEnable.call(this)},onResize:function(g,d,c,e){var a=g,b=d;if(Ext.isDefined(a)||Ext.isDefined(b)){if(!this.collapsed){if(Ext.isNumber(a)){this.body.setWidth(a=this.adjustBodyWidth(a-this.getFrameWidth()))}else{if(a=="auto"){a=this.body.setWidth("auto").dom.offsetWidth}else{a=this.body.dom.offsetWidth}}if(this.tbar){this.tbar.setWidth(a);if(this.topToolbar){this.topToolbar.setSize(a)}}if(this.bbar){this.bbar.setWidth(a);if(this.bottomToolbar){this.bottomToolbar.setSize(a);if(Ext.isIE9m){this.bbar.setStyle("position","static");this.bbar.setStyle("position","")}}}if(this.footer){this.footer.setWidth(a);if(this.fbar){this.fbar.setSize(Ext.isIE9m?(a-this.footer.getFrameWidth("lr")):"auto")}}if(Ext.isNumber(b)){b=Math.max(0,b-this.getFrameHeight());this.body.setHeight(b)}else{if(b=="auto"){this.body.setHeight(b)}}if(this.disabled&&this.el._mask){this.el._mask.setSize(this.el.dom.clientWidth,this.el.getHeight())}}else{this.queuedBodySize={width:a,height:b};if(!this.queuedExpand&&this.allowQueuedExpand!==false){this.queuedExpand=true;this.on("expand",function(){delete this.queuedExpand;this.onResize(this.queuedBodySize.width,this.queuedBodySize.height)},this,{single:true})}}this.onBodyResize(a,b)}this.syncShadow();Ext.Panel.superclass.onResize.call(this,g,d,c,e)},onBodyResize:function(a,b){this.fireEvent("bodyresize",this,a,b)},getToolbarHeight:function(){var a=0;if(this.rendered){Ext.each(this.toolbars,function(b){a+=b.getHeight()},this)}return a},adjustBodyHeight:function(a){return a},adjustBodyWidth:function(a){return a},onPosition:function(){this.syncShadow()},getFrameWidth:function(){var b=this.el.getFrameWidth("lr")+this.bwrap.getFrameWidth("lr");if(this.frame){var a=this.bwrap.dom.firstChild;b+=(Ext.fly(a).getFrameWidth("l")+Ext.fly(a.firstChild).getFrameWidth("r"));b+=this.mc.getFrameWidth("lr")}return b},getFrameHeight:function(){var a=this.el.getFrameWidth("tb")+this.bwrap.getFrameWidth("tb");a+=(this.tbar?this.tbar.getHeight():0)+(this.bbar?this.bbar.getHeight():0);if(this.frame){a+=this.el.dom.firstChild.offsetHeight+this.ft.dom.offsetHeight+this.mc.getFrameWidth("tb")}else{a+=(this.header?this.header.getHeight():0)+(this.footer?this.footer.getHeight():0)}return a},getInnerWidth:function(){return this.getSize().width-this.getFrameWidth()},getInnerHeight:function(){return this.body.getHeight()},syncShadow:function(){if(this.floating){this.el.sync(true)}},getLayoutTarget:function(){return this.body},getContentTarget:function(){return this.body},setTitle:function(b,a){this.title=b;if(this.header&&this.headerAsText){this.header.child("span").update(b)}if(a){this.setIconClass(a)}this.fireEvent("titlechange",this,b);return this},getUpdater:function(){return this.body.getUpdater()},load:function(){var a=this.body.getUpdater();a.update.apply(a,arguments);return this},beforeDestroy:function(){Ext.Panel.superclass.beforeDestroy.call(this);if(this.header){this.header.removeAllListeners()}if(this.tools){for(var a in this.tools){Ext.destroy(this.tools[a])}}if(this.toolbars.length>0){Ext.each(this.toolbars,function(b){b.un("afterlayout",this.syncHeight,this);b.un("remove",this.syncHeight,this)},this)}if(Ext.isArray(this.buttons)){while(this.buttons.length){Ext.destroy(this.buttons[0])}}if(this.rendered){Ext.destroy(this.ft,this.header,this.footer,this.tbar,this.bbar,this.body,this.mc,this.bwrap,this.dd);if(this.fbar){Ext.destroy(this.fbar,this.fbar.el)}}Ext.destroy(this.toolbars)},createClasses:function(){this.headerCls=this.baseCls+"-header";this.headerTextCls=this.baseCls+"-header-text";this.bwrapCls=this.baseCls+"-bwrap";this.tbarCls=this.baseCls+"-tbar";this.bodyCls=this.baseCls+"-body";this.bbarCls=this.baseCls+"-bbar";this.footerCls=this.baseCls+"-footer"},createGhost:function(a,e,b){var d=document.createElement("div");d.className="x-panel-ghost "+(a?a:"");if(this.header){d.appendChild(this.el.dom.firstChild.cloneNode(true))}Ext.fly(d.appendChild(document.createElement("ul"))).setHeight(this.bwrap.getHeight());d.style.width=this.el.dom.offsetWidth+"px";if(!b){this.container.dom.appendChild(d)}else{Ext.getDom(b).appendChild(d)}if(e!==false&&this.el.useShim!==false){var c=new Ext.Layer({shadow:false,useDisplay:true,constrain:false},d);c.show();return c}else{return new Ext.Element(d)}},doAutoLoad:function(){var a=this.body.getUpdater();if(this.renderer){a.setRenderer(this.renderer)}a.update(Ext.isObject(this.autoLoad)?this.autoLoad:{url:this.autoLoad})},getTool:function(a){return this.tools[a]}});Ext.reg("panel",Ext.Panel);Ext.Editor=function(b,a){if(b.field){this.field=Ext.create(b.field,"textfield");a=Ext.apply({},b);delete a.field}else{this.field=b}Ext.Editor.superclass.constructor.call(this,a)};Ext.extend(Ext.Editor,Ext.Component,{allowBlur:true,value:"",alignment:"c-c?",offsets:[0,0],shadow:"frame",constrain:false,swallowKeys:true,completeOnEnter:true,cancelOnEsc:true,updateEl:false,initComponent:function(){Ext.Editor.superclass.initComponent.call(this);this.addEvents("beforestartedit","startedit","beforecomplete","complete","canceledit","specialkey")},onRender:function(b,a){this.el=new Ext.Layer({shadow:this.shadow,cls:"x-editor",parentEl:b,shim:this.shim,shadowOffset:this.shadowOffset||4,id:this.id,constrain:this.constrain});if(this.zIndex){this.el.setZIndex(this.zIndex)}this.el.setStyle("overflow",Ext.isGecko?"auto":"hidden");if(this.field.msgTarget!="title"){this.field.msgTarget="qtip"}this.field.inEditor=true;this.mon(this.field,{scope:this,blur:this.onBlur,specialkey:this.onSpecialKey});if(this.field.grow){this.mon(this.field,"autosize",this.el.sync,this.el,{delay:1})}this.field.render(this.el).show();this.field.getEl().dom.name="";if(this.swallowKeys){this.field.el.swallowEvent(["keypress","keydown"])}},onSpecialKey:function(g,d){var b=d.getKey(),a=this.completeOnEnter&&b==d.ENTER,c=this.cancelOnEsc&&b==d.ESC;if(a||c){d.stopEvent();if(a){this.completeEdit()}else{this.cancelEdit()}if(g.triggerBlur){g.triggerBlur()}}this.fireEvent("specialkey",g,d)},startEdit:function(b,c){if(this.editing){this.completeEdit()}this.boundEl=Ext.get(b);var a=c!==undefined?c:this.boundEl.dom.innerHTML;if(!this.rendered){this.render(this.parentEl||document.body)}if(this.fireEvent("beforestartedit",this,this.boundEl,a)!==false){this.startValue=a;this.field.reset();this.field.setValue(a);this.realign(true);this.editing=true;this.show()}},doAutoSize:function(){if(this.autoSize){var b=this.boundEl.getSize(),a=this.field.getSize();switch(this.autoSize){case"width":this.setSize(b.width,a.height);break;case"height":this.setSize(a.width,b.height);break;case"none":this.setSize(a.width,a.height);break;default:this.setSize(b.width,b.height)}}},setSize:function(a,b){delete this.field.lastSize;this.field.setSize(a,b);if(this.el){if(Ext.isGecko2||Ext.isOpera||(Ext.isIE7&&Ext.isStrict)){this.el.setSize(a,b)}this.el.sync()}},realign:function(a){if(a===true){this.doAutoSize()}this.el.alignTo(this.boundEl,this.alignment,this.offsets)},completeEdit:function(a){if(!this.editing){return}if(this.field.assertValue){this.field.assertValue()}var b=this.getValue();if(!this.field.isValid()){if(this.revertInvalid!==false){this.cancelEdit(a)}return}if(String(b)===String(this.startValue)&&this.ignoreNoChange){this.hideEdit(a);return}if(this.fireEvent("beforecomplete",this,b,this.startValue)!==false){b=this.getValue();if(this.updateEl&&this.boundEl){this.boundEl.update(b)}this.hideEdit(a);this.fireEvent("complete",this,b,this.startValue)}},onShow:function(){this.el.show();if(this.hideEl!==false){this.boundEl.hide()}this.field.show().focus(false,true);this.fireEvent("startedit",this.boundEl,this.startValue)},cancelEdit:function(a){if(this.editing){var b=this.getValue();this.setValue(this.startValue);this.hideEdit(a);this.fireEvent("canceledit",this,b,this.startValue)}},hideEdit:function(a){if(a!==true){this.editing=false;this.hide()}},onBlur:function(){if(this.allowBlur===true&&this.editing&&this.selectSameEditor!==true){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()}},setValue:function(a){this.field.setValue(a)},getValue:function(){return this.field.getValue()},beforeDestroy:function(){Ext.destroyMembers(this,"field");delete this.parentEl;delete this.boundEl}});Ext.reg("editor",Ext.Editor);Ext.ColorPalette=Ext.extend(Ext.Component,{itemCls:"x-color-palette",value:null,clickEvent:"click",ctype:"Ext.ColorPalette",allowReselect:false,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"],initComponent:function(){Ext.ColorPalette.superclass.initComponent.call(this);this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope,true)}},onRender:function(b,a){this.autoEl={tag:"div",cls:this.itemCls};Ext.ColorPalette.superclass.onRender.call(this,b,a);var c=this.tpl||new Ext.XTemplate('<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" class="x-unselectable" unselectable="on">&#160;</span></em></a></tpl>');c.overwrite(this.el,this.colors);this.mon(this.el,this.clickEvent,this.handleClick,this,{delegate:"a"});if(this.clickEvent!="click"){this.mon(this.el,"click",Ext.emptyFn,this,{delegate:"a",preventDefault:true})}},afterRender:function(){Ext.ColorPalette.superclass.afterRender.call(this);if(this.value){var a=this.value;this.value=null;this.select(a,true)}},handleClick:function(b,a){b.preventDefault();if(!this.disabled){var d=a.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];this.select(d.toUpperCase())}},select:function(b,a){b=b.replace("#","");if(b!=this.value||this.allowReselect){var c=this.el;if(this.value){c.child("a.color-"+this.value).removeClass("x-color-palette-sel")}c.child("a.color-"+b).addClass("x-color-palette-sel");this.value=b;if(a!==true){this.fireEvent("select",this,b)}}}});Ext.reg("colorpalette",Ext.ColorPalette);Ext.DatePicker=Ext.extend(Ext.BoxComponent,{todayText:"Today",okText:"&#160;OK&#160;",cancelText:"Cancel",todayTip:"{0} (Spacebar)",minText:"This date is before the minimum date",maxText:"This date is after the maximum date",format:"m/d/y",disabledDaysText:"Disabled",disabledDatesText:"Disabled",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,showToday:true,focusOnSelect:true,initHour:12,initComponent:function(){Ext.DatePicker.superclass.initComponent.call(this);this.value=this.value?this.value.clearTime(true):new Date().clearTime();this.addEvents("select");if(this.handler){this.on("select",this.handler,this.scope||this)}this.initDisabledDays()},initDisabledDays:function(){if(!this.disabledDatesRE&&this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){if(Ext.isArray(a)){this.disabledDates=a;this.disabledDatesRE=null}else{this.disabledDatesRE=a}this.initDisabledDays();this.update(this.value,true)},setDisabledDays:function(a){this.disabledDays=a;this.update(this.value,true)},setMinDate:function(a){this.minDate=a;this.update(this.value,true)},setMaxDate:function(a){this.maxDate=a;this.update(this.value,true)},setValue:function(a){this.value=a.clearTime(true);this.update(this.value)},getValue:function(){return this.value},focus:function(){this.update(this.activeDate)},onEnable:function(a){Ext.DatePicker.superclass.onEnable.call(this);this.doDisabled(false);this.update(a?this.value:this.activeDate);if(Ext.isIE9m){this.el.repaint()}},onDisable:function(){Ext.DatePicker.superclass.onDisable.call(this);this.doDisabled(true);if(Ext.isIE9m&&!Ext.isIE8){Ext.each([].concat(this.textNodes,this.el.query("th span")),function(a){Ext.fly(a).repaint()})}},doDisabled:function(a){this.keyNav.setDisabled(a);this.prevRepeater.setDisabled(a);this.nextRepeater.setDisabled(a);if(this.showToday){this.todayKeyListener.setDisabled(a);this.todayBtn.setDisabled(a)}},onRender:function(e,b){var a=['<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>'],c=this.dayNames,h;for(h=0;h<7;h++){var k=this.startDay+h;if(k>6){k=k-7}a.push("<th><span>",c[k].substr(0,1),"</span></th>")}a[a.length]="</tr></thead><tbody><tr>";for(h=0;h<42;h++){if(h%7===0&&h!==0){a[a.length]="</tr><tr>"}a[a.length]='<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>'}a.push("</tr></tbody></table></td></tr>",this.showToday?'<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>':"",'</table><div class="x-date-mp"></div>');var j=document.createElement("div");j.className="x-date-picker";j.innerHTML=a.join("");e.dom.insertBefore(j,b);this.el=Ext.get(j);this.eventEl=Ext.get(j.firstChild);this.prevRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"),{handler:this.showPrevMonth,scope:this,preventDefault:true,stopDefault:true});this.nextRepeater=new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"),{handler:this.showNextMonth,scope:this,preventDefault:true,stopDefault:true});this.monthPicker=this.el.down("div.x-date-mp");this.monthPicker.enableDisplayMode("block");this.keyNav=new Ext.KeyNav(this.eventEl,{left:function(d){if(d.ctrlKey){this.showPrevMonth()}else{this.update(this.activeDate.add("d",-1))}},right:function(d){if(d.ctrlKey){this.showNextMonth()}else{this.update(this.activeDate.add("d",1))}},up:function(d){if(d.ctrlKey){this.showNextYear()}else{this.update(this.activeDate.add("d",-7))}},down:function(d){if(d.ctrlKey){this.showPrevYear()}else{this.update(this.activeDate.add("d",7))}},pageUp:function(d){this.showNextMonth()},pageDown:function(d){this.showPrevMonth()},enter:function(d){d.stopPropagation();return true},scope: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");this.mbtn=new Ext.Button({text:"&#160;",tooltip:this.monthYearText,renderTo:this.el.child("td.x-date-middle",true)});this.mbtn.el.child("em").addClass("x-btn-arrow");if(this.showToday){this.todayKeyListener=this.eventEl.addKeyListener(Ext.EventObject.SPACE,this.selectToday,this);var g=(new Date()).dateFormat(this.format);this.todayBtn=new Ext.Button({renderTo:this.el.child("td.x-date-bottom",true),text:String.format(this.todayText,g),tooltip:String.format(this.todayTip,g),handler:this.selectToday,scope:this})}this.mon(this.eventEl,"mousewheel",this.handleMouseWheel,this);this.mon(this.eventEl,"click",this.handleDateClick,this,{delegate:"a.x-date-date"});this.mon(this.mbtn,"click",this.showMonthPicker,this);this.onEnable(true)},createMonthPicker:function(){if(!this.monthPicker.dom.firstChild){var a=['<table border="0" cellspacing="0">'];for(var b=0;b<6;b++){a.push('<tr><td class="x-date-mp-month"><a href="#">',Date.getShortMonthName(b),"</a></td>",'<td class="x-date-mp-month x-date-mp-sep"><a href="#">',Date.getShortMonthName(b+6),"</a></td>",b===0?'<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>':'<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>')}a.push('<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',this.okText,'</button><button type="button" class="x-date-mp-cancel">',this.cancelText,"</button></td></tr>","</table>");this.monthPicker.update(a.join(""));this.mon(this.monthPicker,"click",this.onMonthClick,this);this.mon(this.monthPicker,"dblclick",this.onMonthDblClick,this);this.mpMonths=this.monthPicker.select("td.x-date-mp-month");this.mpYears=this.monthPicker.select("td.x-date-mp-year");this.mpMonths.each(function(c,d,e){e+=1;if((e%2)===0){c.dom.xmonth=5+Math.round(e*0.5)}else{c.dom.xmonth=Math.round((e-1)*0.5)}})}},showMonthPicker:function(){if(!this.disabled){this.createMonthPicker();var a=this.el.getSize();this.monthPicker.setSize(a);this.monthPicker.child("table").setSize(a);this.mpSelMonth=(this.activeDate||this.value).getMonth();this.updateMPMonth(this.mpSelMonth);this.mpSelYear=(this.activeDate||this.value).getFullYear();this.updateMPYear(this.mpSelYear);this.monthPicker.slideIn("t",{duration:0.2})}},updateMPYear:function(e){this.mpyear=e;var c=this.mpYears.elements;for(var b=1;b<=10;b++){var d=c[b-1],a;if((b%2)===0){a=e+Math.round(b*0.5);d.firstChild.innerHTML=a;d.xyear=a}else{a=e-(5-Math.round(b*0.5));d.firstChild.innerHTML=a;d.xyear=a}this.mpYears.item(b-1)[a==this.mpSelYear?"addClass":"removeClass"]("x-date-mp-sel")}},updateMPMonth:function(a){this.mpMonths.each(function(b,c,d){b[b.dom.xmonth==a?"addClass":"removeClass"]("x-date-mp-sel")})},selectMPMonth:function(a){},onMonthClick:function(g,b){g.stopEvent();var c=new Ext.Element(b),a;if(c.is("button.x-date-mp-cancel")){this.hideMonthPicker()}else{if(c.is("button.x-date-mp-ok")){var h=new Date(this.mpSelYear,this.mpSelMonth,(this.activeDate||this.value).getDate());if(h.getMonth()!=this.mpSelMonth){h=new Date(this.mpSelYear,this.mpSelMonth,1).getLastDateOfMonth()}this.update(h);this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-month",2))){this.mpMonths.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelMonth=a.dom.xmonth}else{if((a=c.up("td.x-date-mp-year",2))){this.mpYears.removeClass("x-date-mp-sel");a.addClass("x-date-mp-sel");this.mpSelYear=a.dom.xyear}else{if(c.is("a.x-date-mp-prev")){this.updateMPYear(this.mpyear-10)}else{if(c.is("a.x-date-mp-next")){this.updateMPYear(this.mpyear+10)}}}}}}},onMonthDblClick:function(d,b){d.stopEvent();var c=new Ext.Element(b),a;if((a=c.up("td.x-date-mp-month",2))){this.update(new Date(this.mpSelYear,a.dom.xmonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}else{if((a=c.up("td.x-date-mp-year",2))){this.update(new Date(a.dom.xyear,this.mpSelMonth,(this.activeDate||this.value).getDate()));this.hideMonthPicker()}}},hideMonthPicker:function(a){if(this.monthPicker){if(a===true){this.monthPicker.hide()}else{this.monthPicker.slideOut("t",{duration:0.2})}}},showPrevMonth:function(a){this.update(this.activeDate.add("mo",-1))},showNextMonth:function(a){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(a){a.stopEvent();if(!this.disabled){var b=a.getWheelDelta();if(b>0){this.showPrevMonth()}else{if(b<0){this.showNextMonth()}}}},handleDateClick:function(b,a){b.stopEvent();if(!this.disabled&&a.dateValue&&!Ext.fly(a.parentNode).hasClass("x-date-disabled")){this.cancelFocus=this.focusOnSelect===false;this.setValue(new Date(a.dateValue));delete this.cancelFocus;this.fireEvent("select",this,this.value)}},selectToday:function(){if(this.todayBtn&&!this.todayBtn.disabled){this.setValue(new Date().clearTime());this.fireEvent("select",this,this.value)}},update:function(G,A){if(this.rendered){var a=this.activeDate,p=this.isVisible();this.activeDate=G;if(!A&&a&&this.el){var o=G.getTime();if(a.getMonth()==G.getMonth()&&a.getFullYear()==G.getFullYear()){this.cells.removeClass("x-date-selected");this.cells.each(function(d){if(d.dom.firstChild.dateValue==o){d.addClass("x-date-selected");if(p&&!this.cancelFocus){Ext.fly(d.dom.firstChild).focus(50)}return false}},this);return}}var k=G.getDaysInMonth(),q=G.getFirstDateOfMonth(),g=q.getDay()-this.startDay;if(g<0){g+=7}k+=g;var B=G.add("mo",-1),h=B.getDaysInMonth()-g,e=this.cells.elements,r=this.textNodes,D=(new Date(B.getFullYear(),B.getMonth(),h,this.initHour)),C=new Date().clearTime().getTime(),v=G.clearTime(true).getTime(),u=this.minDate?this.minDate.clearTime(true):Number.NEGATIVE_INFINITY,y=this.maxDate?this.maxDate.clearTime(true):Number.POSITIVE_INFINITY,F=this.disabledDatesRE,s=this.disabledDatesText,I=this.disabledDays?this.disabledDays.join(""):false,E=this.disabledDaysText,z=this.format;if(this.showToday){var m=new Date().clearTime(),c=(m<u||m>y||(F&&z&&F.test(m.dateFormat(z)))||(I&&I.indexOf(m.getDay())!=-1));if(!this.disabled){this.todayBtn.setDisabled(c);this.todayKeyListener[c?"disable":"enable"]()}}var l=function(J,d){d.title="";var i=D.clearTime(true).getTime();d.firstChild.dateValue=i;if(i==C){d.className+=" x-date-today";d.title=J.todayText}if(i==v){d.className+=" x-date-selected";if(p){Ext.fly(d.firstChild).focus(50)}}if(i<u){d.className=" x-date-disabled";d.title=J.minText;return}if(i>y){d.className=" x-date-disabled";d.title=J.maxText;return}if(I){if(I.indexOf(D.getDay())!=-1){d.title=E;d.className=" x-date-disabled"}}if(F&&z){var w=D.dateFormat(z);if(F.test(w)){d.title=s.replace("%0",w);d.className=" x-date-disabled"}}};var x=0;for(;x<g;x++){r[x].innerHTML=(++h);D.setDate(D.getDate()+1);e[x].className="x-date-prevday";l(this,e[x])}for(;x<k;x++){var b=x-g+1;r[x].innerHTML=(b);D.setDate(D.getDate()+1);e[x].className="x-date-active";l(this,e[x])}var H=0;for(;x<42;x++){r[x].innerHTML=(++H);D.setDate(D.getDate()+1);e[x].className="x-date-nextday";l(this,e[x])}this.mbtn.setText(this.monthNames[G.getMonth()]+" "+G.getFullYear());if(!this.internalRender){var j=this.el.dom.firstChild,n=j.offsetWidth;this.el.setWidth(n+this.el.getBorderWidth("lr"));Ext.fly(j).setWidth(n);this.internalRender=true;if(Ext.isOpera&&!this.secondPass){j.rows[0].cells[1].style.width=(n-(j.rows[0].cells[0].offsetWidth+j.rows[0].cells[2].offsetWidth))+"px";this.secondPass=true;this.update.defer(10,this,[G])}}}},beforeDestroy:function(){if(this.rendered){Ext.destroy(this.keyNav,this.monthPicker,this.eventEl,this.mbtn,this.nextRepeater,this.prevRepeater,this.cells.el,this.todayBtn);delete this.textNodes;delete this.cells.elements}}});Ext.reg("datepicker",Ext.DatePicker);Ext.LoadMask=function(c,b){this.el=Ext.get(c);Ext.apply(this,b);if(this.store){this.store.on({scope:this,beforeload:this.onBeforeLoad,load:this.onLoad,exception:this.onLoad});this.removeMask=Ext.value(this.removeMask,false)}else{var a=this.el.getUpdater();a.showLoadIndicator=false;a.on({scope:this,beforeupdate:this.onBeforeLoad,update:this.onLoad,failure:this.onLoad});this.removeMask=Ext.value(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)}},show:function(){this.onBeforeLoad()},hide:function(){this.onLoad()},destroy:function(){if(this.store){this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.onLoad,this)}else{var a=this.el.getUpdater();a.un("beforeupdate",this.onBeforeLoad,this);a.un("update",this.onLoad,this);a.un("failure",this.onLoad,this)}}};Ext.slider.Thumb=Ext.extend(Object,{dragging:false,constructor:function(a){Ext.apply(this,a||{},{cls:"x-slider-thumb",constrain:false});Ext.slider.Thumb.superclass.constructor.call(this,a);if(this.slider.vertical){Ext.apply(this,Ext.slider.Thumb.Vertical)}},render:function(){this.el=this.slider.innerEl.insertFirst({cls:this.cls});this.initEvents()},enable:function(){this.disabled=false;this.el.removeClass(this.slider.disabledClass)},disable:function(){this.disabled=true;this.el.addClass(this.slider.disabledClass)},initEvents:function(){var a=this.el;a.addClassOnOver("x-slider-thumb-over");this.tracker=new Ext.dd.DragTracker({onBeforeStart:this.onBeforeDragStart.createDelegate(this),onStart:this.onDragStart.createDelegate(this),onDrag:this.onDrag.createDelegate(this),onEnd:this.onDragEnd.createDelegate(this),tolerance:3,autoStart:300});this.tracker.initEl(a)},onBeforeDragStart:function(a){if(this.disabled){return false}else{this.slider.promoteThumb(this);return true}},onDragStart:function(a){this.el.addClass("x-slider-thumb-drag");this.dragging=true;this.dragStartValue=this.value;this.slider.fireEvent("dragstart",this.slider,a,this)},onDrag:function(g){var c=this.slider,b=this.index,d=this.getNewValue();if(this.constrain){var a=c.thumbs[b+1],h=c.thumbs[b-1];if(h!=undefined&&d<=h.value){d=h.value}if(a!=undefined&&d>=a.value){d=a.value}}c.setValue(b,d,false);c.fireEvent("drag",c,g,this)},getNewValue:function(){var a=this.slider,b=a.innerEl.translatePoints(this.tracker.getXY());return Ext.util.Format.round(a.reverseValue(b.left),a.decimalPrecision)},onDragEnd:function(c){var a=this.slider,b=this.value;this.el.removeClass("x-slider-thumb-drag");this.dragging=false;a.fireEvent("dragend",a,c);if(this.dragStartValue!=b){a.fireEvent("changecomplete",a,b,this)}},destroy:function(){Ext.destroyMembers(this,"tracker","el")}});Ext.slider.MultiSlider=Ext.extend(Ext.BoxComponent,{vertical:false,minValue:0,maxValue:100,decimalPrecision:0,keyIncrement:1,increment:0,clickRange:[5,15],clickToChange:true,animate:true,constrainThumbs:true,topThumbZIndex:10000,initComponent:function(){if(!Ext.isDefined(this.value)){this.value=this.minValue}this.thumbs=[];Ext.slider.MultiSlider.superclass.initComponent.call(this);this.keyIncrement=Math.max(this.increment,this.keyIncrement);this.addEvents("beforechange","change","changecomplete","dragstart","drag","dragend");if(this.values==undefined||Ext.isEmpty(this.values)){this.values=[0]}var a=this.values;for(var b=0;b<a.length;b++){this.addThumb(a[b])}if(this.vertical){Ext.apply(this,Ext.slider.Vertical)}},addThumb:function(b){var a=new Ext.slider.Thumb({value:b,slider:this,index:this.thumbs.length,constrain:this.constrainThumbs});this.thumbs.push(a);if(this.rendered){a.render()}},promoteThumb:function(d){var a=this.thumbs,g,b;for(var e=0,c=a.length;e<c;e++){b=a[e];if(b==d){g=this.topThumbZIndex}else{g=""}b.el.setStyle("zIndex",g)}},onRender:function(){this.autoEl={cls:"x-slider "+(this.vertical?"x-slider-vert":"x-slider-horz"),cn:{cls:"x-slider-end",cn:{cls:"x-slider-inner",cn:[{tag:"a",cls:"x-slider-focus",href:"#",tabIndex:"-1",hidefocus:"on"}]}}};Ext.slider.MultiSlider.superclass.onRender.apply(this,arguments);this.endEl=this.el.first();this.innerEl=this.endEl.first();this.focusEl=this.innerEl.child(".x-slider-focus");for(var b=0;b<this.thumbs.length;b++){this.thumbs[b].render()}var a=this.innerEl.child(".x-slider-thumb");this.halfThumb=(this.vertical?a.getHeight():a.getWidth())/2;this.initEvents()},initEvents:function(){this.mon(this.el,{scope:this,mousedown:this.onMouseDown,keydown:this.onKeyDown});this.focusEl.swallowEvent("click",true)},onMouseDown:function(d){if(this.disabled){return}var c=false;for(var b=0;b<this.thumbs.length;b++){c=c||d.target==this.thumbs[b].el.dom}if(this.clickToChange&&!c){var a=this.innerEl.translatePoints(d.getXY());this.onClickChange(a)}this.focus()},onClickChange:function(c){if(c.top>this.clickRange[0]&&c.top<this.clickRange[1]){var a=this.getNearest(c,"left"),b=a.index;this.setValue(b,Ext.util.Format.round(this.reverseValue(c.left),this.decimalPrecision),undefined,true)}},getNearest:function(k,b){var m=b=="top"?this.innerEl.getHeight()-k[b]:k[b],g=this.reverseValue(m),j=(this.maxValue-this.minValue)+5,e=0,c=null;for(var d=0;d<this.thumbs.length;d++){var a=this.thumbs[d],l=a.value,h=Math.abs(l-g);if(Math.abs(h<=j)){c=a;e=d;j=h}}return c},onKeyDown:function(b){if(this.disabled||this.thumbs.length!==1){b.preventDefault();return}var a=b.getKey(),c;switch(a){case b.UP:case b.RIGHT:b.stopEvent();c=b.ctrlKey?this.maxValue:this.getValue(0)+this.keyIncrement;this.setValue(0,c,undefined,true);break;case b.DOWN:case b.LEFT:b.stopEvent();c=b.ctrlKey?this.minValue:this.getValue(0)-this.keyIncrement;this.setValue(0,c,undefined,true);break;default:b.preventDefault()}},doSnap:function(b){if(!(this.increment&&b)){return b}var d=b,c=this.increment,a=b%c;if(a!=0){d-=a;if(a*2>=c){d+=c}else{if(a*2<-c){d-=c}}}return d.constrain(this.minValue,this.maxValue)},afterRender:function(){Ext.slider.MultiSlider.superclass.afterRender.apply(this,arguments);for(var c=0;c<this.thumbs.length;c++){var b=this.thumbs[c];if(b.value!==undefined){var a=this.normalizeValue(b.value);if(a!==b.value){this.setValue(c,a,false)}else{this.moveThumb(c,this.translateValue(a),false)}}}},getRatio:function(){var a=this.innerEl.getWidth(),b=this.maxValue-this.minValue;return b==0?a:(a/b)},normalizeValue:function(a){a=this.doSnap(a);a=Ext.util.Format.round(a,this.decimalPrecision);a=a.constrain(this.minValue,this.maxValue);return a},setMinValue:function(e){this.minValue=e;var d=0,b=this.thumbs,a=b.length,c;for(;d<a;++d){c=b[d];c.value=c.value<e?e:c.value}this.syncThumb()},setMaxValue:function(e){this.maxValue=e;var d=0,b=this.thumbs,a=b.length,c;for(;d<a;++d){c=b[d];c.value=c.value>e?e:c.value}this.syncThumb()},setValue:function(d,c,b,g){var a=this.thumbs[d],e=a.el;c=this.normalizeValue(c);if(c!==a.value&&this.fireEvent("beforechange",this,c,a.value,a)!==false){a.value=c;if(this.rendered){this.moveThumb(d,this.translateValue(c),b!==false);this.fireEvent("change",this,c,a);if(g){this.fireEvent("changecomplete",this,c,a)}}}},translateValue:function(a){var b=this.getRatio();return(a*b)-(this.minValue*b)-this.halfThumb},reverseValue:function(b){var a=this.getRatio();return(b+(this.minValue*a))/a},moveThumb:function(d,c,b){var a=this.thumbs[d].el;if(!b||this.animate===false){a.setLeft(c)}else{a.shift({left:c,stopFx:true,duration:0.35})}},focus:function(){this.focusEl.focus(10)},onResize:function(c,e){var b=this.thumbs,a=b.length,d=0;for(;d<a;++d){b[d].el.stopFx()}if(Ext.isNumber(c)){this.innerEl.setWidth(c-(this.el.getPadding("l")+this.endEl.getPadding("r")))}this.syncThumb();Ext.slider.MultiSlider.superclass.onResize.apply(this,arguments)},onDisable:function(){Ext.slider.MultiSlider.superclass.onDisable.call(this);for(var b=0;b<this.thumbs.length;b++){var a=this.thumbs[b],c=a.el;a.disable();if(Ext.isIE){var d=c.getXY();c.hide();this.innerEl.addClass(this.disabledClass).dom.disabled=true;if(!this.thumbHolder){this.thumbHolder=this.endEl.createChild({cls:"x-slider-thumb "+this.disabledClass})}this.thumbHolder.show().setXY(d)}}},onEnable:function(){Ext.slider.MultiSlider.superclass.onEnable.call(this);for(var b=0;b<this.thumbs.length;b++){var a=this.thumbs[b],c=a.el;a.enable();if(Ext.isIE){this.innerEl.removeClass(this.disabledClass).dom.disabled=false;if(this.thumbHolder){this.thumbHolder.hide()}c.show();this.syncThumb()}}},syncThumb:function(){if(this.rendered){for(var a=0;a<this.thumbs.length;a++){this.moveThumb(a,this.translateValue(this.thumbs[a].value))}}},getValue:function(a){return this.thumbs[a].value},getValues:function(){var a=[];for(var b=0;b<this.thumbs.length;b++){a.push(this.thumbs[b].value)}return a},beforeDestroy:function(){var b=this.thumbs;for(var c=0,a=b.length;c<a;++c){b[c].destroy();b[c]=null}Ext.destroyMembers(this,"endEl","innerEl","focusEl","thumbHolder");Ext.slider.MultiSlider.superclass.beforeDestroy.call(this)}});Ext.reg("multislider",Ext.slider.MultiSlider);Ext.slider.SingleSlider=Ext.extend(Ext.slider.MultiSlider,{constructor:function(a){a=a||{};Ext.applyIf(a,{values:[a.value||0]});Ext.slider.SingleSlider.superclass.constructor.call(this,a)},getValue:function(){return Ext.slider.SingleSlider.superclass.getValue.call(this,0)},setValue:function(d,b){var c=Ext.toArray(arguments),a=c.length;if(a==1||(a<=3&&typeof arguments[1]!="number")){c.unshift(0)}return Ext.slider.SingleSlider.superclass.setValue.apply(this,c)},syncThumb:function(){return Ext.slider.SingleSlider.superclass.syncThumb.apply(this,[0].concat(arguments))},getNearest:function(){return this.thumbs[0]}});Ext.Slider=Ext.slider.SingleSlider;Ext.reg("slider",Ext.slider.SingleSlider);Ext.slider.Vertical={onResize:function(a,b){this.innerEl.setHeight(b-(this.el.getPadding("t")+this.endEl.getPadding("b")));this.syncThumb()},getRatio:function(){var b=this.innerEl.getHeight(),a=this.maxValue-this.minValue;return b/a},moveThumb:function(d,c,b){var a=this.thumbs[d],e=a.el;if(!b||this.animate===false){e.setBottom(c)}else{e.shift({bottom:c,stopFx:true,duration:0.35})}},onClickChange:function(c){if(c.left>this.clickRange[0]&&c.left<this.clickRange[1]){var a=this.getNearest(c,"top"),b=a.index,d=this.minValue+this.reverseValue(this.innerEl.getHeight()-c.top);this.setValue(b,Ext.util.Format.round(d,this.decimalPrecision),undefined,true)}}};Ext.slider.Thumb.Vertical={getNewValue:function(){var b=this.slider,c=b.innerEl,d=c.translatePoints(this.tracker.getXY()),a=c.getHeight()-d.top;return b.minValue+Ext.util.Format.round(a/b.getRatio(),b.decimalPrecision)}};Ext.ProgressBar=Ext.extend(Ext.BoxComponent,{baseCls:"x-progress",animate:false,waitTimer:null,initComponent:function(){Ext.ProgressBar.superclass.initComponent.call(this);this.addEvents("update")},onRender:function(d,a){var c=new Ext.Template('<div class="{cls}-wrap">','<div class="{cls}-inner">','<div class="{cls}-bar">','<div class="{cls}-text">',"<div>&#160;</div>","</div>","</div>",'<div class="{cls}-text {cls}-text-back">',"<div>&#160;</div>","</div>","</div>","</div>");this.el=a?c.insertBefore(a,{cls:this.baseCls},true):c.append(d,{cls:this.baseCls},true);if(this.id){this.el.dom.id=this.id}var b=this.el.dom.firstChild;this.progressBar=Ext.get(b.firstChild);if(this.textEl){this.textEl=Ext.get(this.textEl);delete this.textTopEl}else{this.textTopEl=Ext.get(this.progressBar.dom.firstChild);var e=Ext.get(b.childNodes[1]);this.textTopEl.setStyle("z-index",99).addClass("x-hidden");this.textEl=new Ext.CompositeElement([this.textTopEl.dom.firstChild,e.dom.firstChild]);this.textEl.setWidth(b.offsetWidth)}this.progressBar.setHeight(b.offsetHeight)},afterRender:function(){Ext.ProgressBar.superclass.afterRender.call(this);if(this.value){this.updateProgress(this.value,this.text)}else{this.updateText(this.text)}},updateProgress:function(c,d,b){this.value=c||0;if(d){this.updateText(d)}if(this.rendered&&!this.isDestroyed){var a=Math.floor(c*this.el.dom.firstChild.offsetWidth);this.progressBar.setWidth(a,b===true||(b!==false&&this.animate));if(this.textTopEl){this.textTopEl.removeClass("x-hidden").setWidth(a)}}this.fireEvent("update",this,c,d);return this},wait:function(b){if(!this.waitTimer){var a=this;b=b||{};this.updateText(b.text);this.waitTimer=Ext.TaskMgr.start({run:function(c){var d=b.increment||10;c-=1;this.updateProgress(((((c+d)%d)+1)*(100/d))*0.01,null,b.animate)},interval:b.interval||1000,duration:b.duration,onStop:function(){if(b.fn){b.fn.apply(b.scope||this)}this.reset()},scope:a})}return this},isWaiting:function(){return this.waitTimer!==null},updateText:function(a){this.text=a||"&#160;";if(this.rendered){this.textEl.update(this.text)}return this},syncProgressBar:function(){if(this.value){this.updateProgress(this.value,this.text)}return this},setSize:function(a,c){Ext.ProgressBar.superclass.setSize.call(this,a,c);if(this.textTopEl){var b=this.el.dom.firstChild;this.textEl.setSize(b.offsetWidth,b.offsetHeight)}this.syncProgressBar();return this},reset:function(a){this.updateProgress(0);if(this.textTopEl){this.textTopEl.addClass("x-hidden")}this.clearTimer();if(a===true){this.hide()}return this},clearTimer:function(){if(this.waitTimer){this.waitTimer.onStop=null;Ext.TaskMgr.stop(this.waitTimer);this.waitTimer=null}},onDestroy:function(){this.clearTimer();if(this.rendered){if(this.textEl.isComposite){this.textEl.clear()}Ext.destroyMembers(this,"textEl","progressBar","textTopEl")}Ext.ProgressBar.superclass.onDestroy.call(this)}});Ext.reg("progress",Ext.ProgressBar);(function(){var a=Ext.EventManager;var b=Ext.lib.Dom;Ext.dd.DragDrop=function(e,c,d){if(e){this.init(e,c,d)}};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},moveOnly:false,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(c,d){},startDrag:function(c,d){},b4Drag:function(c){},onDrag:function(c){},onDragEnter:function(c,d){},b4DragOver:function(c){},onDragOver:function(c,d){},b4DragOut:function(c){},onDragOut:function(c,d){},b4DragDrop:function(c){},onDragDrop:function(c,d){},onInvalidDrop:function(c){},b4EndDrag:function(c){},endDrag:function(c){},b4MouseDown:function(c){},onMouseDown:function(c){},onMouseUp:function(c){},onAvailable:function(){},defaultPadding:{left:0,right:0,top:0,bottom:0},constrainTo:function(j,h,o){if(Ext.isNumber(h)){h={left:h,right:h,top:h,bottom:h}}h=h||this.defaultPadding;var l=Ext.get(this.getEl()).getBox(),d=Ext.get(j),n=d.getScroll(),k,e=d.dom;if(e==document.body){k={x:n.left,y:n.top,width:Ext.lib.Dom.getViewWidth(),height:Ext.lib.Dom.getViewHeight()}}else{var m=d.getXY();k={x:m[0],y:m[1],width:e.clientWidth,height:e.clientHeight}}var i=l.y-k.y,g=l.x-k.x;this.resetConstraints();this.setXConstraint(g-(h.left||0),k.width-g-l.width-(h.right||0),this.xTickSize);this.setYConstraint(i-(h.top||0),k.height-i-l.height-(h.bottom||0),this.yTickSize)},getEl:function(){if(!this._domRef){this._domRef=Ext.getDom(this.id)}return this._domRef},getDragEl:function(){return Ext.getDom(this.dragElId)},init:function(e,c,d){this.initTarget(e,c,d);a.on(this.id,"mousedown",this.handleMouseDown,this)},initTarget:function(e,c,d){this.config=d||{};this.DDM=Ext.dd.DDM;this.groups={};if(typeof e!=="string"){e=Ext.id(e)}this.id=e;this.addToGroup((c)?c:"default");this.handleElId=e;this.setDragElId(e);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(e,c,g,d){if(!c&&0!==c){this.padding=[e,e,e,e]}else{if(!g&&0!==g){this.padding=[e,c,e,c]}else{this.padding=[e,c,g,d]}}},setInitPosition:function(g,e){var h=this.getEl();if(!this.DDM.verifyEl(h)){return}var d=g||0;var c=e||0;var i=b.getXY(h);this.initPageX=i[0]-d;this.initPageY=i[1]-c;this.lastPageX=i[0];this.lastPageY=i[1];this.setStartPosition(i)},setStartPosition:function(d){var c=d||b.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=c[0];this.startPageY=c[1]},addToGroup:function(c){this.groups[c]=true;this.DDM.regDragDrop(this,c)},removeFromGroup:function(c){if(this.groups[c]){delete this.groups[c]}this.DDM.removeDDFromGroup(this,c)},setDragElId:function(c){this.dragElId=c},setHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.handleElId=c;this.DDM.regHandle(this.id,c)},setOuterHandleElId:function(c){if(typeof c!=="string"){c=Ext.id(c)}a.on(c,"mousedown",this.handleMouseDown,this);this.setHandleElId(c);this.hasOuterHandles=true},unreg:function(){a.un(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this)},destroy:function(){this.unreg()},isLocked:function(){return(this.DDM.isLocked()||this.locked)},handleMouseDown:function(g,d){if(this.primaryButtonOnly&&g.button!=0){return}if(this.isLocked()){return}this.DDM.refreshCache(this.groups);var c=new Ext.lib.Point(Ext.lib.Event.getPageX(g),Ext.lib.Event.getPageY(g));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(c,this)){}else{if(this.clickValidator(g)){this.setStartPosition();this.b4MouseDown(g);this.onMouseDown(g);this.DDM.handleMouseDown(g,this);if(this.preventDefault||this.stopPropagation){if(this.preventDefault){g.preventDefault()}if(this.stopPropagation){g.stopPropagation()}}else{this.DDM.stopEvent(g)}}else{}}},clickValidator:function(d){var c=d.getTarget();return(this.isValidHandleChild(c)&&(this.id==this.handleElId||this.DDM.handleWasClicked(c,this.id)))},addInvalidHandleType:function(c){var d=c.toUpperCase();this.invalidHandleTypes[d]=d},addInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}this.invalidHandleIds[c]=c},addInvalidHandleClass:function(c){this.invalidHandleClasses.push(c)},removeInvalidHandleType:function(c){var d=c.toUpperCase();delete this.invalidHandleTypes[d]},removeInvalidHandleId:function(c){if(typeof c!=="string"){c=Ext.id(c)}delete this.invalidHandleIds[c]},removeInvalidHandleClass:function(d){for(var e=0,c=this.invalidHandleClasses.length;e<c;++e){if(this.invalidHandleClasses[e]==d){delete this.invalidHandleClasses[e]}}},isValidHandleChild:function(h){var g=true;var k;try{k=h.nodeName.toUpperCase()}catch(j){k=h.nodeName}g=g&&!this.invalidHandleTypes[k];g=g&&!this.invalidHandleIds[h.id];for(var d=0,c=this.invalidHandleClasses.length;g&&d<c;++d){g=!Ext.fly(h).hasClass(this.invalidHandleClasses[d])}return g},setXTicks:function(g,c){this.xTicks=[];this.xTickSize=c;var e={};for(var d=this.initPageX;d>=this.minX;d=d-c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}for(d=this.initPageX;d<=this.maxX;d=d+c){if(!e[d]){this.xTicks[this.xTicks.length]=d;e[d]=true}}this.xTicks.sort(this.DDM.numericSort)},setYTicks:function(g,c){this.yTicks=[];this.yTickSize=c;var e={};for(var d=this.initPageY;d>=this.minY;d=d-c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}for(d=this.initPageY;d<=this.maxY;d=d+c){if(!e[d]){this.yTicks[this.yTicks.length]=d;e[d]=true}}this.yTicks.sort(this.DDM.numericSort)},setXConstraint:function(e,d,c){this.leftConstraint=e;this.rightConstraint=d;this.minX=this.initPageX-e;this.maxX=this.initPageX+d;if(c){this.setXTicks(this.initPageX,c)}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(c,e,d){this.topConstraint=c;this.bottomConstraint=e;this.minY=this.initPageY-c;this.maxY=this.initPageY+e;if(d){this.setYTicks(this.initPageY,d)}this.constrainY=true},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var d=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var c=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(d,c)}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(k,g){if(!g){return k}else{if(g[0]>=k){return g[0]}else{for(var d=0,c=g.length;d<c;++d){var e=d+1;if(g[e]&&g[e]>=k){var j=k-g[d];var h=g[e]-k;return(h>j)?g[d]:g[e]}}return g[g.length-1]}}},toString:function(){return("DragDrop "+this.id)}}})();if(!Ext.dd.DragDropMgr){Ext.dd.DragDropMgr=function(){var a=Ext.EventManager;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,init:function(){this.initialized=true},POINT:0,INTERSECT:1,mode:0,notifyOccluded:false,_execOnAll:function(d,c){for(var e in this.ids){for(var b in this.ids[e]){var g=this.ids[e][b];if(!this.isTypeOfDD(g)){continue}g[d].apply(g,c)}}},_onLoad:function(){this.init();a.on(document,"mouseup",this.handleMouseUp,this,true);a.on(document,"mousemove",this.handleMouseMove,this,true);a.on(window,"unload",this._onUnload,this,true);a.on(window,"resize",this._onResize,this,true)},_onResize:function(b){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(c,b){if(!this.initialized){this.init()}if(!this.ids[b]){this.ids[b]={}}this.ids[b][c.id]=c},removeDDFromGroup:function(d,b){if(!this.ids[b]){this.ids[b]={}}var c=this.ids[b];if(c&&c[d.id]){delete c[d.id]}},_remove:function(c){for(var b in c.groups){if(b&&this.ids[b]&&this.ids[b][c.id]){delete this.ids[b][c.id]}}delete this.handleIds[c.id]},regHandle:function(c,b){if(!this.handleIds[c]){this.handleIds[c]={}}this.handleIds[c][b]=b},isDragDrop:function(b){return(this.getDDById(b))?true:false},getRelated:function(h,c){var g=[];for(var e in h.groups){for(var d in this.ids[e]){var b=this.ids[e][d];if(!this.isTypeOfDD(b)){continue}if(!c||b.isTarget){g[g.length]=b}}}return g},isLegalTarget:function(g,e){var c=this.getRelated(g,true);for(var d=0,b=c.length;d<b;++d){if(c[d].id==e.id){return true}}return false},isTypeOfDD:function(b){return(b&&b.__ygDragDrop)},isHandle:function(c,b){return(this.handleIds[c]&&this.handleIds[c][b])},getDDById:function(c){for(var b in this.ids){if(this.ids[b][c]){return this.ids[b][c]}}return null},handleMouseDown:function(d,c){if(Ext.QuickTips){Ext.QuickTips.ddDisable()}if(this.dragCurrent){this.handleMouseUp(d)}this.currentTarget=d.getTarget();this.dragCurrent=c;var b=c.getEl();this.startX=d.getPageX();this.startY=d.getPageY();this.deltaX=this.startX-b.offsetLeft;this.deltaY=this.startY-b.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var e=Ext.dd.DDM;e.startDrag(e.startX,e.startY)},this.clickTimeThresh)},startDrag:function(b,c){clearTimeout(this.clickTimeout);if(this.dragCurrent){this.dragCurrent.b4StartDrag(b,c);this.dragCurrent.startDrag(b,c)}this.dragThreshMet=true},handleMouseUp:function(b){if(Ext.QuickTips){Ext.QuickTips.ddEnable()}if(!this.dragCurrent){return}clearTimeout(this.clickTimeout);if(this.dragThreshMet){this.fireEvents(b,true)}else{}this.stopDrag(b);this.stopEvent(b)},stopEvent:function(b){if(this.stopPropagation){b.stopPropagation()}if(this.preventDefault){b.preventDefault()}},stopDrag:function(b){if(this.dragCurrent){if(this.dragThreshMet){this.dragCurrent.b4EndDrag(b);this.dragCurrent.endDrag(b)}this.dragCurrent.onMouseUp(b)}this.dragCurrent=null;this.dragOvers={}},handleMouseMove:function(d){if(!this.dragCurrent){return true}if(Ext.isIE&&(d.button!==0&&d.button!==1&&d.button!==2)){this.stopEvent(d);return this.handleMouseUp(d)}if(!this.dragThreshMet){var c=Math.abs(this.startX-d.getPageX());var b=Math.abs(this.startY-d.getPageY());if(c>this.clickPixelThresh||b>this.clickPixelThresh){this.startDrag(this.startX,this.startY)}}if(this.dragThreshMet){this.dragCurrent.b4Drag(d);this.dragCurrent.onDrag(d);if(!this.dragCurrent.moveOnly){this.fireEvents(d,false)}}this.stopEvent(d);return true},fireEvents:function(o,r){var q=this,l=q.dragCurrent,s=o.getPoint(),c,u,g=[],b=[],h=[],m=[],k=[],d=[],p,j,n,t;if(!l||l.isLocked()){return}for(j in q.dragOvers){c=q.dragOvers[j];if(!q.isTypeOfDD(c)){continue}if(!this.isOverTarget(s,c,q.mode)){h.push(c)}b[j]=true;delete q.dragOvers[j]}for(t in l.groups){if("string"!=typeof t){continue}for(j in q.ids[t]){c=q.ids[t][j];if(q.isTypeOfDD(c)&&(u=c.getEl())&&(c.isTarget)&&(!c.isLocked())&&((c!=l)||(l.ignoreSelf===false))){if((c.zIndex=q.getZIndex(u))!==-1){p=true}g.push(c)}}}if(p){g.sort(q.byZIndex)}for(j=0,n=g.length;j<n;j++){c=g[j];if(q.isOverTarget(s,c,q.mode)){if(r){k.push(c)}else{if(!b[c.id]){d.push(c)}else{m.push(c)}q.dragOvers[c.id]=c}if(!q.notifyOccluded){break}}}if(q.mode){if(h.length){l.b4DragOut(o,h);l.onDragOut(o,h)}if(d.length){l.onDragEnter(o,d)}if(m.length){l.b4DragOver(o,m);l.onDragOver(o,m)}if(k.length){l.b4DragDrop(o,k);l.onDragDrop(o,k)}}else{for(j=0,n=h.length;j<n;++j){l.b4DragOut(o,h[j].id);l.onDragOut(o,h[j].id)}for(j=0,n=d.length;j<n;++j){l.onDragEnter(o,d[j].id)}for(j=0,n=m.length;j<n;++j){l.b4DragOver(o,m[j].id);l.onDragOver(o,m[j].id)}for(j=0,n=k.length;j<n;++j){l.b4DragDrop(o,k[j].id);l.onDragDrop(o,k[j].id)}}if(r&&!k.length){l.onInvalidDrop(o)}},getZIndex:function(c){var b=document.body,d,e=-1;c=Ext.getDom(c);while(c!==b){if(!isNaN(d=Number(Ext.fly(c).getStyle("zIndex")))){e=d}c=c.parentNode}return e},byZIndex:function(c,b){return c.zIndex<b.zIndex},getBestMatch:function(d){var g=null;var c=d.length;if(c==1){g=d[0]}else{for(var e=0;e<c;++e){var b=d[e];if(b.cursorIsOver){g=b;break}else{if(!g||g.overlap.getArea()<b.overlap.getArea()){g=b}}}}return g},refreshCache:function(c){for(var b in c){if("string"!=typeof b){continue}for(var d in this.ids[b]){var e=this.ids[b][d];if(this.isTypeOfDD(e)){var g=this.getLocation(e);if(g){this.locationCache[e.id]=g}else{delete this.locationCache[e.id]}}}}},verifyEl:function(c){if(c){var b;if(Ext.isIE){try{b=c.offsetParent}catch(d){}}else{b=c.offsetParent}if(b){return true}}return false},getLocation:function(j){if(!this.isTypeOfDD(j)){return null}var h=j.getEl(),o,g,d,q,p,s,c,n,i,m;try{o=Ext.lib.Dom.getXY(h)}catch(k){}if(!o){return null}g=o[0];d=g+h.offsetWidth;q=o[1];p=q+h.offsetHeight;s=q-j.padding[0];c=d+j.padding[1];n=p+j.padding[2];i=g-j.padding[3];return new Ext.lib.Region(s,c,n,i)},isOverTarget:function(k,b,d){var g=this.locationCache[b.id];if(!g||!this.useCache){g=this.getLocation(b);this.locationCache[b.id]=g}if(!g){return false}b.cursorIsOver=g.contains(k);var j=this.dragCurrent;if(!j||!j.getTargetCoord||(!d&&!j.constrainX&&!j.constrainY)){return b.cursorIsOver}b.overlap=null;var h=j.getTargetCoord(k.x,k.y);var c=j.getDragEl();var e=new Ext.lib.Region(h.y,h.x+c.offsetWidth,h.y+c.offsetHeight,h.x);var i=e.intersect(g);if(i){b.overlap=i;return(d)?true:b.cursorIsOver}else{return false}},_onUnload:function(c,b){a.removeListener(document,"mouseup",this.handleMouseUp,this);a.removeListener(document,"mousemove",this.handleMouseMove,this);a.removeListener(window,"resize",this._onResize,this);Ext.dd.DragDropMgr.unregAll()},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null}this._execOnAll("unreg",[]);for(var b in this.elementCache){delete this.elementCache[b]}this.elementCache={};this.ids={}},elementCache:{},getElWrapper:function(c){var b=this.elementCache[c];if(!b||!b.el){b=this.elementCache[c]=new this.ElementWrapper(Ext.getDom(c))}return b},getElement:function(b){return Ext.getDom(b)},getCss:function(c){var b=Ext.getDom(c);return(b)?b.style:null},ElementWrapper:function(b){this.el=b||null;this.id=this.el&&b.id;this.css=this.el&&b.style},getPosX:function(b){return Ext.lib.Dom.getX(b)},getPosY:function(b){return Ext.lib.Dom.getY(b)},swapNode:function(d,b){if(d.swapNode){d.swapNode(b)}else{var e=b.parentNode;var c=b.nextSibling;if(c==d){e.insertBefore(d,b)}else{if(b==d.nextSibling){e.insertBefore(b,d)}else{d.parentNode.replaceChild(b,d);e.insertBefore(d,c)}}}},getScroll:function(){var d,b,e=document.documentElement,c=document.body;if(e&&(e.scrollTop||e.scrollLeft)){d=e.scrollTop;b=e.scrollLeft}else{if(c){d=c.scrollTop;b=c.scrollLeft}else{}}return{top:d,left:b}},getStyle:function(c,b){return Ext.fly(c).getStyle(b)},getScrollTop:function(){return this.getScroll().top},getScrollLeft:function(){return this.getScroll().left},moveToEl:function(b,d){var c=Ext.lib.Dom.getXY(d);Ext.lib.Dom.setXY(b,c)},numericSort:function(d,c){return(d-c)},_timeoutCount:0,_addListeners:function(){var b=Ext.dd.DDM;if(Ext.lib.Event&&document){b._onLoad()}else{if(b._timeoutCount>2000){}else{setTimeout(b._addListeners,10);if(document&&document.body){b._timeoutCount+=1}}}},handleWasClicked:function(b,d){if(this.isHandle(d,b.id)){return true}else{var c=b.parentNode;while(c){if(this.isHandle(d,c.id)){return true}else{c=c.parentNode}}}return false}}}();Ext.dd.DDM=Ext.dd.DragDropMgr;Ext.dd.DDM._addListeners()}Ext.dd.DD=function(c,a,b){if(c){this.init(c,a,b)}};Ext.extend(Ext.dd.DD,Ext.dd.DragDrop,{scroll:true,autoOffset:function(c,b){var a=c-this.startPageX;var d=b-this.startPageY;this.setDelta(a,d)},setDelta:function(b,a){this.deltaX=b;this.deltaY=a},setDragElPos:function(c,b){var a=this.getDragEl();this.alignElWithMouse(a,c,b)},alignElWithMouse:function(c,h,g){var e=this.getTargetCoord(h,g);var b=c.dom?c:Ext.fly(c,"_dd");if(!this.deltaSetXY){var i=[e.x,e.y];b.setXY(i);var d=b.getLeft(true);var a=b.getTop(true);this.deltaSetXY=[d-e.x,a-e.y]}else{b.setLeftTop(e.x+this.deltaSetXY[0],e.y+this.deltaSetXY[1])}this.cachePosition(e.x,e.y);this.autoScroll(e.x,e.y,c.offsetHeight,c.offsetWidth);return e},cachePosition:function(b,a){if(b){this.lastPageX=b;this.lastPageY=a}else{var c=Ext.lib.Dom.getXY(this.getEl());this.lastPageX=c[0];this.lastPageY=c[1]}},autoScroll:function(l,k,e,m){if(this.scroll){var n=Ext.lib.Dom.getViewHeight();var b=Ext.lib.Dom.getViewWidth();var p=this.DDM.getScrollTop();var d=this.DDM.getScrollLeft();var j=e+k;var o=m+l;var i=(n+p-k-this.deltaY);var g=(b+d-l-this.deltaX);var c=40;var a=(document.all)?80:30;if(j>n&&i<c){window.scrollTo(d,p+a)}if(k<p&&p>0&&k-p<c){window.scrollTo(d,p-a)}if(o>b&&g<c){window.scrollTo(d+a,p)}if(l<d&&d>0&&l-d<c){window.scrollTo(d-a,p)}}},getTargetCoord:function(c,b){var a=c-this.deltaX;var d=b-this.deltaY;if(this.constrainX){if(a<this.minX){a=this.minX}if(a>this.maxX){a=this.maxX}}if(this.constrainY){if(d<this.minY){d=this.minY}if(d>this.maxY){d=this.maxY}}a=this.getTick(a,this.xTicks);d=this.getTick(d,this.yTicks);return{x:a,y:d}},applyConfig:function(){Ext.dd.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false)},b4MouseDown:function(a){this.autoOffset(a.getPageX(),a.getPageY())},b4Drag:function(a){this.setDragElPos(a.getPageX(),a.getPageY())},toString:function(){return("DD "+this.id)}});Ext.dd.DDProxy=function(c,a,b){if(c){this.init(c,a,b);this.initFrame()}};Ext.dd.DDProxy.dragElId="ygddfdiv";Ext.extend(Ext.dd.DDProxy,Ext.dd.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var b=this;var a=document.body;if(!a||!a.firstChild){setTimeout(function(){b.createFrame()},50);return}var d=this.getDragEl();if(!d){d=document.createElement("div");d.id=this.dragElId;var c=d.style;c.position="absolute";c.visibility="hidden";c.cursor="move";c.border="2px solid #aaa";c.zIndex=999;a.insertBefore(d,a.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(e,d){var c=this.getEl();var a=this.getDragEl();var b=a.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(b.width,10)/2),Math.round(parseInt(b.height,10)/2))}this.setDragElPos(e,d);Ext.fly(a).show()},_resizeProxy:function(){if(this.resizeFrame){var a=this.getEl();Ext.fly(this.getDragEl()).setSize(a.offsetWidth,a.offsetHeight)}},b4MouseDown:function(b){var a=b.getPageX();var c=b.getPageY();this.autoOffset(a,c);this.setDragElPos(a,c)},b4StartDrag:function(a,b){this.showFrame(a,b)},b4EndDrag:function(a){Ext.fly(this.getDragEl()).hide()},endDrag:function(c){var b=this.getEl();var a=this.getDragEl();a.style.visibility="";this.beforeMove();b.style.visibility="hidden";Ext.dd.DDM.moveToEl(b,a);a.style.visibility="hidden";b.style.visibility="";this.afterDrag()},beforeMove:function(){},afterDrag:function(){},toString:function(){return("DDProxy "+this.id)}});Ext.dd.DDTarget=function(c,a,b){if(c){this.initTarget(c,a,b)}};Ext.extend(Ext.dd.DDTarget,Ext.dd.DragDrop,{getDragEl:Ext.emptyFn,isValidHandleChild:Ext.emptyFn,startDrag:Ext.emptyFn,endDrag:Ext.emptyFn,onDrag:Ext.emptyFn,onDragDrop:Ext.emptyFn,onDragEnter:Ext.emptyFn,onDragOut:Ext.emptyFn,onDragOver:Ext.emptyFn,onInvalidDrop:Ext.emptyFn,onMouseDown:Ext.emptyFn,onMouseUp:Ext.emptyFn,setXConstraint:Ext.emptyFn,setYConstraint:Ext.emptyFn,resetConstraints:Ext.emptyFn,clearConstraints:Ext.emptyFn,clearTicks:Ext.emptyFn,setInitPosition:Ext.emptyFn,setDragElId:Ext.emptyFn,setHandleElId:Ext.emptyFn,setOuterHandleElId:Ext.emptyFn,addInvalidHandleClass:Ext.emptyFn,addInvalidHandleId:Ext.emptyFn,addInvalidHandleType:Ext.emptyFn,removeInvalidHandleClass:Ext.emptyFn,removeInvalidHandleId:Ext.emptyFn,removeInvalidHandleType:Ext.emptyFn,toString:function(){return("DDTarget "+this.id)}});Ext.dd.DragTracker=Ext.extend(Ext.util.Observable,{active:false,tolerance:5,autoStart:false,constructor:function(a){Ext.apply(this,a);this.addEvents("mousedown","mouseup","mousemove","dragstart","dragend","drag");this.dragRegion=new Ext.lib.Region(0,0,0,0);if(this.el){this.initEl(this.el)}Ext.dd.DragTracker.superclass.constructor.call(this,a)},initEl:function(a){this.el=Ext.get(a);a.on("mousedown",this.onMouseDown,this,this.delegate?{delegate:this.delegate}:undefined)},destroy:function(){this.el.un("mousedown",this.onMouseDown,this);delete this.el},onMouseDown:function(b,a){if(this.fireEvent("mousedown",this,b)!==false&&this.onBeforeStart(b)!==false){this.startXY=this.lastXY=b.getXY();this.dragTarget=this.delegate?a:this.el.dom;if(this.preventDefault!==false){b.preventDefault()}Ext.getDoc().on({scope:this,mouseup:this.onMouseUp,mousemove:this.onMouseMove,selectstart:this.stopSelect});if(this.autoStart){this.timer=this.triggerStart.defer(this.autoStart===true?1000:this.autoStart,this,[b])}}},onMouseMove:function(g,d){var b=Ext.isIE6||Ext.isIE7||Ext.isIE8;if(this.active&&b&&!g.browserEvent.button){g.preventDefault();this.onMouseUp(g);return}g.preventDefault();var c=g.getXY(),a=this.startXY;this.lastXY=c;if(!this.active){if(Math.abs(a[0]-c[0])>this.tolerance||Math.abs(a[1]-c[1])>this.tolerance){this.triggerStart(g)}else{return}}this.fireEvent("mousemove",this,g);this.onDrag(g);this.fireEvent("drag",this,g)},onMouseUp:function(c){var b=Ext.getDoc(),a=this.active;b.un("mousemove",this.onMouseMove,this);b.un("mouseup",this.onMouseUp,this);b.un("selectstart",this.stopSelect,this);c.preventDefault();this.clearStart();this.active=false;delete this.elRegion;this.fireEvent("mouseup",this,c);if(a){this.onEnd(c);this.fireEvent("dragend",this,c)}},triggerStart:function(a){this.clearStart();this.active=true;this.onStart(a);this.fireEvent("dragstart",this,a)},clearStart:function(){if(this.timer){clearTimeout(this.timer);delete this.timer}},stopSelect:function(a){a.stopEvent();return false},onBeforeStart:function(a){},onStart:function(a){},onDrag:function(a){},onEnd:function(a){},getDragTarget:function(){return this.dragTarget},getDragCt:function(){return this.el},getXY:function(a){return a?this.constrainModes[a].call(this,this.lastXY):this.lastXY},getOffset:function(c){var b=this.getXY(c),a=this.startXY;return[a[0]-b[0],a[1]-b[1]]},constrainModes:{point:function(b){if(!this.elRegion){this.elRegion=this.getDragCt().getRegion()}var a=this.dragRegion;a.left=b[0];a.top=b[1];a.right=b[0];a.bottom=b[1];a.constrainTo(this.elRegion);return[a.left,a.top]}}});Ext.dd.ScrollManager=function(){var c=Ext.dd.DragDropMgr;var e={};var b=null;var i={};var h=function(l){b=null;a()};var j=function(){if(c.dragCurrent){c.refreshCache(c.dragCurrent.groups)}};var d=function(){if(c.dragCurrent){var l=Ext.dd.ScrollManager;var m=i.el.ddScrollConfig?i.el.ddScrollConfig.increment:l.increment;if(!l.animate){if(i.el.scroll(i.dir,m)){j()}}else{i.el.scroll(i.dir,m,true,l.animDuration,j)}}};var a=function(){if(i.id){clearInterval(i.id)}i.id=0;i.el=null;i.dir=""};var g=function(m,l){a();i.el=m;i.dir=l;var o=m.ddScrollConfig?m.ddScrollConfig.ddGroup:undefined,n=(m.ddScrollConfig&&m.ddScrollConfig.frequency)?m.ddScrollConfig.frequency:Ext.dd.ScrollManager.frequency;if(o===undefined||c.dragCurrent.ddGroup==o){i.id=setInterval(d,n)}};var k=function(o,q){if(q||!c.dragCurrent){return}var s=Ext.dd.ScrollManager;if(!b||b!=c.dragCurrent){b=c.dragCurrent;s.refreshCache()}var t=Ext.lib.Event.getXY(o);var u=new Ext.lib.Point(t[0],t[1]);for(var m in e){var n=e[m],l=n._region;var p=n.ddScrollConfig?n.ddScrollConfig:s;if(l&&l.contains(u)&&n.isScrollable()){if(l.bottom-u.y<=p.vthresh){if(i.el!=n){g(n,"down")}return}else{if(l.right-u.x<=p.hthresh){if(i.el!=n){g(n,"left")}return}else{if(u.y-l.top<=p.vthresh){if(i.el!=n){g(n,"up")}return}else{if(u.x-l.left<=p.hthresh){if(i.el!=n){g(n,"right")}return}}}}}}a()};c.fireEvents=c.fireEvents.createSequence(k,c);c.stopDrag=c.stopDrag.createSequence(h,c);return{register:function(n){if(Ext.isArray(n)){for(var m=0,l=n.length;m<l;m++){this.register(n[m])}}else{n=Ext.get(n);e[n.id]=n}},unregister:function(n){if(Ext.isArray(n)){for(var m=0,l=n.length;m<l;m++){this.unregister(n[m])}}else{n=Ext.get(n);delete e[n.id]}},vthresh:25,hthresh:25,increment:100,frequency:500,animate:true,animDuration:0.4,ddGroup:undefined,refreshCache:function(){for(var l in e){if(typeof e[l]=="object"){e[l]._region=e[l].getRegion()}}}}}();Ext.dd.Registry=function(){var d={};var b={};var a=0;var c=function(g,e){if(typeof g=="string"){return g}var h=g.id;if(!h&&e!==false){h="extdd-"+(++a);g.id=h}return h};return{register:function(j,k){k=k||{};if(typeof j=="string"){j=document.getElementById(j)}k.ddel=j;d[c(j)]=k;if(k.isHandle!==false){b[k.ddel.id]=k}if(k.handles){var h=k.handles;for(var g=0,e=h.length;g<e;g++){b[c(h[g])]=k}}},unregister:function(j){var l=c(j,false);var k=d[l];if(k){delete d[l];if(k.handles){var h=k.handles;for(var g=0,e=h.length;g<e;g++){delete b[c(h[g],false)]}}}},getHandle:function(e){if(typeof e!="string"){e=e.id}return b[e]},getHandleFromEvent:function(h){var g=Ext.lib.Event.getTarget(h);return g?b[g.id]:null},getTarget:function(e){if(typeof e!="string"){e=e.id}return d[e]},getTargetFromEvent:function(h){var g=Ext.lib.Event.getTarget(h);return g?d[g.id]||b[g.id]:null}}}();Ext.dd.StatusProxy=function(a){Ext.apply(this,a);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:!a||a.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(a){a=a||this.dropNotAllowed;if(this.dropStatus!=a){this.el.replaceClass(this.dropStatus,a);this.dropStatus=a}},reset:function(a){this.el.dom.className="x-dd-drag-proxy "+this.dropNotAllowed;this.dropStatus=this.dropNotAllowed;if(a){this.ghost.update("")}},update:function(a){if(typeof a=="string"){this.ghost.update(a)}else{this.ghost.update("");a.style.margin="0";this.ghost.dom.appendChild(a)}var b=this.ghost.dom.firstChild;if(b){Ext.fly(b).setStyle("float","none")}},getEl:function(){return this.el},getGhost:function(){return this.ghost},hide:function(a){this.el.hide();if(a){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(b,c,a){this.callback=c;this.scope=a;if(b&&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:b,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},destroy:function(){Ext.destroy(this.ghost,this.el)}};Ext.dd.DragSource=function(b,a){this.el=Ext.get(b);if(!this.dragData){this.dragData={}}Ext.apply(this,a);if(!this.proxy){this.proxy=new Ext.dd.StatusProxy()}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(a){return this.dragData},onDragEnter:function(c,d){var b=Ext.dd.DragDropMgr.getDDById(d);this.cachedTarget=b;if(this.beforeDragEnter(b,c,d)!==false){if(b.isNotifyTarget){var a=b.notifyEnter(this,c,this.dragData);this.proxy.setStatus(a)}else{this.proxy.setStatus(this.dropAllowed)}if(this.afterDragEnter){this.afterDragEnter(b,c,d)}}},beforeDragEnter:function(b,a,c){return true},alignElWithMouse:function(){Ext.dd.DragSource.superclass.alignElWithMouse.apply(this,arguments);this.proxy.sync()},onDragOver:function(c,d){var b=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(d);if(this.beforeDragOver(b,c,d)!==false){if(b.isNotifyTarget){var a=b.notifyOver(this,c,this.dragData);this.proxy.setStatus(a)}if(this.afterDragOver){this.afterDragOver(b,c,d)}}},beforeDragOver:function(b,a,c){return true},onDragOut:function(b,c){var a=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(c);if(this.beforeDragOut(a,b,c)!==false){if(a.isNotifyTarget){a.notifyOut(this,b,this.dragData)}this.proxy.reset();if(this.afterDragOut){this.afterDragOut(a,b,c)}}this.cachedTarget=null},beforeDragOut:function(b,a,c){return true},onDragDrop:function(b,c){var a=this.cachedTarget||Ext.dd.DragDropMgr.getDDById(c);if(this.beforeDragDrop(a,b,c)!==false){if(a.isNotifyTarget){if(a.notifyDrop(this,b,this.dragData)){this.onValidDrop(a,b,c)}else{this.onInvalidDrop(a,b,c)}}else{this.onValidDrop(a,b,c)}if(this.afterDragDrop){this.afterDragDrop(a,b,c)}}delete this.cachedTarget},beforeDragDrop:function(b,a,c){return true},onValidDrop:function(b,a,c){this.hideProxy();if(this.afterValidDrop){this.afterValidDrop(b,a,c)}},getRepairXY:function(b,a){return this.el.getXY()},onInvalidDrop:function(b,a,c){this.beforeInvalidDrop(b,a,c);if(this.cachedTarget){if(this.cachedTarget.isNotifyTarget){this.cachedTarget.notifyOut(this,a,this.dragData)}this.cacheTarget=null}this.proxy.repair(this.getRepairXY(a,this.dragData),this.afterRepair,this);if(this.afterInvalidDrop){this.afterInvalidDrop(a,c)}},afterRepair:function(){if(Ext.enableFx){this.el.highlight(this.hlColor||"c3daf9")}this.dragging=false},beforeInvalidDrop:function(b,a,c){return true},handleMouseDown:function(b){if(this.dragging){return}var a=this.getDragData(b);if(a&&this.onBeforeDrag(a,b)!==false){this.dragData=a;this.proxy.stop();Ext.dd.DragSource.superclass.handleMouseDown.apply(this,arguments)}},onBeforeDrag:function(a,b){return true},onStartDrag:Ext.emptyFn,startDrag:function(a,b){this.proxy.reset();this.dragging=true;this.proxy.update("");this.onInitDrag(a,b);this.proxy.show()},onInitDrag:function(a,c){var b=this.el.dom.cloneNode(true);b.id=Ext.id();this.proxy.update(b);this.onStartDrag(a,c);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(a){},endDrag:function(a){this.onEndDrag(this.dragData,a)},onEndDrag:function(a,b){},autoOffset:function(a,b){this.setDelta(-12,-20)},destroy:function(){Ext.dd.DragSource.superclass.destroy.call(this);Ext.destroy(this.proxy)}});Ext.dd.DropTarget=Ext.extend(Ext.dd.DDTarget,{constructor:function(b,a){this.el=Ext.get(b);Ext.apply(this,a);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})},dropAllowed:"x-dd-drop-ok",dropNotAllowed:"x-dd-drop-nodrop",isTarget:true,isNotifyTarget:true,notifyEnter:function(a,c,b){if(this.overClass){this.el.addClass(this.overClass)}return this.dropAllowed},notifyOver:function(a,c,b){return this.dropAllowed},notifyOut:function(a,c,b){if(this.overClass){this.el.removeClass(this.overClass)}},notifyDrop:function(a,c,b){return false},destroy:function(){Ext.dd.DropTarget.superclass.destroy.call(this);if(this.containerScroll){Ext.dd.ScrollManager.unregister(this.el)}}});Ext.dd.DragZone=Ext.extend(Ext.dd.DragSource,{constructor:function(b,a){Ext.dd.DragZone.superclass.constructor.call(this,b,a);if(this.containerScroll){Ext.dd.ScrollManager.register(this.el)}},getDragData:function(a){return Ext.dd.Registry.getHandleFromEvent(a)},onInitDrag:function(a,b){this.proxy.update(this.dragData.ddel.cloneNode(true));this.onStartDrag(a,b);return true},afterRepair:function(){if(Ext.enableFx){Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor||"c3daf9")}this.dragging=false},getRepairXY:function(a){return Ext.Element.fly(this.dragData.ddel).getXY()},destroy:function(){Ext.dd.DragZone.superclass.destroy.call(this);if(this.containerScroll){Ext.dd.ScrollManager.unregister(this.el)}}});Ext.dd.DropZone=function(b,a){Ext.dd.DropZone.superclass.constructor.call(this,b,a)};Ext.extend(Ext.dd.DropZone,Ext.dd.DropTarget,{getTargetFromEvent:function(a){return Ext.dd.Registry.getTargetFromEvent(a)},onNodeEnter:function(d,a,c,b){},onNodeOver:function(d,a,c,b){return this.dropAllowed},onNodeOut:function(d,a,c,b){},onNodeDrop:function(d,a,c,b){return false},onContainerOver:function(a,c,b){return this.dropNotAllowed},onContainerDrop:function(a,c,b){return false},notifyEnter:function(a,c,b){return this.dropNotAllowed},notifyOver:function(a,c,b){var d=this.getTargetFromEvent(c);if(!d){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,a,c,b);this.lastOverNode=null}return this.onContainerOver(a,c,b)}if(this.lastOverNode!=d){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,a,c,b)}this.onNodeEnter(d,a,c,b);this.lastOverNode=d}return this.onNodeOver(d,a,c,b)},notifyOut:function(a,c,b){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,a,c,b);this.lastOverNode=null}},notifyDrop:function(a,c,b){if(this.lastOverNode){this.onNodeOut(this.lastOverNode,a,c,b);this.lastOverNode=null}var d=this.getTargetFromEvent(c);return d?this.onNodeDrop(d,a,c,b):this.onContainerDrop(a,c,b)},triggerCacheRefresh:function(){Ext.dd.DDM.refreshCache(this.groups)}});Ext.Element.addMethods({initDD:function(c,b,d){var a=new Ext.dd.DD(Ext.id(this.dom),c,b);return Ext.apply(a,d)},initDDProxy:function(c,b,d){var a=new Ext.dd.DDProxy(Ext.id(this.dom),c,b);return Ext.apply(a,d)},initDDTarget:function(c,b,d){var a=new Ext.dd.DDTarget(Ext.id(this.dom),c,b);return Ext.apply(a,d)}});Ext.data.Api=(function(){var a={};return{actions:{create:"create",read:"read",update:"update",destroy:"destroy"},restActions:{create:"POST",read:"GET",update:"PUT",destroy:"DELETE"},isAction:function(b){return(Ext.data.Api.actions[b])?true:false},getVerb:function(b){if(a[b]){return a[b]}for(var c in this.actions){if(this.actions[c]===b){a[b]=c;break}}return(a[b]!==undefined)?a[b]:null},isValid:function(b){var e=[];var d=this.actions;for(var c in b){if(!(c in d)){e.push(c)}}return(!e.length)?true:e},hasUniqueUrl:function(c,g){var b=(c.api[g])?c.api[g].url:null;var e=true;for(var d in c.api){if((e=(d===g)?true:(c.api[d].url!=b)?true:false)===false){break}}return e},prepare:function(b){if(!b.api){b.api={}}for(var d in this.actions){var c=this.actions[d];b.api[c]=b.api[c]||b.url||b.directFn;if(typeof(b.api[c])=="string"){b.api[c]={url:b.api[c],method:(b.restful===true)?Ext.data.Api.restActions[c]:undefined}}}},restify:function(b){b.restful=true;for(var c in this.restActions){b.api[this.actions[c]].method||(b.api[this.actions[c]].method=this.restActions[c])}b.onWrite=b.onWrite.createInterceptor(function(i,j,g,e){var d=j.reader;var h=new Ext.data.Response({action:i,raw:g});switch(g.status){case 200:return true;break;case 201:if(Ext.isEmpty(h.raw.responseText)){h.success=true}else{return true}break;case 204:h.success=true;h.data=null;break;default:return true;break}if(h.success===true){this.fireEvent("write",this,i,h.data,h,e,j.request.arg)}else{this.fireEvent("exception",this,"remote",i,j,h,e)}j.request.callback.call(j.request.scope,h.data,h,h.success);return false},b)}}})();Ext.data.Response=function(b,a){Ext.apply(this,b,{raw:a})};Ext.data.Response.prototype={message:null,success:false,status:null,root:null,raw:null,getMessage:function(){return this.message},getSuccess:function(){return this.success},getStatus:function(){return this.status},getRoot:function(){return this.root},getRawResponse:function(){return this.raw}};Ext.data.Api.Error=Ext.extend(Ext.Error,{constructor:function(b,a){this.arg=a;Ext.Error.call(this,b)},name:"Ext.data.Api"});Ext.apply(Ext.data.Api.Error.prototype,{lang:{"action-url-undefined":"No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.",invalid:"received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions","invalid-url":"Invalid url. Please review your proxy configuration.",execute:'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'}});Ext.data.SortTypes={none:function(a){return a},stripTagsRE:/<\/?[^>]+>/gi,asText:function(a){return String(a).replace(this.stripTagsRE,"")},asUCText:function(a){return String(a).toUpperCase().replace(this.stripTagsRE,"")},asUCString:function(a){return String(a).toUpperCase()},asDate:function(a){if(!a){return 0}if(Ext.isDate(a)){return a.getTime()}return Date.parse(String(a))},asFloat:function(a){var b=parseFloat(String(a).replace(/,/g,""));return isNaN(b)?0:b},asInt:function(a){var b=parseInt(String(a).replace(/,/g,""),10);return isNaN(b)?0:b}};Ext.data.Record=function(a,b){this.id=(b||b===0)?b:Ext.data.Record.id(this);this.data=a||{}};Ext.data.Record.create=function(e){var c=Ext.extend(Ext.data.Record,{});var d=c.prototype;d.fields=new Ext.util.MixedCollection(false,function(g){return g.name});for(var b=0,a=e.length;b<a;b++){d.fields.add(new Ext.data.Field(e[b]))}c.getField=function(g){return d.fields.get(g)};return c};Ext.data.Record.PREFIX="ext-record";Ext.data.Record.AUTO_ID=1;Ext.data.Record.EDIT="edit";Ext.data.Record.REJECT="reject";Ext.data.Record.COMMIT="commit";Ext.data.Record.id=function(a){a.phantom=true;return[Ext.data.Record.PREFIX,"-",Ext.data.Record.AUTO_ID++].join("")};Ext.data.Record.prototype={dirty:false,editing:false,error:null,modified:null,phantom:false,join:function(a){this.store=a},set:function(a,c){var b=Ext.isPrimitive(c)?String:Ext.encode;if(b(this.data[a])==b(c)){return}this.dirty=true;if(!this.modified){this.modified={}}if(this.modified[a]===undefined){this.modified[a]=this.data[a]}this.data[a]=c;if(!this.editing){this.afterEdit()}},afterEdit:function(){if(this.store!=undefined&&typeof this.store.afterEdit=="function"){this.store.afterEdit(this)}},afterReject:function(){if(this.store){this.store.afterReject(this)}},afterCommit:function(){if(this.store){this.store.afterCommit(this)}},get:function(a){return this.data[a]},beginEdit:function(){this.editing=true;this.modified=this.modified||{}},cancelEdit:function(){this.editing=false;delete this.modified},endEdit:function(){this.editing=false;if(this.dirty){this.afterEdit()}},reject:function(b){var a=this.modified;for(var c in a){if(typeof a[c]!="function"){this.data[c]=a[c]}}this.dirty=false;delete this.modified;this.editing=false;if(b!==true){this.afterReject()}},commit:function(a){this.dirty=false;delete this.modified;this.editing=false;if(a!==true){this.afterCommit()}},getChanges:function(){var a=this.modified,b={};for(var c in a){if(a.hasOwnProperty(c)){b[c]=this.data[c]}}return b},hasError:function(){return this.error!==null},clearError:function(){this.error=null},copy:function(a){return new this.constructor(Ext.apply({},this.data),a||this.id)},isModified:function(a){return !!(this.modified&&this.modified.hasOwnProperty(a))},isValid:function(){return this.fields.find(function(a){return(a.allowBlank===false&&Ext.isEmpty(this.data[a.name]))?true:false},this)?false:true},markDirty:function(){this.dirty=true;if(!this.modified){this.modified={}}this.fields.each(function(a){this.modified[a.name]=this.data[a.name]},this)}};Ext.StoreMgr=Ext.apply(new Ext.util.MixedCollection(),{register:function(){for(var a=0,b;(b=arguments[a]);a++){this.add(b)}},unregister:function(){for(var a=0,b;(b=arguments[a]);a++){this.remove(this.lookup(b))}},lookup:function(e){if(Ext.isArray(e)){var b=["field1"],d=!Ext.isArray(e[0]);if(!d){for(var c=2,a=e[0].length;c<=a;++c){b.push("field"+c)}}return new Ext.data.ArrayStore({fields:b,data:e,expandData:d,autoDestroy:true,autoCreated:true})}return Ext.isObject(e)?(e.events?e:Ext.create(e,"store")):this.get(e)},getKey:function(a){return a.storeId}});Ext.data.Store=Ext.extend(Ext.util.Observable,{writer:undefined,remoteSort:false,autoDestroy:false,pruneModifiedRecords:false,lastOptions:null,autoSave:true,batch:true,restful:false,paramNames:undefined,defaultParamNames:{start:"start",limit:"limit",sort:"sort",dir:"dir"},isDestroyed:false,hasMultiSort:false,batchKey:"_ext_batch_",constructor:function(a){this.data=new Ext.util.MixedCollection(false);this.data.getKey=function(b){return b.id};this.removed=[];if(a&&a.data){this.inlineData=a.data;delete a.data}Ext.apply(this,a);this.baseParams=Ext.isObject(this.baseParams)?this.baseParams:{};this.paramNames=Ext.applyIf(this.paramNames||{},this.defaultParamNames);if((this.url||this.api)&&!this.proxy){this.proxy=new Ext.data.HttpProxy({url:this.url,api:this.api})}if(this.restful===true&&this.proxy){this.batch=false;Ext.data.Api.restify(this.proxy)}if(this.reader){if(!this.recordType){this.recordType=this.reader.recordType}if(this.reader.onMetaChange){this.reader.onMetaChange=this.reader.onMetaChange.createSequence(this.onMetaChange,this)}if(this.writer){if(this.writer instanceof (Ext.data.DataWriter)===false){this.writer=this.buildWriter(this.writer)}this.writer.meta=this.reader.meta;this.pruneModifiedRecords=true}}if(this.recordType){this.fields=this.recordType.prototype.fields}this.modified=[];this.addEvents("datachanged","metachange","add","remove","update","clear","exception","beforeload","load","loadexception","beforewrite","write","beforesave","save");if(this.proxy){this.relayEvents(this.proxy,["loadexception","exception"])}if(this.writer){this.on({scope:this,add:this.createRecords,remove:this.destroyRecord,update:this.updateRecord,clear:this.onClear})}this.sortToggle={};if(this.sortField){this.setDefaultSort(this.sortField,this.sortDir)}else{if(this.sortInfo){this.setDefaultSort(this.sortInfo.field,this.sortInfo.direction)}}Ext.data.Store.superclass.constructor.call(this);if(this.id){this.storeId=this.id;delete this.id}if(this.storeId){Ext.StoreMgr.register(this)}if(this.inlineData){this.loadData(this.inlineData);delete this.inlineData}else{if(this.autoLoad){this.load.defer(10,this,[typeof this.autoLoad=="object"?this.autoLoad:undefined])}}this.batchCounter=0;this.batches={}},buildWriter:function(b){var a=undefined,c=(b.format||"json").toLowerCase();switch(c){case"json":a=Ext.data.JsonWriter;break;case"xml":a=Ext.data.XmlWriter;break;default:a=Ext.data.JsonWriter}return new a(b)},destroy:function(){if(!this.isDestroyed){if(this.storeId){Ext.StoreMgr.unregister(this)}this.clearData();this.data=null;Ext.destroy(this.proxy);this.reader=this.writer=null;this.purgeListeners();this.isDestroyed=true}},add:function(c){var e,a,b,d;c=[].concat(c);if(c.length<1){return}for(e=0,a=c.length;e<a;e++){b=c[e];b.join(this);if(b.dirty||b.phantom){this.modified.push(b)}}d=this.data.length;this.data.addAll(c);if(this.snapshot){this.snapshot.addAll(c)}this.fireEvent("add",this,c,d)},addSorted:function(a){var b=this.findInsertIndex(a);this.insert(b,a)},doUpdate:function(a){var b=a.id;this.getById(b).join(null);this.data.replace(b,a);if(this.snapshot){this.snapshot.replace(b,a)}a.join(this);this.fireEvent("update",this,a,Ext.data.Record.COMMIT)},remove:function(a){if(Ext.isArray(a)){Ext.each(a,function(c){this.remove(c)},this);return}var b=this.data.indexOf(a);if(b>-1){a.join(null);this.data.removeAt(b)}if(this.pruneModifiedRecords){this.modified.remove(a)}if(this.snapshot){this.snapshot.remove(a)}if(b>-1){this.fireEvent("remove",this,a,b)}},removeAt:function(a){this.remove(this.getAt(a))},removeAll:function(b){var a=[];this.each(function(c){a.push(c)});this.clearData();if(this.snapshot){this.snapshot.clear()}if(this.pruneModifiedRecords){this.modified=[]}if(b!==true){this.fireEvent("clear",this,a)}},onClear:function(b,a){Ext.each(a,function(d,c){this.destroyRecord(this,d,c)},this)},insert:function(d,c){var e,a,b;c=[].concat(c);for(e=0,a=c.length;e<a;e++){b=c[e];this.data.insert(d+e,b);b.join(this);if(b.dirty||b.phantom){this.modified.push(b)}}if(this.snapshot){this.snapshot.addAll(c)}this.fireEvent("add",this,c,d)},indexOf:function(a){return this.data.indexOf(a)},indexOfId:function(a){return this.data.indexOfKey(a)},getById:function(a){return(this.snapshot||this.data).key(a)},getAt:function(a){return this.data.itemAt(a)},getRange:function(b,a){return this.data.getRange(b,a)},storeOptions:function(a){a=Ext.apply({},a);delete a.callback;delete a.scope;this.lastOptions=a},clearData:function(){this.data.each(function(a){a.join(null)});this.data.clear()},load:function(b){b=Ext.apply({},b);this.storeOptions(b);if(this.sortInfo&&this.remoteSort){var a=this.paramNames;b.params=Ext.apply({},b.params);b.params[a.sort]=this.sortInfo.field;b.params[a.dir]=this.sortInfo.direction}try{return this.execute("read",null,b)}catch(c){this.handleException(c);return false}},updateRecord:function(b,a,c){if(c==Ext.data.Record.EDIT&&this.autoSave===true&&(!a.phantom||(a.phantom&&a.isValid()))){this.save()}},createRecords:function(c,b,e){var d=this.modified,h=b.length,a,g;for(g=0;g<h;g++){a=b[g];if(a.phantom&&a.isValid()){a.markDirty();if(d.indexOf(a)==-1){d.push(a)}}}if(this.autoSave===true){this.save()}},destroyRecord:function(b,a,c){if(this.modified.indexOf(a)!=-1){this.modified.remove(a)}if(!a.phantom){this.removed.push(a);a.lastIndex=c;if(this.autoSave===true){this.save()}}},execute:function(e,a,c,b){if(!Ext.data.Api.isAction(e)){throw new Ext.data.Api.Error("execute",e)}c=Ext.applyIf(c||{},{params:{}});if(b!==undefined){this.addToBatch(b)}var d=true;if(e==="read"){d=this.fireEvent("beforeload",this,c);Ext.applyIf(c.params,this.baseParams)}else{if(this.writer.listful===true&&this.restful!==true){a=(Ext.isArray(a))?a:[a]}else{if(Ext.isArray(a)&&a.length==1){a=a.shift()}}if((d=this.fireEvent("beforewrite",this,e,a,c))!==false){this.writer.apply(c.params,this.baseParams,e,a)}}if(d!==false){if(this.writer&&this.proxy.url&&!this.proxy.restful&&!Ext.data.Api.hasUniqueUrl(this.proxy,e)){c.params.xaction=e}this.proxy.request(Ext.data.Api.actions[e],a,c.params,this.reader,this.createCallback(e,a,b),this,c)}return d},save:function(){if(!this.writer){throw new Ext.data.Store.Error("writer-undefined")}var h=[],j,k,e,c={},d;if(this.removed.length){h.push(["destroy",this.removed])}var b=[].concat(this.getModifiedRecords());if(b.length){var g=[];for(d=b.length-1;d>=0;d--){if(b[d].phantom===true){var a=b.splice(d,1).shift();if(a.isValid()){g.push(a)}}else{if(!b[d].isValid()){b.splice(d,1)}}}if(g.length){h.push(["create",g])}if(b.length){h.push(["update",b])}}j=h.length;if(j){e=++this.batchCounter;for(d=0;d<j;++d){k=h[d];c[k[0]]=k[1]}if(this.fireEvent("beforesave",this,c)!==false){for(d=0;d<j;++d){k=h[d];this.doTransaction(k[0],k[1],e)}return e}}return -1},doTransaction:function(e,b,c){function g(h){try{this.execute(e,h,undefined,c)}catch(i){this.handleException(i)}}if(this.batch===false){for(var d=0,a=b.length;d<a;d++){g.call(this,b[d])}}else{g.call(this,b)}},addToBatch:function(c){var a=this.batches,d=this.batchKey+c,e=a[d];if(!e){a[d]=e={id:c,count:0,data:{}}}++e.count},removeFromBatch:function(d,h,g){var c=this.batches,e=this.batchKey+d,i=c[e],a;if(i){a=i.data[h]||[];i.data[h]=a.concat(g);if(i.count===1){g=i.data;delete c[e];this.fireEvent("save",this,d,g)}else{--i.count}}},createCallback:function(c,a,b){var d=Ext.data.Api.actions;return(c=="read")?this.loadRecords:function(g,e,h){this["on"+Ext.util.Format.capitalize(c)+"Records"](h,a,[].concat(g));if(h===true){this.fireEvent("write",this,c,g,e,a)}this.removeFromBatch(b,c,g)}},clearModified:function(a){if(Ext.isArray(a)){for(var b=a.length-1;b>=0;b--){this.modified.splice(this.modified.indexOf(a[b]),1)}}else{this.modified.splice(this.modified.indexOf(a),1)}},reMap:function(b){if(Ext.isArray(b)){for(var d=0,a=b.length;d<a;d++){this.reMap(b[d])}}else{delete this.data.map[b._phid];this.data.map[b.id]=b;var c=this.data.keys.indexOf(b._phid);this.data.keys.splice(c,1,b.id);delete b._phid}},onCreateRecords:function(d,a,b){if(d===true){try{this.reader.realize(a,b)}catch(c){this.handleException(c);if(Ext.isArray(a)){this.onCreateRecords(d,a,b)}}}},onUpdateRecords:function(d,a,b){if(d===true){try{this.reader.update(a,b)}catch(c){this.handleException(c);if(Ext.isArray(a)){this.onUpdateRecords(d,a,b)}}}},onDestroyRecords:function(e,b,d){b=(b instanceof Ext.data.Record)?[b]:[].concat(b);for(var c=0,a=b.length;c<a;c++){this.removed.splice(this.removed.indexOf(b[c]),1)}if(e===false){for(c=b.length-1;c>=0;c--){this.insert(b[c].lastIndex,b[c])}}},handleException:function(a){Ext.handleError(a)},reload:function(a){this.load(Ext.applyIf(a||{},this.lastOptions))},loadRecords:function(b,l,h){var e,g;if(this.isDestroyed===true){return}if(!b||h===false){if(h!==false){this.fireEvent("load",this,[],l)}if(l.callback){l.callback.call(l.scope||this,[],l,false,b)}return}var a=b.records,j=b.totalRecords||a.length;if(!l||l.add!==true){if(this.pruneModifiedRecords){this.modified=[]}for(e=0,g=a.length;e<g;e++){a[e].join(this)}if(this.snapshot){this.data=this.snapshot;delete this.snapshot}this.clearData();this.data.addAll(a);this.totalLength=j;this.applySort();this.fireEvent("datachanged",this)}else{var k=[],d,c=0;for(e=0,g=a.length;e<g;++e){d=a[e];if(this.indexOfId(d.id)>-1){this.doUpdate(d)}else{k.push(d);++c}}this.totalLength=Math.max(j,this.data.length+c);this.add(k)}this.fireEvent("load",this,a,l);if(l.callback){l.callback.call(l.scope||this,a,l,true)}},loadData:function(c,a){var b=this.reader.readRecords(c);this.loadRecords(b,{add:a},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.multiSortInfo)&&!this.remoteSort){this.sortData()}},sortData:function(){var a=this.hasMultiSort?this.multiSortInfo:this.sortInfo,k=a.direction||"ASC",h=a.sorters,c=[];if(!this.hasMultiSort){h=[{direction:k,field:a.field}]}for(var d=0,b=h.length;d<b;d++){c.push(this.createSortFunction(h[d].field,h[d].direction))}if(c.length==0){return}var g=k.toUpperCase()=="DESC"?-1:1;var e=function(n,m){var l=c[0].call(this,n,m);if(c.length>1){for(var p=1,o=c.length;p<o;p++){l=l||c[p].call(this,n,m)}}return g*l};this.data.sort(k,e);if(this.snapshot&&this.snapshot!=this.data){this.snapshot.sort(k,e)}},createSortFunction:function(c,b){b=b||"ASC";var a=b.toUpperCase()=="DESC"?-1:1;var d=this.fields.get(c).sortType;return function(g,e){var i=d(g.data[c]),h=d(e.data[c]);return a*(i>h?1:(i<h?-1:0))}},setDefaultSort:function(b,a){a=a?a.toUpperCase():"ASC";this.sortInfo={field:b,direction:a};this.sortToggle[b]=a},sort:function(b,a){if(Ext.isArray(arguments[0])){return this.multiSort.call(this,b,a)}else{return this.singleSort(b,a)}},singleSort:function(g,c){var e=this.fields.get(g);if(!e){return false}var b=e.name,a=this.sortInfo||null,d=this.sortToggle?this.sortToggle[b]:null;if(!c){if(a&&a.field==b){c=(this.sortToggle[b]||"ASC").toggle("ASC","DESC")}else{c=e.sortDir}}this.sortToggle[b]=c;this.sortInfo={field:b,direction:c};this.hasMultiSort=false;if(this.remoteSort){if(!this.load(this.lastOptions)){if(d){this.sortToggle[b]=d}if(a){this.sortInfo=a}}}else{this.applySort();this.fireEvent("datachanged",this)}return true},multiSort:function(b,a){this.hasMultiSort=true;a=a||"ASC";if(this.multiSortInfo&&a==this.multiSortInfo.direction){a=a.toggle("ASC","DESC")}this.multiSortInfo={sorters:b,direction:a};if(this.remoteSort){this.singleSort(b[0].field,b[0].direction)}else{this.applySort();this.fireEvent("datachanged",this)}},each:function(b,a){this.data.each(b,a)},getModifiedRecords:function(){return this.modified},sum:function(e,g,a){var c=this.data.items,b=0;g=g||0;a=(a||a===0)?a:c.length-1;for(var d=g;d<=a;d++){b+=(c[d].data[e]||0)}return b},createFilterFn:function(d,c,e,a,b){if(Ext.isEmpty(c,false)){return false}c=this.data.createValueMatcher(c,e,a,b);return function(g){return c.test(g.data[d])}},createMultipleFilterFn:function(a){return function(b){var k=true;for(var d=0,c=a.length;d<c;d++){var h=a[d],g=h.fn,e=h.scope;k=k&&g.call(e,b)}return k}},filter:function(n,m,h,k,e){var l;if(Ext.isObject(n)){n=[n]}if(Ext.isArray(n)){var b=[];for(var g=0,d=n.length;g<d;g++){var a=n[g],c=a.fn,o=a.scope||this;if(!Ext.isFunction(c)){c=this.createFilterFn(a.property,a.value,a.anyMatch,a.caseSensitive,a.exactMatch)}b.push({fn:c,scope:o})}l=this.createMultipleFilterFn(b)}else{l=this.createFilterFn(n,m,h,k,e)}return l?this.filterBy(l):this.clearFilter()},filterBy:function(b,a){this.snapshot=this.snapshot||this.data;this.data=this.queryBy(b,a||this);this.fireEvent("datachanged",this)},clearFilter:function(a){if(this.isFiltered()){this.data=this.snapshot;delete this.snapshot;if(a!==true){this.fireEvent("datachanged",this)}}},isFiltered:function(){return !!this.snapshot&&this.snapshot!=this.data},query:function(d,c,e,a){var b=this.createFilterFn(d,c,e,a);return b?this.queryBy(b):this.data.clone()},queryBy:function(b,a){var c=this.snapshot||this.data;return c.filterBy(b,a||this)},find:function(d,c,g,e,a){var b=this.createFilterFn(d,c,e,a);return b?this.data.findIndexBy(b,null,g):-1},findExact:function(b,a,c){return this.data.findIndexBy(function(d){return d.get(b)===a},this,c)},findBy:function(b,a,c){return this.data.findIndexBy(b,a,c)},collect:function(j,k,b){var h=(b===true&&this.snapshot)?this.snapshot.items:this.data.items;var m,n,a=[],c={};for(var e=0,g=h.length;e<g;e++){m=h[e].data[j];n=String(m);if((k||!Ext.isEmpty(m))&&!c[n]){c[n]=true;a[a.length]=m}}return a},afterEdit:function(a){if(this.modified.indexOf(a)==-1){this.modified.push(a)}this.fireEvent("update",this,a,Ext.data.Record.EDIT)},afterReject:function(a){this.modified.remove(a);this.fireEvent("update",this,a,Ext.data.Record.REJECT)},afterCommit:function(a){this.modified.remove(a);this.fireEvent("update",this,a,Ext.data.Record.COMMIT)},commitChanges:function(){var a=this.modified.slice(0),c=a.length,b;for(b=0;b<c;b++){a[b].commit()}this.modified=[];this.removed=[]},rejectChanges:function(){var a=this.modified.slice(0),e=this.removed.slice(0).reverse(),c=a.length,d=e.length,b;for(b=0;b<c;b++){a[b].reject()}for(b=0;b<d;b++){this.insert(e[b].lastIndex||0,e[b]);e[b].reject()}this.modified=[];this.removed=[]},onMetaChange:function(a){this.recordType=this.reader.recordType;this.fields=this.recordType.prototype.fields;delete this.snapshot;if(this.reader.meta.sortInfo){this.sortInfo=this.reader.meta.sortInfo}else{if(this.sortInfo&&!this.fields.get(this.sortInfo.field)){delete this.sortInfo}}if(this.writer){this.writer.meta=this.reader.meta}this.modified=[];this.fireEvent("metachange",this,this.reader.meta)},findInsertIndex:function(a){this.suspendEvents();var c=this.data.clone();this.data.add(a);this.applySort();var b=this.data.indexOf(a);this.data=c;this.resumeEvents();return b},setBaseParam:function(a,b){this.baseParams=this.baseParams||{};this.baseParams[a]=b}});Ext.reg("store",Ext.data.Store);Ext.data.Store.Error=Ext.extend(Ext.Error,{name:"Ext.data.Store"});Ext.apply(Ext.data.Store.Error.prototype,{lang:{"writer-undefined":"Attempted to execute a write-action without a DataWriter installed."}});Ext.data.Field=Ext.extend(Object,{constructor:function(b){if(Ext.isString(b)){b={name:b}}Ext.apply(this,b);var d=Ext.data.Types,a=this.sortType,c;if(this.type){if(Ext.isString(this.type)){this.type=Ext.data.Types[this.type.toUpperCase()]||d.AUTO}}else{this.type=d.AUTO}if(Ext.isString(a)){this.sortType=Ext.data.SortTypes[a]}else{if(Ext.isEmpty(a)){this.sortType=this.type.sortType}}if(!this.convert){this.convert=this.type.convert}},dateFormat:null,useNull:false,defaultValue:"",mapping:null,sortType:null,sortDir:"ASC",allowBlank:true});Ext.data.DataReader=function(a,b){this.meta=a;this.recordType=Ext.isArray(b)?Ext.data.Record.create(b):b;if(this.recordType){this.buildExtractors()}};Ext.data.DataReader.prototype={getTotal:Ext.emptyFn,getRoot:Ext.emptyFn,getMessage:Ext.emptyFn,getSuccess:Ext.emptyFn,getId:Ext.emptyFn,buildExtractors:Ext.emptyFn,extractValues:Ext.emptyFn,realize:function(a,c){if(Ext.isArray(a)){for(var b=a.length-1;b>=0;b--){if(Ext.isArray(c)){this.realize(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.realize(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(!this.isData(c)){throw new Ext.data.DataReader.Error("realize",a)}a.phantom=false;a._phid=a.id;a.id=this.getId(c);a.data=c;a.commit();a.store.reMap(a)}},update:function(a,c){if(Ext.isArray(a)){for(var b=a.length-1;b>=0;b--){if(Ext.isArray(c)){this.update(a.splice(b,1).shift(),c.splice(b,1).shift())}else{this.update(a.splice(b,1).shift(),c)}}}else{if(Ext.isArray(c)&&c.length==1){c=c.shift()}if(this.isData(c)){a.data=Ext.apply(a.data,c)}a.commit()}},extractData:function(k,a){var j=(this instanceof Ext.data.JsonReader)?"json":"node";var c=[];if(this.isData(k)&&!(this instanceof Ext.data.XmlReader)){k=[k]}var h=this.recordType.prototype.fields,o=h.items,m=h.length,c=[];if(a===true){var l=this.recordType;for(var e=0;e<k.length;e++){var b=k[e];var g=new l(this.extractValues(b,o,m),this.getId(b));g[j]=b;c.push(g)}}else{for(var e=0;e<k.length;e++){var d=this.extractValues(k[e],o,m);d[this.meta.idProperty]=this.getId(k[e]);c.push(d)}}return c},isData:function(a){return(a&&Ext.isObject(a)&&!Ext.isEmpty(this.getId(a)))?true:false},onMetaChange:function(a){delete this.ef;this.meta=a;this.recordType=Ext.data.Record.create(a.fields);this.buildExtractors()}};Ext.data.DataReader.Error=Ext.extend(Ext.Error,{constructor:function(b,a){this.arg=a;Ext.Error.call(this,b)},name:"Ext.data.DataReader"});Ext.apply(Ext.data.DataReader.Error.prototype,{lang:{update:"#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",realize:"#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.","invalid-response":"#readResponse received an invalid response from the server."}});Ext.data.DataWriter=function(a){Ext.apply(this,a)};Ext.data.DataWriter.prototype={writeAllFields:false,listful:false,apply:function(e,g,d,a){var c=[],b=d+"Record";if(Ext.isArray(a)){Ext.each(a,function(h){c.push(this[b](h))},this)}else{if(a instanceof Ext.data.Record){c=this[b](a)}}this.render(e,g,c)},render:Ext.emptyFn,updateRecord:Ext.emptyFn,createRecord:Ext.emptyFn,destroyRecord:Ext.emptyFn,toHash:function(g,c){var e=g.fields.map,d={},b=(this.writeAllFields===false&&g.phantom===false)?g.getChanges():g.data,a;Ext.iterate(b,function(i,h){if((a=e[i])){d[a.mapping?a.mapping:a.name]=h}});if(g.phantom){if(g.fields.containsKey(this.meta.idProperty)&&Ext.isEmpty(g.data[this.meta.idProperty])){delete d[this.meta.idProperty]}}else{d[this.meta.idProperty]=g.id}return d},toArray:function(b){var a=[];Ext.iterate(b,function(d,c){a.push({name:d,value:c})},this);return a}};Ext.data.DataProxy=function(a){a=a||{};this.api=a.api;this.url=a.url;this.restful=a.restful;this.listeners=a.listeners;this.prettyUrls=a.prettyUrls;this.addEvents("exception","beforeload","load","loadexception","beforewrite","write");Ext.data.DataProxy.superclass.constructor.call(this);try{Ext.data.Api.prepare(this)}catch(b){if(b instanceof Ext.data.Api.Error){b.toConsole()}}Ext.data.DataProxy.relayEvents(this,["beforewrite","write","exception"])};Ext.extend(Ext.data.DataProxy,Ext.util.Observable,{restful:false,setApi:function(){if(arguments.length==1){var a=Ext.data.Api.isValid(arguments[0]);if(a===true){this.api=arguments[0]}else{throw new Ext.data.Api.Error("invalid",a)}}else{if(arguments.length==2){if(!Ext.data.Api.isAction(arguments[0])){throw new Ext.data.Api.Error("invalid",arguments[0])}this.api[arguments[0]]=arguments[1]}}Ext.data.Api.prepare(this)},isApiAction:function(a){return(this.api[a])?true:false},request:function(e,b,g,a,h,d,c){if(!this.api[e]&&!this.load){throw new Ext.data.DataProxy.Error("action-undefined",e)}g=g||{};if((e===Ext.data.Api.actions.read)?this.fireEvent("beforeload",this,g):this.fireEvent("beforewrite",this,e,b,g)!==false){this.doRequest.apply(this,arguments)}else{h.call(d||this,null,c,false)}},load:null,doRequest:function(e,b,g,a,h,d,c){this.load(g,a,h,d,c)},onRead:Ext.emptyFn,onWrite:Ext.emptyFn,buildUrl:function(d,b){b=b||null;var c=(this.conn&&this.conn.url)?this.conn.url:(this.api[d])?this.api[d].url:this.url;if(!c){throw new Ext.data.Api.Error("invalid-url",d)}var e=null;var a=c.match(/(.*)(\.json|\.xml|\.html)$/);if(a){e=a[2];c=a[1]}if((this.restful===true||this.prettyUrls===true)&&b instanceof Ext.data.Record&&!b.phantom){c+="/"+b.id}return(e===null)?c:c+e},destroy:function(){this.purgeListeners()}});Ext.apply(Ext.data.DataProxy,Ext.util.Observable.prototype);Ext.util.Observable.call(Ext.data.DataProxy);Ext.data.DataProxy.Error=Ext.extend(Ext.Error,{constructor:function(b,a){this.arg=a;Ext.Error.call(this,b)},name:"Ext.data.DataProxy"});Ext.apply(Ext.data.DataProxy.Error.prototype,{lang:{"action-undefined":"DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.","api-invalid":"Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions."}});Ext.data.Request=function(a){Ext.apply(this,a)};Ext.data.Request.prototype={action:undefined,rs:undefined,params:undefined,callback:Ext.emptyFn,scope:undefined,reader:undefined};Ext.data.Response=function(a){Ext.apply(this,a)};Ext.data.Response.prototype={action:undefined,success:undefined,message:undefined,data:undefined,raw:undefined,records:undefined};Ext.data.ScriptTagProxy=function(a){Ext.apply(this,a);Ext.data.ScriptTagProxy.superclass.constructor.call(this,a);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,doRequest:function(e,g,d,h,j,k,l){var c=Ext.urlEncode(Ext.apply(d,this.extraParams));var b=this.buildUrl(e,g);if(!b){throw new Ext.data.Api.Error("invalid-url",b)}b=Ext.urlAppend(b,c);if(this.nocache){b=Ext.urlAppend(b,"_dc="+(new Date().getTime()))}var a=++Ext.data.ScriptTagProxy.TRANS_ID;var m={id:a,action:e,cb:"stcCallback"+a,scriptId:"stcScript"+a,params:d,arg:l,url:b,callback:j,scope:k,reader:h};window[m.cb]=this.createCallback(e,g,m);b+=String.format("&{0}={1}",this.callbackParam,m.cb);if(this.autoAbort!==false){this.abort()}m.timeoutId=this.handleFailure.defer(this.timeout,this,[m]);var i=document.createElement("script");i.setAttribute("src",b);i.setAttribute("type","text/javascript");i.setAttribute("id",m.scriptId);this.head.appendChild(i);this.trans=m},createCallback:function(d,b,c){var a=this;return function(e){a.trans=false;a.destroyTrans(c,true);if(d===Ext.data.Api.actions.read){a.onRead.call(a,d,c,e)}else{a.onWrite.call(a,d,c,e,b)}}},onRead:function(d,c,b){var a;try{a=c.reader.readRecords(b)}catch(g){this.fireEvent("loadexception",this,c,b,g);this.fireEvent("exception",this,"response",d,c,b,g);c.callback.call(c.scope||window,null,c.arg,false);return}if(a.success===false){this.fireEvent("loadexception",this,c,b);this.fireEvent("exception",this,"remote",d,c,b,null)}else{this.fireEvent("load",this,b,c.arg)}c.callback.call(c.scope||window,a,c.arg,a.success)},onWrite:function(h,g,c,b){var a=g.reader;try{var d=a.readResponse(h,c)}catch(i){this.fireEvent("exception",this,"response",h,g,d,i);g.callback.call(g.scope||window,null,d,false);return}if(!d.success===true){this.fireEvent("exception",this,"remote",h,g,d,b);g.callback.call(g.scope||window,null,d,false);return}this.fireEvent("write",this,h,d.data,d,b,g.arg);g.callback.call(g.scope||window,d.data,d,true)},isLoading:function(){return this.trans?true:false},abort:function(){if(this.isLoading()){this.destroyTrans(this.trans)}},destroyTrans:function(b,a){this.head.removeChild(document.getElementById(b.scriptId));clearTimeout(b.timeoutId);if(a){window[b.cb]=undefined;try{delete window[b.cb]}catch(c){}}else{window[b.cb]=function(){window[b.cb]=undefined;try{delete window[b.cb]}catch(d){}}}},handleFailure:function(a){this.trans=false;this.destroyTrans(a,false);if(a.action===Ext.data.Api.actions.read){this.fireEvent("loadexception",this,null,a.arg)}this.fireEvent("exception",this,"response",a.action,{response:null,options:a.arg});a.callback.call(a.scope||window,null,a.arg,false)},destroy:function(){this.abort();Ext.data.ScriptTagProxy.superclass.destroy.call(this)}});Ext.data.HttpProxy=function(a){Ext.data.HttpProxy.superclass.constructor.call(this,a);this.conn=a;this.conn.url=null;this.useAjax=!a||!a.events;var c=Ext.data.Api.actions;this.activeRequest={};for(var b in c){this.activeRequest[c[b]]=undefined}};Ext.extend(Ext.data.HttpProxy,Ext.data.DataProxy,{getConnection:function(){return this.useAjax?Ext.Ajax:this.conn},setUrl:function(a,b){this.conn.url=a;if(b===true){this.url=a;this.api=null;Ext.data.Api.prepare(this)}},doRequest:function(g,d,i,c,b,e,a){var h={method:(this.api[g])?this.api[g]["method"]:undefined,request:{callback:b,scope:e,arg:a},reader:c,callback:this.createCallback(g,d),scope:this};if(i.jsonData){h.jsonData=i.jsonData}else{if(i.xmlData){h.xmlData=i.xmlData}else{h.params=i||{}}}this.conn.url=this.buildUrl(g,d);if(this.useAjax){Ext.applyIf(h,this.conn);if(g==Ext.data.Api.actions.read&&this.activeRequest[g]){Ext.Ajax.abort(this.activeRequest[g])}this.activeRequest[g]=Ext.Ajax.request(h)}else{this.conn.request(h)}this.conn.url=null},createCallback:function(b,a){return function(e,d,c){this.activeRequest[b]=undefined;if(!d){if(b===Ext.data.Api.actions.read){this.fireEvent("loadexception",this,e,c)}this.fireEvent("exception",this,"response",b,e,c);e.request.callback.call(e.request.scope,null,e.request.arg,false);return}if(b===Ext.data.Api.actions.read){this.onRead(b,e,c)}else{this.onWrite(b,e,c,a)}}},onRead:function(d,h,b){var a;try{a=h.reader.read(b)}catch(g){this.fireEvent("loadexception",this,h,b,g);this.fireEvent("exception",this,"response",d,h,b,g);h.request.callback.call(h.request.scope,null,h.request.arg,false);return}if(a.success===false){this.fireEvent("loadexception",this,h,b);var c=h.reader.readResponse(d,b);this.fireEvent("exception",this,"remote",d,h,c,null)}else{this.fireEvent("load",this,h,h.request.arg)}h.request.callback.call(h.request.scope,a,h.request.arg,a.success)},onWrite:function(g,i,c,b){var a=i.reader;var d;try{d=a.readResponse(g,c)}catch(h){this.fireEvent("exception",this,"response",g,i,c,h);i.request.callback.call(i.request.scope,null,i.request.arg,false);return}if(d.success===true){this.fireEvent("write",this,g,d.data,d,b,i.request.arg)}else{this.fireEvent("exception",this,"remote",g,i,d,b)}i.request.callback.call(i.request.scope,d.data,d,d.success)},destroy:function(){if(!this.useAjax){this.conn.abort()}else{if(this.activeRequest){var b=Ext.data.Api.actions;for(var a in b){if(this.activeRequest[b[a]]){Ext.Ajax.abort(this.activeRequest[b[a]])}}}}Ext.data.HttpProxy.superclass.destroy.call(this)}});Ext.data.MemoryProxy=function(b){var a={};a[Ext.data.Api.actions.read]=true;Ext.data.MemoryProxy.superclass.constructor.call(this,{api:a});this.data=b};Ext.extend(Ext.data.MemoryProxy,Ext.data.DataProxy,{doRequest:function(b,c,a,d,h,i,j){a=a||{};var k;try{k=d.readRecords(this.data)}catch(g){this.fireEvent("loadexception",this,null,j,g);this.fireEvent("exception",this,"response",b,j,null,g);h.call(i,null,j,false);return}h.call(i,k,j,true)}});Ext.data.Types=new function(){var a=Ext.data.SortTypes;Ext.apply(this,{stripRe:/[\$,%]/g,AUTO:{convert:function(b){return b},sortType:a.none,type:"auto"},STRING:{convert:function(b){return(b===undefined||b===null)?"":String(b)},sortType:a.asUCString,type:"string"},INT:{convert:function(b){return b!==undefined&&b!==null&&b!==""?parseInt(String(b).replace(Ext.data.Types.stripRe,""),10):(this.useNull?null:0)},sortType:a.none,type:"int"},FLOAT:{convert:function(b){return b!==undefined&&b!==null&&b!==""?parseFloat(String(b).replace(Ext.data.Types.stripRe,""),10):(this.useNull?null:0)},sortType:a.none,type:"float"},BOOL:{convert:function(b){return b===true||b==="true"||b==1},sortType:a.none,type:"bool"},DATE:{convert:function(c){var d=this.dateFormat;if(!c){return null}if(Ext.isDate(c)){return c}if(d){if(d=="timestamp"){return new Date(c*1000)}if(d=="time"){return new Date(parseInt(c,10))}return Date.parseDate(c,d)}var b=Date.parse(c);return b?new Date(b):null},sortType:a.asDate,type:"date"}});Ext.apply(this,{BOOLEAN:this.BOOL,INTEGER:this.INT,NUMBER:this.FLOAT})};Ext.data.JsonWriter=Ext.extend(Ext.data.DataWriter,{encode:true,encodeDelete:false,constructor:function(a){Ext.data.JsonWriter.superclass.constructor.call(this,a)},render:function(c,d,b){if(this.encode===true){Ext.apply(c,d);c[this.meta.root]=Ext.encode(b)}else{var a=Ext.apply({},d);a[this.meta.root]=b;c.jsonData=a}},createRecord:function(a){return this.toHash(a)},updateRecord:function(a){return this.toHash(a)},destroyRecord:function(b){if(this.encodeDelete){var a={};a[this.meta.idProperty]=b.id;return a}else{return b.id}}});Ext.data.JsonReader=function(a,b){a=a||{};Ext.applyIf(a,{idProperty:"id",successProperty:"success",totalProperty:"total"});Ext.data.JsonReader.superclass.constructor.call(this,a,b||a.fields)};Ext.extend(Ext.data.JsonReader,Ext.data.DataReader,{read:function(a){var b=a.responseText;var c=Ext.decode(b);if(!c){throw {message:"JsonReader.read: Json object not found"}}return this.readRecords(c)},readResponse:function(e,b){var h=(b.responseText!==undefined)?Ext.decode(b.responseText):b;if(!h){throw new Ext.data.JsonReader.Error("response")}var a=this.getRoot(h),g=this.getSuccess(h);if(g&&e===Ext.data.Api.actions.create){var d=Ext.isDefined(a);if(d&&Ext.isEmpty(a)){throw new Ext.data.JsonReader.Error("root-empty",this.meta.root)}else{if(!d){throw new Ext.data.JsonReader.Error("root-undefined-response",this.meta.root)}}}var c=new Ext.data.Response({action:e,success:g,data:(a)?this.extractData(a,false):[],message:this.getMessage(h),raw:h});if(Ext.isEmpty(c.success)){throw new Ext.data.JsonReader.Error("successProperty-response",this.meta.successProperty)}return c},readRecords:function(a){this.jsonData=a;if(a.metaData){this.onMetaChange(a.metaData)}var m=this.meta,h=this.recordType,b=h.prototype.fields,l=b.items,i=b.length,j;var g=this.getRoot(a),e=g.length,d=e,k=true;if(m.totalProperty){j=parseInt(this.getTotal(a),10);if(!isNaN(j)){d=j}}if(m.successProperty){j=this.getSuccess(a);if(j===false||j==="false"){k=false}}return{success:k,records:this.extractData(g,true),totalRecords:d}},buildExtractors:function(){if(this.ef){return}var l=this.meta,h=this.recordType,e=h.prototype.fields,k=e.items,j=e.length;if(l.totalProperty){this.getTotal=this.createAccessor(l.totalProperty)}if(l.successProperty){this.getSuccess=this.createAccessor(l.successProperty)}if(l.messageProperty){this.getMessage=this.createAccessor(l.messageProperty)}this.getRoot=l.root?this.createAccessor(l.root):function(g){return g};if(l.id||l.idProperty){var d=this.createAccessor(l.id||l.idProperty);this.getId=function(i){var g=d(i);return(g===undefined||g==="")?null:g}}else{this.getId=function(){return null}}var c=[];for(var b=0;b<j;b++){e=k[b];var a=(e.mapping!==undefined&&e.mapping!==null)?e.mapping:e.name;c.push(this.createAccessor(a))}this.ef=c},simpleAccess:function(b,a){return b[a]},createAccessor:function(){var a=/[\[\.]/;return function(c){if(Ext.isEmpty(c)){return Ext.emptyFn}if(Ext.isFunction(c)){return c}var b=String(c).search(a);if(b>=0){return new Function("obj","return obj"+(b>0?".":"")+c)}return function(d){return d[c]}}}(),extractValues:function(h,d,a){var g,c={};for(var e=0;e<a;e++){g=d[e];var b=this.ef[e](h);c[g.name]=g.convert((b!==undefined)?b:g.defaultValue,h)}return c}});Ext.data.JsonReader.Error=Ext.extend(Ext.Error,{constructor:function(b,a){this.arg=a;Ext.Error.call(this,b)},name:"Ext.data.JsonReader"});Ext.apply(Ext.data.JsonReader.Error.prototype,{lang:{response:"An error occurred while json-decoding your server response","successProperty-response":'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.',"root-undefined-config":'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.',"idProperty-undefined":'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.',"root-empty":'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.'}});Ext.data.ArrayReader=Ext.extend(Ext.data.JsonReader,{readRecords:function(r){this.arrayData=r;var l=this.meta,d=l?Ext.num(l.idIndex,l.id):null,b=this.recordType,q=b.prototype.fields,z=[],e=true,g;var u=this.getRoot(r);for(var y=0,A=u.length;y<A;y++){var t=u[y],a={},p=((d||d===0)&&t[d]!==undefined&&t[d]!==""?t[d]:null);for(var x=0,m=q.length;x<m;x++){var B=q.items[x],w=B.mapping!==undefined&&B.mapping!==null?B.mapping:x;g=t[w]!==undefined?t[w]:B.defaultValue;g=B.convert(g,t);a[B.name]=g}var c=new b(a,p);c.json=t;z[z.length]=c}var h=z.length;if(l.totalProperty){g=parseInt(this.getTotal(r),10);if(!isNaN(g)){h=g}}if(l.successProperty){g=this.getSuccess(r);if(g===false||g==="false"){e=false}}return{success:e,records:z,totalRecords:h}}});Ext.data.ArrayStore=Ext.extend(Ext.data.Store,{constructor:function(a){Ext.data.ArrayStore.superclass.constructor.call(this,Ext.apply(a,{reader:new Ext.data.ArrayReader(a)}))},loadData:function(e,b){if(this.expandData===true){var d=[];for(var c=0,a=e.length;c<a;c++){d[d.length]=[e[c]]}e=d}Ext.data.ArrayStore.superclass.loadData.call(this,e,b)}});Ext.reg("arraystore",Ext.data.ArrayStore);Ext.data.SimpleStore=Ext.data.ArrayStore;Ext.reg("simplestore",Ext.data.SimpleStore);Ext.data.JsonStore=Ext.extend(Ext.data.Store,{constructor:function(a){Ext.data.JsonStore.superclass.constructor.call(this,Ext.apply(a,{reader:new Ext.data.JsonReader(a)}))}});Ext.reg("jsonstore",Ext.data.JsonStore);Ext.data.XmlWriter=function(a){Ext.data.XmlWriter.superclass.constructor.apply(this,arguments);this.tpl=(typeof(this.tpl)==="string")?new Ext.XTemplate(this.tpl).compile():this.tpl.compile()};Ext.extend(Ext.data.XmlWriter,Ext.data.DataWriter,{documentRoot:"xrequest",forceDocumentRoot:false,root:"records",xmlVersion:"1.0",xmlEncoding:"ISO-8859-15",tpl:'<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',render:function(b,c,a){c=this.toArray(c);b.xmlData=this.tpl.applyTemplate({version:this.xmlVersion,encoding:this.xmlEncoding,documentRoot:(c.length>0||this.forceDocumentRoot===true)?this.documentRoot:false,record:this.meta.record,root:this.root,baseParams:c,records:(Ext.isArray(a[0]))?a:[a]})},createRecord:function(a){return this.toArray(this.toHash(a))},updateRecord:function(a){return this.toArray(this.toHash(a))},destroyRecord:function(b){var a={};a[this.meta.idProperty]=b.id;return this.toArray(a)}});Ext.data.XmlReader=function(a,b){a=a||{};Ext.applyIf(a,{idProperty:a.idProperty||a.idPath||a.id,successProperty:a.successProperty||a.success});Ext.data.XmlReader.superclass.constructor.call(this,a,b||a.fields)};Ext.extend(Ext.data.XmlReader,Ext.data.DataReader,{read:function(a){var b=a.responseXML;if(!b){throw {message:"XmlReader.read: XML Document not available"}}return this.readRecords(b)},readRecords:function(d){this.xmlData=d;var a=d.documentElement||d,c=Ext.DomQuery,g=0,e=true;if(this.meta.totalProperty){g=this.getTotal(a,0)}if(this.meta.successProperty){e=this.getSuccess(a)}var b=this.extractData(c.select(this.meta.record,a),true);return{success:e,records:b,totalRecords:g||b.length}},readResponse:function(g,b){var e=Ext.DomQuery,h=b.responseXML,a=h.documentElement||h;var c=new Ext.data.Response({action:g,success:this.getSuccess(a),message:this.getMessage(a),data:this.extractData(e.select(this.meta.record,a)||e.select(this.meta.root,a),false),raw:h});if(Ext.isEmpty(c.success)){throw new Ext.data.DataReader.Error("successProperty-response",this.meta.successProperty)}if(g===Ext.data.Api.actions.create){var d=Ext.isDefined(c.data);if(d&&Ext.isEmpty(c.data)){throw new Ext.data.JsonReader.Error("root-empty",this.meta.root)}else{if(!d){throw new Ext.data.JsonReader.Error("root-undefined-response",this.meta.root)}}}return c},getSuccess:function(){return true},buildExtractors:function(){if(this.ef){return}var l=this.meta,h=this.recordType,e=h.prototype.fields,k=e.items,j=e.length;if(l.totalProperty){this.getTotal=this.createAccessor(l.totalProperty)}if(l.successProperty){this.getSuccess=this.createAccessor(l.successProperty)}if(l.messageProperty){this.getMessage=this.createAccessor(l.messageProperty)}this.getRoot=function(g){return(!Ext.isEmpty(g[this.meta.record]))?g[this.meta.record]:g[this.meta.root]};if(l.idPath||l.idProperty){var d=this.createAccessor(l.idPath||l.idProperty);this.getId=function(g){var i=d(g)||g.id;return(i===undefined||i==="")?null:i}}else{this.getId=function(){return null}}var c=[];for(var b=0;b<j;b++){e=k[b];var a=(e.mapping!==undefined&&e.mapping!==null)?e.mapping:e.name;c.push(this.createAccessor(a))}this.ef=c},createAccessor:function(){var a=Ext.DomQuery;return function(b){if(Ext.isFunction(b)){return b}switch(b){case this.meta.totalProperty:return function(c,d){return a.selectNumber(b,c,d)};break;case this.meta.successProperty:return function(d,e){var c=a.selectValue(b,d,true);var g=c!==false&&c!=="false";return g};break;default:return function(c,d){return a.selectValue(b,c,d)};break}}}(),extractValues:function(h,d,a){var g,c={};for(var e=0;e<a;e++){g=d[e];var b=this.ef[e](h);c[g.name]=g.convert((b!==undefined)?b:g.defaultValue,h)}return c}});Ext.data.XmlStore=Ext.extend(Ext.data.Store,{constructor:function(a){Ext.data.XmlStore.superclass.constructor.call(this,Ext.apply(a,{reader:new Ext.data.XmlReader(a)}))}});Ext.reg("xmlstore",Ext.data.XmlStore);Ext.data.GroupingStore=Ext.extend(Ext.data.Store,{constructor:function(d){d=d||{};this.hasMultiSort=true;this.multiSortInfo=this.multiSortInfo||{sorters:[]};var e=this.multiSortInfo.sorters,c=d.groupField||this.groupField,b=d.sortInfo||this.sortInfo,a=d.groupDir||this.groupDir;if(c){e.push({field:c,direction:a})}if(b){e.push(b)}Ext.data.GroupingStore.superclass.constructor.call(this,d);this.addEvents("groupchange");this.applyGroupField()},remoteGroup:false,groupOnSort:false,groupDir:"ASC",clearGrouping:function(){this.groupField=false;if(this.remoteGroup){if(this.baseParams){delete this.baseParams.groupBy;delete this.baseParams.groupDir}var a=this.lastOptions;if(a&&a.params){delete a.params.groupBy;delete a.params.groupDir}this.reload()}else{this.sort();this.fireEvent("datachanged",this)}},groupBy:function(e,a,d){d=d?(String(d).toUpperCase()=="DESC"?"DESC":"ASC"):this.groupDir;if(this.groupField==e&&this.groupDir==d&&!a){return}var c=this.multiSortInfo.sorters;if(c.length>0&&c[0].field==this.groupField){c.shift()}this.groupField=e;this.groupDir=d;this.applyGroupField();var b=function(){this.fireEvent("groupchange",this,this.getGroupState())};if(this.groupOnSort){this.sort(e,d);b.call(this);return}if(this.remoteGroup){this.on("load",b,this,{single:true});this.reload()}else{this.sort(c);b.call(this)}},sort:function(h,c){if(this.remoteSort){return Ext.data.GroupingStore.superclass.sort.call(this,h,c)}var g=[];if(Ext.isArray(arguments[0])){g=arguments[0]}else{if(h==undefined){g=this.sortInfo?[this.sortInfo]:[]}else{var e=this.fields.get(h);if(!e){return false}var b=e.name,a=this.sortInfo||null,d=this.sortToggle?this.sortToggle[b]:null;if(!c){if(a&&a.field==b){c=(this.sortToggle[b]||"ASC").toggle("ASC","DESC")}else{c=e.sortDir}}this.sortToggle[b]=c;this.sortInfo={field:b,direction:c};g=[this.sortInfo]}}if(this.groupField){g.unshift({direction:this.groupDir,field:this.groupField})}return this.multiSort.call(this,g,c)},applyGroupField:function(){if(this.remoteGroup){if(!this.baseParams){this.baseParams={}}Ext.apply(this.baseParams,{groupBy:this.groupField,groupDir:this.groupDir});var a=this.lastOptions;if(a&&a.params){a.params.groupDir=this.groupDir;delete a.params.groupBy}}},applyGrouping:function(a){if(this.groupField!==false){this.groupBy(this.groupField,true,this.groupDir);return true}else{if(a===true){this.fireEvent("datachanged",this)}return false}},getGroupState:function(){return this.groupOnSort&&this.groupField!==false?(this.sortInfo?this.sortInfo.field:undefined):this.groupField}});Ext.reg("groupingstore",Ext.data.GroupingStore);Ext.data.DirectProxy=function(a){Ext.apply(this,a);if(typeof this.paramOrder=="string"){this.paramOrder=this.paramOrder.split(/[\s,|]/)}Ext.data.DirectProxy.superclass.constructor.call(this,a)};Ext.extend(Ext.data.DirectProxy,Ext.data.DataProxy,{paramOrder:undefined,paramsAsHash:true,directFn:undefined,doRequest:function(b,c,a,e,k,l,n){var j=[],h=this.api[b]||this.directFn;switch(b){case Ext.data.Api.actions.create:j.push(a.jsonData);break;case Ext.data.Api.actions.read:if(h.directCfg.method.len>0){if(this.paramOrder){for(var d=0,g=this.paramOrder.length;d<g;d++){j.push(a[this.paramOrder[d]])}}else{if(this.paramsAsHash){j.push(a)}}}break;case Ext.data.Api.actions.update:j.push(a.jsonData);break;case Ext.data.Api.actions.destroy:j.push(a.jsonData);break}var m={params:a||{},request:{callback:k,scope:l,arg:n},reader:e};j.push(this.createCallback(b,c,m),this);h.apply(window,j)},createCallback:function(d,a,b){var c=this;return function(e,g){if(!g.status){if(d===Ext.data.Api.actions.read){c.fireEvent("loadexception",c,b,g,null)}c.fireEvent("exception",c,"remote",d,b,g,null);b.request.callback.call(b.request.scope,null,b.request.arg,false);return}if(d===Ext.data.Api.actions.read){c.onRead(d,b,e,g)}else{c.onWrite(d,b,e,g,a)}}},onRead:function(g,e,a,d){var b;try{b=e.reader.readRecords(a)}catch(c){this.fireEvent("loadexception",this,e,d,c);this.fireEvent("exception",this,"response",g,e,d,c);e.request.callback.call(e.request.scope,null,e.request.arg,false);return}this.fireEvent("load",this,d,e.request.arg);e.request.callback.call(e.request.scope,b,e.request.arg,true)},onWrite:function(g,d,a,c,b){var e=d.reader.extractData(d.reader.getRoot(a),false);var h=d.reader.getSuccess(a);h=(h!==false);if(h){this.fireEvent("write",this,g,e,c,b,d.request.arg)}else{this.fireEvent("exception",this,"remote",g,d,a,b)}d.request.callback.call(d.request.scope,e,c,h)}});Ext.data.DirectStore=Ext.extend(Ext.data.Store,{constructor:function(a){var b=Ext.apply({},{batchTransactions:false},a);Ext.data.DirectStore.superclass.constructor.call(this,Ext.apply(b,{proxy:Ext.isDefined(b.proxy)?b.proxy:new Ext.data.DirectProxy(Ext.copyTo({},b,"paramOrder,paramsAsHash,directFn,api")),reader:(!Ext.isDefined(b.reader)&&b.fields)?new Ext.data.JsonReader(Ext.copyTo({},b,"totalProperty,root,idProperty"),b.fields):b.reader}))}});Ext.reg("directstore",Ext.data.DirectStore);Ext.Direct=Ext.extend(Ext.util.Observable,{exceptions:{TRANSPORT:"xhr",PARSE:"parse",LOGIN:"login",SERVER:"exception"},constructor:function(){this.addEvents("event","exception");this.transactions={};this.providers={}},addProvider:function(e){var c=arguments;if(c.length>1){for(var d=0,b=c.length;d<b;d++){this.addProvider(c[d])}return}if(!e.events){e=new Ext.Direct.PROVIDERS[e.type](e)}e.id=e.id||Ext.id();this.providers[e.id]=e;e.on("data",this.onProviderData,this);e.on("exception",this.onProviderException,this);if(!e.isConnected()){e.connect()}return e},getProvider:function(a){return this.providers[a]},removeProvider:function(b){var a=b.id?b:this.providers[b];a.un("data",this.onProviderData,this);a.un("exception",this.onProviderException,this);delete this.providers[a.id];return a},addTransaction:function(a){this.transactions[a.tid]=a;return a},removeTransaction:function(a){delete this.transactions[a.tid||a];return a},getTransaction:function(a){return this.transactions[a.tid||a]},onProviderData:function(d,c){if(Ext.isArray(c)){for(var b=0,a=c.length;b<a;b++){this.onProviderData(d,c[b])}return}if(c.name&&c.name!="event"&&c.name!="exception"){this.fireEvent(c.name,c)}else{if(c.type=="exception"){this.fireEvent("exception",c)}}this.fireEvent("event",c,d)},createEvent:function(a,b){return new Ext.Direct.eventTypes[a.type](Ext.apply(a,b))}});Ext.Direct=new Ext.Direct();Ext.Direct.TID=1;Ext.Direct.PROVIDERS={};Ext.Direct.Transaction=function(a){Ext.apply(this,a);this.tid=++Ext.Direct.TID;this.retryCount=0};Ext.Direct.Transaction.prototype={send:function(){this.provider.queueTransaction(this)},retry:function(){this.retryCount++;this.send()},getProvider:function(){return this.provider}};Ext.Direct.Event=function(a){Ext.apply(this,a)};Ext.Direct.Event.prototype={status:true,getData:function(){return this.data}};Ext.Direct.RemotingEvent=Ext.extend(Ext.Direct.Event,{type:"rpc",getTransaction:function(){return this.transaction||Ext.Direct.getTransaction(this.tid)}});Ext.Direct.ExceptionEvent=Ext.extend(Ext.Direct.RemotingEvent,{status:false,type:"exception"});Ext.Direct.eventTypes={rpc:Ext.Direct.RemotingEvent,event:Ext.Direct.Event,exception:Ext.Direct.ExceptionEvent};Ext.direct.Provider=Ext.extend(Ext.util.Observable,{priority:1,constructor:function(a){Ext.apply(this,a);this.addEvents("connect","disconnect","data","exception");Ext.direct.Provider.superclass.constructor.call(this,a)},isConnected:function(){return false},connect:Ext.emptyFn,disconnect:Ext.emptyFn});Ext.direct.JsonProvider=Ext.extend(Ext.direct.Provider,{parseResponse:function(a){if(!Ext.isEmpty(a.responseText)){if(typeof a.responseText=="object"){return a.responseText}return Ext.decode(a.responseText)}return null},getEvents:function(j){var g=null;try{g=this.parseResponse(j)}catch(h){var d=new Ext.Direct.ExceptionEvent({data:h,xhr:j,code:Ext.Direct.exceptions.PARSE,message:"Error parsing json response: \n\n "+g});return[d]}var c=[];if(Ext.isArray(g)){for(var b=0,a=g.length;b<a;b++){c.push(Ext.Direct.createEvent(g[b]))}}else{c.push(Ext.Direct.createEvent(g))}return c}});Ext.direct.PollingProvider=Ext.extend(Ext.direct.JsonProvider,{priority:3,interval:3000,constructor:function(a){Ext.direct.PollingProvider.superclass.constructor.call(this,a);this.addEvents("beforepoll","poll")},isConnected:function(){return !!this.pollTask},connect:function(){if(this.url&&!this.pollTask){this.pollTask=Ext.TaskMgr.start({run:function(){if(this.fireEvent("beforepoll",this)!==false){if(typeof this.url=="function"){this.url(this.baseParams)}else{Ext.Ajax.request({url:this.url,callback:this.onData,scope:this,params:this.baseParams})}}},interval:this.interval,scope:this});this.fireEvent("connect",this)}else{if(!this.url){throw"Error initializing PollingProvider, no url configured."}}},disconnect:function(){if(this.pollTask){Ext.TaskMgr.stop(this.pollTask);delete this.pollTask;this.fireEvent("disconnect",this)}},onData:function(d,j,h){if(j){var c=this.getEvents(h);for(var b=0,a=c.length;b<a;b++){var g=c[b];this.fireEvent("data",this,g)}}else{var g=new Ext.Direct.ExceptionEvent({data:g,code:Ext.Direct.exceptions.TRANSPORT,message:"Unable to connect to the server.",xhr:h});this.fireEvent("data",this,g)}}});Ext.Direct.PROVIDERS.polling=Ext.direct.PollingProvider;Ext.direct.RemotingProvider=Ext.extend(Ext.direct.JsonProvider,{enableBuffer:10,maxRetries:1,timeout:undefined,constructor:function(a){Ext.direct.RemotingProvider.superclass.constructor.call(this,a);this.addEvents("beforecall","call");this.namespace=(Ext.isString(this.namespace))?Ext.ns(this.namespace):this.namespace||window;this.transactions={};this.callBuffer=[]},initAPI:function(){var h=this.actions;for(var j in h){var d=this.namespace[j]||(this.namespace[j]={}),e=h[j];for(var g=0,b=e.length;g<b;g++){var a=e[g];d[a.name]=this.createMethod(j,a)}}},isConnected:function(){return !!this.connected},connect:function(){if(this.url){this.initAPI();this.connected=true;this.fireEvent("connect",this)}else{if(!this.url){throw"Error initializing RemotingProvider, no url configured."}}},disconnect:function(){if(this.connected){this.connected=false;this.fireEvent("disconnect",this)}},onData:function(a,h,j){if(h){var k=this.getEvents(j);for(var b=0,c=k.length;b<c;b++){var d=k[b],l=this.getTransaction(d);this.fireEvent("data",this,d);if(l){this.doCallback(l,d,true);Ext.Direct.removeTransaction(l)}}}else{var g=[].concat(a.ts);for(var b=0,c=g.length;b<c;b++){var l=this.getTransaction(g[b]);if(l&&l.retryCount<this.maxRetries){l.retry()}else{var d=new Ext.Direct.ExceptionEvent({data:d,transaction:l,code:Ext.Direct.exceptions.TRANSPORT,message:"Unable to connect to the server.",xhr:j});this.fireEvent("data",this,d);if(l){this.doCallback(l,d,false);Ext.Direct.removeTransaction(l)}}}}},getCallData:function(a){return{action:a.action,method:a.method,data:a.data,type:"rpc",tid:a.tid}},doSend:function(d){var g={url:this.url,callback:this.onData,scope:this,ts:d,timeout:this.timeout},b;if(Ext.isArray(d)){b=[];for(var c=0,a=d.length;c<a;c++){b.push(this.getCallData(d[c]))}}else{b=this.getCallData(d)}if(this.enableUrlEncode){var e={};e[Ext.isString(this.enableUrlEncode)?this.enableUrlEncode:"data"]=Ext.encode(b);g.params=e}else{g.jsonData=b}Ext.Ajax.request(g)},combineAndSend:function(){var a=this.callBuffer.length;if(a>0){this.doSend(a==1?this.callBuffer[0]:this.callBuffer);this.callBuffer=[]}},queueTransaction:function(a){if(a.form){this.processForm(a);return}this.callBuffer.push(a);if(this.enableBuffer){if(!this.callTask){this.callTask=new Ext.util.DelayedTask(this.combineAndSend,this)}this.callTask.delay(Ext.isNumber(this.enableBuffer)?this.enableBuffer:10)}else{this.combineAndSend()}},doCall:function(i,a,b){var h=null,e=b[a.len],g=b[a.len+1];if(a.len!==0){h=b.slice(0,a.len)}var d=new Ext.Direct.Transaction({provider:this,args:b,action:i,method:a.name,data:h,cb:g&&Ext.isFunction(e)?e.createDelegate(g):e});if(this.fireEvent("beforecall",this,d,a)!==false){Ext.Direct.addTransaction(d);this.queueTransaction(d);this.fireEvent("call",this,d,a)}},doForm:function(j,b,g,i,e){var d=new Ext.Direct.Transaction({provider:this,action:j,method:b.name,args:[g,i,e],cb:e&&Ext.isFunction(i)?i.createDelegate(e):i,isForm:true});if(this.fireEvent("beforecall",this,d,b)!==false){Ext.Direct.addTransaction(d);var a=String(g.getAttribute("enctype")).toLowerCase()=="multipart/form-data",h={extTID:d.tid,extAction:j,extMethod:b.name,extType:"rpc",extUpload:String(a)};Ext.apply(d,{form:Ext.getDom(g),isUpload:a,params:i&&Ext.isObject(i.params)?Ext.apply(h,i.params):h});this.fireEvent("call",this,d,b);this.processForm(d)}},processForm:function(a){Ext.Ajax.request({url:this.url,params:a.params,callback:this.onData,scope:this,form:a.form,isUpload:a.isUpload,ts:a})},createMethod:function(d,a){var b;if(!a.formHandler){b=function(){this.doCall(d,a,Array.prototype.slice.call(arguments,0))}.createDelegate(this)}else{b=function(e,g,c){this.doForm(d,a,e,g,c)}.createDelegate(this)}b.directCfg={action:d,method:a};return b},getTransaction:function(a){return a&&a.tid?Ext.Direct.getTransaction(a.tid):null},doCallback:function(c,g){var d=g.status?"success":"failure";if(c&&c.cb){var b=c.cb,a=Ext.isDefined(g.result)?g.result:g.data;if(Ext.isFunction(b)){b(a,g)}else{Ext.callback(b[d],b.scope,[a,g]);Ext.callback(b.callback,b.scope,[a,g])}}}});Ext.Direct.PROVIDERS.remoting=Ext.direct.RemotingProvider;Ext.Resizable=Ext.extend(Ext.util.Observable,{constructor:function(d,e){this.el=Ext.get(d);if(e&&e.wrap){e.resizeChild=this.el;this.el=this.el.wrap(typeof e.wrap=="object"?e.wrap:{cls:"xresizable-wrap"});this.el.id=this.el.dom.id=e.resizeChild.id+"-rzwrap";this.el.setStyle("overflow","hidden");this.el.setPositioning(e.resizeChild.getPositioning());e.resizeChild.clearPositioning();if(!e.width||!e.height){var g=e.resizeChild.getSize();this.el.setSize(g.width,g.height)}if(e.pinned&&!e.adjustments){e.adjustments="auto"}}this.proxy=this.el.createProxy({tag:"div",cls:"x-resizable-proxy",id:this.el.id+"-rzproxy"},Ext.getBody());this.proxy.unselectable();this.proxy.enableDisplayMode("block");Ext.apply(this,e);if(this.pinned){this.disableTrackOver=true;this.el.addClass("x-resizable-pinned")}var k=this.el.getStyle("position");if(k!="absolute"&&k!="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 o=this.handles.split(/\s*?[,;]\s*?| /);var c=Ext.Resizable.positions;for(var j=0,l=o.length;j<l;j++){if(o[j]&&c[o[j]]){var n=c[o[j]];this[n]=new Ext.Resizable.Handle(this,n,this.disableTrackOver,this.transparent,this.handleCls)}}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 b=this.resizeChild;var m=this.west,h=this.east,a=this.north,o=this.south;if(b&&(m||a)){b.position("relative");b.setLeft(m?m.el.getWidth():0);b.setTop(a?a.el.getHeight():0)}this.adjustments=[(h?-h.el.getWidth():0)+(m?-m.el.getWidth():0),(a?-a.el.getHeight():0)+(o?-o.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);if(this.constrainTo){this.dd.constrainTo(this.constrainTo)}}this.addEvents("beforeresize","resize");if(this.width!==null&&this.height!==null){this.resizeTo(this.width,this.height)}else{this.updateChildSize()}if(Ext.isIE){this.el.dom.style.zoom=1}Ext.Resizable.superclass.constructor.call(this)},adjustments:[0,0],animate:false,disableTrackOver:false,draggable:false,duration:0.35,dynamic:false,easing:"easeOutStrong",enabled:true,handles:false,multiDirectional:false,height:null,width:null,heightIncrement:0,widthIncrement:0,minHeight:5,minWidth:5,maxHeight:10000,maxWidth:10000,minX:0,minY:0,pinned:false,preserveRatio:false,resizeChild:false,transparent:false,resizeTo:function(b,a){this.el.setSize(b,a);this.updateChildSize();this.fireEvent("resize",this,b,a,null)},startSizing:function(c,b){this.fireEvent("beforeresize",this,c);if(this.enabled){if(!this.overlay){this.overlay=this.el.createProxy({tag:"div",cls:"x-resizable-overlay",html:"&#160;"},Ext.getBody());this.overlay.unselectable();this.overlay.enableDisplayMode("block");this.overlay.on({scope:this,mousemove:this.onMouseMove,mouseup:this.onMouseUp})}this.overlay.setStyle("cursor",b.el.getStyle("cursor"));this.resizing=true;this.startBox=this.el.getBox();this.startPoint=c.getXY();this.offsets=[(this.startBox.x+this.startBox.width)-this.startPoint[0],(this.startBox.y+this.startBox.height)-this.startPoint[1]];this.overlay.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.overlay.show();if(this.constrainTo){var a=Ext.get(this.constrainTo);this.resizeRegion=a.getRegion().adjust(a.getFrameWidth("t"),a.getFrameWidth("l"),-a.getFrameWidth("b"),-a.getFrameWidth("r"))}this.proxy.setStyle("visibility","hidden");this.proxy.show();this.proxy.setBox(this.startBox);if(!this.dynamic){this.proxy.setStyle("visibility","visible")}}},onMouseDown:function(a,b){if(this.enabled){b.stopEvent();this.activeHandle=a;this.startSizing(b,a)}},onMouseUp:function(b){this.activeHandle=null;var a=this.resizeElement();this.resizing=false;this.handleOut();this.overlay.hide();this.proxy.hide();this.fireEvent("resize",this,a.width,a.height,b)},updateChildSize:function(){if(this.resizeChild){var d=this.el;var e=this.resizeChild;var c=this.adjustments;if(d.dom.offsetWidth){var a=d.getSize(true);e.setSize(a.width+c[0],a.height+c[1])}if(Ext.isIE9m){setTimeout(function(){if(d.dom.offsetWidth){var g=d.getSize(true);e.setSize(g.width+c[0],g.height+c[1])}},10)}}},snap:function(c,e,b){if(!e||!c){return c}var d=c;var a=c%e;if(a>0){if(a>(e/2)){d=c+(e-a)}else{d=c-a}}return Math.max(b,d)},resizeElement:function(){var a=this.proxy.getBox();if(this.updateBox){this.el.setBox(a,false,this.animate,this.duration,null,this.easing)}else{this.el.setSize(a.width,a.height,this.animate,this.duration,null,this.easing)}this.updateChildSize();if(!this.dynamic){this.proxy.hide()}if(this.draggable&&this.constrainTo){this.dd.resetConstraints();this.dd.constrainTo(this.constrainTo)}return a},constrain:function(b,c,a,d){if(b-c<a){c=b-a}else{if(b-c>d){c=b-d}}return c},onMouseMove:function(z){if(this.enabled&&this.activeHandle){try{if(this.resizeRegion&&!this.resizeRegion.contains(z.getPoint())){return}var t=this.curSize||this.startBox,l=this.startBox.x,k=this.startBox.y,c=l,b=k,m=t.width,u=t.height,d=m,o=u,n=this.minWidth,A=this.minHeight,s=this.maxWidth,D=this.maxHeight,i=this.widthIncrement,a=this.heightIncrement,B=z.getXY(),r=-(this.startPoint[0]-Math.max(this.minX,B[0])),p=-(this.startPoint[1]-Math.max(this.minY,B[1])),j=this.activeHandle.position,E,g;switch(j){case"east":m+=r;m=Math.min(Math.max(n,m),s);break;case"south":u+=p;u=Math.min(Math.max(A,u),D);break;case"southeast":m+=r;u+=p;m=Math.min(Math.max(n,m),s);u=Math.min(Math.max(A,u),D);break;case"north":p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"west":r=this.constrain(m,r,n,s);l+=r;m-=r;break;case"northeast":m+=r;m=Math.min(Math.max(n,m),s);p=this.constrain(u,p,A,D);k+=p;u-=p;break;case"northwest":r=this.constrain(m,r,n,s);p=this.constrain(u,p,A,D);k+=p;u-=p;l+=r;m-=r;break;case"southwest":r=this.constrain(m,r,n,s);u+=p;u=Math.min(Math.max(A,u),D);l+=r;m-=r;break}var q=this.snap(m,i,n);var C=this.snap(u,a,A);if(q!=m||C!=u){switch(j){case"northeast":k-=C-u;break;case"north":k-=C-u;break;case"southwest":l-=q-m;break;case"west":l-=q-m;break;case"northwest":l-=q-m;k-=C-u;break}m=q;u=C}if(this.preserveRatio){switch(j){case"southeast":case"east":u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);break;case"south":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"northeast":m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);break;case"north":E=m;m=d*(u/o);m=Math.min(Math.max(n,m),s);u=o*(m/d);l+=(E-m)/2;break;case"southwest":u=o*(m/d);u=Math.min(Math.max(A,u),D);E=m;m=d*(u/o);l+=E-m;break;case"west":g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);k+=(g-u)/2;E=m;m=d*(u/o);l+=E-m;break;case"northwest":E=m;g=u;u=o*(m/d);u=Math.min(Math.max(A,u),D);m=d*(u/o);k+=g-u;l+=E-m;break}}this.proxy.setBounds(l,k,m,u);if(this.dynamic){this.resizeElement()}}catch(v){}}},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(b){Ext.destroy(this.dd,this.overlay,this.proxy);this.overlay=null;this.proxy=null;var c=Ext.Resizable.positions;for(var a in c){if(typeof c[a]!="function"&&this[c[a]]){this[c[a]].destroy()}}if(b){this.el.update("");Ext.destroy(this.el);this.el=null}this.purgeListeners()},syncHandleHeight:function(){var a=this.el.getHeight(true);if(this.west){this.west.el.setHeight(a)}if(this.east){this.east.el.setHeight(a)}}});Ext.Resizable.positions={n:"north",s:"south",e:"east",w:"west",se:"southeast",sw:"southwest",nw:"northwest",ne:"northeast"};Ext.Resizable.Handle=Ext.extend(Object,{constructor:function(d,g,c,e,a){if(!this.tpl){var b=Ext.DomHelper.createTemplate({tag:"div",cls:"x-resizable-handle x-resizable-handle-{0}"});b.compile();Ext.Resizable.Handle.prototype.tpl=b}this.position=g;this.rz=d;this.el=this.tpl.append(d.el.dom,[this.position],true);this.el.unselectable();if(e){this.el.setOpacity(0)}if(!Ext.isEmpty(a)){this.el.addClass(a)}this.el.on("mousedown",this.onMouseDown,this);if(!c){this.el.on({scope:this,mouseover:this.onMouseOver,mouseout:this.onMouseOut})}},afterResize:function(a){},onMouseDown:function(a){this.rz.onMouseDown(this,a)},onMouseOver:function(a){this.rz.handleOver(this,a)},onMouseOut:function(a){this.rz.handleOut(this,a)},destroy:function(){Ext.destroy(this.el);this.el=null}});Ext.Window=Ext.extend(Ext.Panel,{baseCls:"x-window",resizable:true,draggable:true,closable:true,closeAction:"close",constrain:false,constrainHeader:false,plain:false,minimizable:false,maximizable:false,minHeight:100,minWidth:200,expandOnShow:true,showAnimDuration:0.25,hideAnimDuration:0.25,collapsible:false,initHidden:undefined,hidden:true,elements:"header,body",frame:true,floating:true,initComponent:function(){this.initTools();Ext.Window.superclass.initComponent.call(this);this.addEvents("resize","maximize","minimize","restore");if(Ext.isDefined(this.initHidden)){this.hidden=this.initHidden}if(this.hidden===false){this.hidden=true;this.show()}},getState:function(){return Ext.apply(Ext.Window.superclass.getState.call(this)||{},this.getBox(true))},onRender:function(b,a){Ext.Window.superclass.onRender.call(this,b,a);if(this.plain){this.el.addClass("x-window-plain")}this.focusEl=this.el.createChild({tag:"a",href:"#",cls:"x-dlg-focus",tabIndex:"-1",html:"&#160;"});this.focusEl.swallowEvent("click",true);this.proxy=this.el.createProxy("x-window-proxy");this.proxy.enableDisplayMode("block");if(this.modal){this.mask=this.container.createChild({cls:"ext-el-mask"},this.el.dom);this.mask.enableDisplayMode("block");this.mask.hide();this.mon(this.mask,"click",this.focus,this)}if(this.maximizable){this.mon(this.header,"dblclick",this.toggleMaximize,this)}},initEvents:function(){Ext.Window.superclass.initEvents.call(this);if(this.animateTarget){this.setAnimateTarget(this.animateTarget)}if(this.resizable){this.resizer=new Ext.Resizable(this.el,{minWidth:this.minWidth,minHeight:this.minHeight,handles:this.resizeHandles||"all",pinned:true,resizeElement:this.resizerAction,handleCls:"x-window-handle"});this.resizer.window=this;this.mon(this.resizer,"beforeresize",this.beforeResize,this)}if(this.draggable){this.header.addClass("x-window-draggable")}this.mon(this.el,"mousedown",this.toFront,this);this.manager=this.manager||Ext.WindowMgr;this.manager.register(this);if(this.maximized){this.maximized=false;this.maximize()}if(this.closable){var a=this.getKeyMap();a.on(27,this.onEsc,this);a.disable()}},initDraggable:function(){this.dd=new Ext.Window.DD(this)},onEsc:function(a,b){if(this.activeGhost){this.unghost()}b.stopEvent();this[this.closeAction]()},beforeDestroy:function(){if(this.rendered){this.hide();this.clearAnchor();Ext.destroy(this.focusEl,this.resizer,this.dd,this.proxy,this.mask)}Ext.Window.superclass.beforeDestroy.call(this)},onDestroy:function(){if(this.manager){this.manager.unregister(this)}Ext.Window.superclass.onDestroy.call(this)},initTools:function(){if(this.minimizable){this.addTool({id:"minimize",handler:this.minimize.createDelegate(this,[])})}if(this.maximizable){this.addTool({id:"maximize",handler:this.maximize.createDelegate(this,[])});this.addTool({id:"restore",handler:this.restore.createDelegate(this,[]),hidden:true})}if(this.closable){this.addTool({id:"close",handler:this[this.closeAction].createDelegate(this,[])})}},resizerAction:function(){var a=this.proxy.getBox();this.proxy.hide();this.window.handleResize(a);return a},beforeResize:function(){this.resizer.minHeight=Math.max(this.minHeight,this.getFrameHeight()+40);this.resizer.minWidth=Math.max(this.minWidth,this.getFrameWidth()+40);this.resizeBox=this.el.getBox()},updateHandles:function(){if(Ext.isIE9m&&this.resizer){this.resizer.syncHandleHeight();this.el.repaint()}},handleResize:function(b){var a=this.resizeBox;if(a.x!=b.x||a.y!=b.y){this.updateBox(b)}else{this.setSize(b);if(Ext.isIE6&&Ext.isStrict){this.doLayout()}}this.focus();this.updateHandles();this.saveState()},focus:function(){var e=this.focusEl,a=this.defaultButton,c=typeof a,d,b;if(Ext.isDefined(a)){if(Ext.isNumber(a)&&this.fbar){e=this.fbar.items.get(a)}else{if(Ext.isString(a)){e=Ext.getCmp(a)}else{e=a}}d=e.getEl();b=Ext.getDom(this.container);if(d&&b){if(b!=document.body&&!Ext.lib.Region.getRegion(b).contains(Ext.lib.Region.getRegion(d.dom))){return}}}e=e||this.focusEl;e.focus.defer(10,e)},setAnimateTarget:function(a){a=Ext.get(a);this.animateTarget=a},beforeShow:function(){delete this.el.lastXY;delete this.el.lastLT;if(this.x===undefined||this.y===undefined){var a=this.el.getAlignToXY(this.container,"c-c");var b=this.el.translatePoints(a[0],a[1]);this.x=this.x===undefined?b.left:this.x;this.y=this.y===undefined?b.top:this.y}this.el.setLeftTop(this.x,this.y);if(this.expandOnShow){this.expand(false)}if(this.modal){Ext.getBody().addClass("x-body-masked");this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true));this.mask.show()}},show:function(c,a,b){if(!this.rendered){this.render(Ext.getBody())}if(this.hidden===false){this.toFront();return this}if(this.fireEvent("beforeshow",this)===false){return this}if(a){this.on("show",a,b,{single:true})}this.hidden=false;if(Ext.isDefined(c)){this.setAnimateTarget(c)}this.beforeShow();if(this.animateTarget){this.animShow()}else{this.afterShow()}return this},afterShow:function(b){if(this.isDestroyed){return false}this.proxy.hide();this.el.setStyle("display","block");this.el.show();if(this.maximized){this.fitContainer()}if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.onWindowResize(this.onWindowResize,this)}this.doConstrain();this.doLayout();if(this.keyMap){this.keyMap.enable()}this.toFront();this.updateHandles();if(b&&(Ext.isIE||Ext.isWebKit)){var a=this.getSize();this.onResize(a.width,a.height)}this.onShow();this.fireEvent("show",this)},animShow:function(){this.proxy.show();this.proxy.setBox(this.animateTarget.getBox());this.proxy.setOpacity(0);var a=this.getBox();this.el.setStyle("display","none");this.proxy.shift(Ext.apply(a,{callback:this.afterShow.createDelegate(this,[true],false),scope:this,easing:"easeNone",duration:this.showAnimDuration,opacity:0.5}))},hide:function(c,a,b){if(this.hidden||this.fireEvent("beforehide",this)===false){return this}if(a){this.on("hide",a,b,{single:true})}this.hidden=true;if(c!==undefined){this.setAnimateTarget(c)}if(this.modal){this.mask.hide();Ext.getBody().removeClass("x-body-masked")}if(this.animateTarget){this.animHide()}else{this.el.hide();this.afterHide()}return this},afterHide:function(){this.proxy.hide();if(this.monitorResize||this.modal||this.constrain||this.constrainHeader){Ext.EventManager.removeResizeListener(this.onWindowResize,this)}if(this.keyMap){this.keyMap.disable()}this.onHide();this.fireEvent("hide",this)},animHide:function(){this.proxy.setOpacity(0.5);this.proxy.show();var a=this.getBox(false);this.proxy.setBox(a);this.el.hide();this.proxy.shift(Ext.apply(this.animateTarget.getBox(),{callback:this.afterHide,scope:this,duration:this.hideAnimDuration,easing:"easeNone",opacity:0}))},onShow:Ext.emptyFn,onHide:Ext.emptyFn,onWindowResize:function(){if(this.maximized){this.fitContainer()}if(this.modal){this.mask.setSize("100%","100%");var a=this.mask.dom.offsetHeight;this.mask.setSize(Ext.lib.Dom.getViewWidth(true),Ext.lib.Dom.getViewHeight(true))}this.doConstrain()},doConstrain:function(){if(this.constrain||this.constrainHeader){var b;if(this.constrain){b={right:this.el.shadowOffset,left:this.el.shadowOffset,bottom:this.el.shadowOffset}}else{var a=this.getSize();b={right:-(a.width-100),bottom:-(a.height-25+this.el.getConstrainOffset())}}var c=this.el.getConstrainToXY(this.container,true,b);if(c){this.setPosition(c[0],c[1])}}},ghost:function(a){var c=this.createGhost(a);var b=this.getBox(true);c.setLeftTop(b.x,b.y);c.setWidth(b.width);this.el.hide();this.activeGhost=c;return c},unghost:function(b,a){if(!this.activeGhost){return}if(b!==false){this.el.show();this.focus.defer(10,this);if(Ext.isMac&&Ext.isGecko2){this.cascade(this.setAutoScroll)}}if(a!==false){this.setPosition(this.activeGhost.getLeft(true),this.activeGhost.getTop(true))}this.activeGhost.hide();this.activeGhost.remove();delete this.activeGhost},minimize:function(){this.fireEvent("minimize",this);return this},close:function(){if(this.fireEvent("beforeclose",this)!==false){if(this.hidden){this.doClose()}else{this.hide(null,this.doClose,this)}}},doClose:function(){this.fireEvent("close",this);this.destroy()},maximize:function(){if(!this.maximized){this.expand(false);this.restoreSize=this.getSize();this.restorePos=this.getPosition(true);if(this.maximizable){this.tools.maximize.hide();this.tools.restore.show()}this.maximized=true;this.el.disableShadow();if(this.dd){this.dd.lock()}if(this.collapsible){this.tools.toggle.hide()}this.el.addClass("x-window-maximized");this.container.addClass("x-window-maximized-ct");this.setPosition(0,0);this.fitContainer();this.fireEvent("maximize",this)}return this},restore:function(){if(this.maximized){var a=this.tools;this.el.removeClass("x-window-maximized");if(a.restore){a.restore.hide()}if(a.maximize){a.maximize.show()}this.setPosition(this.restorePos[0],this.restorePos[1]);this.setSize(this.restoreSize.width,this.restoreSize.height);delete this.restorePos;delete this.restoreSize;this.maximized=false;this.el.enableShadow(true);if(this.dd){this.dd.unlock()}if(this.collapsible&&a.toggle){a.toggle.show()}this.container.removeClass("x-window-maximized-ct");this.doConstrain();this.fireEvent("restore",this)}return this},toggleMaximize:function(){return this[this.maximized?"restore":"maximize"]()},fitContainer:function(){var a=this.container.getViewSize(false);this.setSize(a.width,a.height)},setZIndex:function(a){if(this.modal){this.mask.setStyle("z-index",a)}this.el.setZIndex(++a);a+=5;if(this.resizer){this.resizer.proxy.setStyle("z-index",++a)}this.lastZIndex=a},alignTo:function(b,a,c){var d=this.el.getAlignToXY(b,a,c);this.setPagePosition(d[0],d[1]);return this},anchorTo:function(c,e,d,b){this.clearAnchor();this.anchorTarget={el:c,alignment:e,offsets:d};Ext.EventManager.onWindowResize(this.doAnchor,this);var a=typeof b;if(a!="undefined"){Ext.EventManager.on(window,"scroll",this.doAnchor,this,{buffer:a=="number"?b:50})}return this.doAnchor()},doAnchor:function(){var a=this.anchorTarget;this.alignTo(a.el,a.alignment,a.offsets);return this},clearAnchor:function(){if(this.anchorTarget){Ext.EventManager.removeResizeListener(this.doAnchor,this);Ext.EventManager.un(window,"scroll",this.doAnchor,this);delete this.anchorTarget}return this},toFront:function(a){if(this.manager.bringToFront(this)){if(!a||!a.getTarget().focus){this.focus()}}return this},setActive:function(a){if(a){if(!this.maximized){this.el.enableShadow(true)}this.fireEvent("activate",this)}else{this.el.disableShadow();this.fireEvent("deactivate",this)}},toBack:function(){this.manager.sendToBack(this);return this},center:function(){var a=this.el.getAlignToXY(this.container,"c-c");this.setPagePosition(a[0],a[1]);return this}});Ext.reg("window",Ext.Window);Ext.Window.DD=Ext.extend(Ext.dd.DD,{constructor:function(a){this.win=a;Ext.Window.DD.superclass.constructor.call(this,a.el.id,"WindowDD-"+a.id);this.setHandleElId(a.header.id);this.scroll=false},moveOnly:true,headerOffsets:[100,25],startDrag:function(){var a=this.win;this.proxy=a.ghost(a.initialConfig.cls);if(a.constrain!==false){var c=a.el.shadowOffset;this.constrainTo(a.container,{right:c,left:c,bottom:c})}else{if(a.constrainHeader!==false){var b=this.proxy.getSize();this.constrainTo(a.container,{right:-(b.width-this.headerOffsets[0]),bottom:-(b.height-this.headerOffsets[1])})}}},b4Drag:Ext.emptyFn,onDrag:function(a){this.alignElWithMouse(this.proxy,a.getPageX(),a.getPageY())},endDrag:function(a){this.win.unghost();this.win.saveState()}});Ext.WindowGroup=function(){var g={};var d=[];var e=null;var c=function(j,i){return(!j._lastAccess||j._lastAccess<i._lastAccess)?-1:1};var h=function(){var l=d,j=l.length;if(j>0){l.sort(c);var k=l[0].manager.zseed;for(var m=0;m<j;m++){var n=l[m];if(n&&!n.hidden){n.setZIndex(k+(m*10))}}}a()};var b=function(i){if(i!=e){if(e){e.setActive(false)}e=i;if(i){i.setActive(true)}}};var a=function(){for(var j=d.length-1;j>=0;--j){if(!d[j].hidden){b(d[j]);return}}b(null)};return{zseed:9000,register:function(i){if(i.manager){i.manager.unregister(i)}i.manager=this;g[i.id]=i;d.push(i);i.on("hide",a)},unregister:function(i){delete i.manager;delete g[i.id];i.un("hide",a);d.remove(i)},get:function(i){return typeof i=="object"?i:g[i]},bringToFront:function(i){i=this.get(i);if(i!=e){i._lastAccess=new Date().getTime();h();return true}return false},sendToBack:function(i){i=this.get(i);i._lastAccess=-(new Date().getTime());h();return i},hideAll:function(){for(var i in g){if(g[i]&&typeof g[i]!="function"&&g[i].isVisible()){g[i].hide()}}},getActive:function(){return e},getBy:function(l,k){var m=[];for(var j=d.length-1;j>=0;--j){var n=d[j];if(l.call(k||n,n)!==false){m.push(n)}}return m},each:function(j,i){for(var k in g){if(g[k]&&typeof g[k]!="function"){if(j.call(i||g[k],g[k])===false){return}}}}}};Ext.WindowMgr=new Ext.WindowGroup();Ext.MessageBox=function(){var u,b,q,t,h,l,s,a,n,p,j,g,r,v,o,i="",d="",m=["ok","yes","no","cancel"];var c=function(x){r[x].blur();if(u.isVisible()){u.hide();w();Ext.callback(b.fn,b.scope||window,[x,v.dom.value,b],1)}};var w=function(){if(b&&b.cls){u.el.removeClass(b.cls)}n.reset()};var e=function(z,x,y){if(b&&b.closable!==false){u.hide();w()}if(y){y.stopEvent()}};var k=function(x){var z=0,y;if(!x){Ext.each(m,function(A){r[A].hide()});return z}u.footer.dom.style.display="";Ext.iterate(r,function(A,B){y=x[A];if(y){B.show();B.setText(Ext.isString(y)?y:Ext.MessageBox.buttonText[A]);z+=B.getEl().getWidth()+15}else{B.hide()}});return z};return{getDialog:function(x){if(!u){var z=[];r={};Ext.each(m,function(A){z.push(r[A]=new Ext.Button({text:this.buttonText[A],handler:c.createCallback(A),hideMode:"offsets"}))},this);u=new Ext.Window({autoCreate:true,title:x,resizable:false,constrain:true,constrainHeader:true,minimizable:false,maximizable:false,stateful:false,modal:true,shim:true,buttonAlign:"center",width:400,height:100,minHeight:80,plain:true,footer:true,closable:true,close:function(){if(b&&b.buttons&&b.buttons.no&&!b.buttons.cancel){c("no")}else{c("cancel")}},fbar:new Ext.Toolbar({items:z,enableOverflow:false})});u.render(document.body);u.getEl().addClass("x-window-dlg");q=u.mask;h=u.body.createChild({html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'});j=Ext.get(h.dom.firstChild);var y=h.dom.childNodes[1];l=Ext.get(y.firstChild);s=Ext.get(y.childNodes[2].firstChild);s.enableDisplayMode();s.addKeyListener([10,13],function(){if(u.isVisible()&&b&&b.buttons){if(b.buttons.ok){c("ok")}else{if(b.buttons.yes){c("yes")}}}});a=Ext.get(y.childNodes[2].childNodes[1]);a.enableDisplayMode();n=new Ext.ProgressBar({renderTo:h});h.createChild({cls:"x-clear"})}return u},updateText:function(A){if(!u.isVisible()&&!b.width){u.setSize(this.maxWidth,100)}l.update(A?A+" ":"&#160;");var y=d!=""?(j.getWidth()+j.getMargins("lr")):0,C=l.getWidth()+l.getMargins("lr"),z=u.getFrameWidth("lr"),B=u.body.getFrameWidth("lr"),x;x=Math.max(Math.min(b.width||y+C+z+B,b.maxWidth||this.maxWidth),Math.max(b.minWidth||this.minWidth,o||0));if(b.prompt===true){v.setWidth(x-y-z-B)}if(b.progress===true||b.wait===true){n.setSize(x-y-z-B)}if(Ext.isIE9m&&x==o){x+=4}l.update(A||"&#160;");u.setSize(x,"auto").center();return this},updateProgress:function(y,x,z){n.updateProgress(y,x);if(z){this.updateText(z)}return this},isVisible:function(){return u&&u.isVisible()},hide:function(){var x=u?u.activeGhost:null;if(this.isVisible()||x){u.hide();w();if(x){u.unghost(false,false)}}return this},show:function(A){if(this.isVisible()){this.hide()}b=A;var B=this.getDialog(b.title||"&#160;");B.setTitle(b.title||"&#160;");var x=(b.closable!==false&&b.progress!==true&&b.wait!==true);B.tools.close.setDisplayed(x);v=s;b.prompt=b.prompt||(b.multiline?true:false);if(b.prompt){if(b.multiline){s.hide();a.show();a.setHeight(Ext.isNumber(b.multiline)?b.multiline:this.defaultTextHeight);v=a}else{s.show();a.hide()}}else{s.hide();a.hide()}v.dom.value=b.value||"";if(b.prompt){B.focusEl=v}else{var z=b.buttons;var y=null;if(z&&z.ok){y=r.ok}else{if(z&&z.yes){y=r.yes}}if(y){B.focusEl=y}}if(Ext.isDefined(b.iconCls)){B.setIconClass(b.iconCls)}this.setIcon(Ext.isDefined(b.icon)?b.icon:i);o=k(b.buttons);n.setVisible(b.progress===true||b.wait===true);this.updateProgress(0,b.progressText);this.updateText(b.msg);if(b.cls){B.el.addClass(b.cls)}B.proxyDrag=b.proxyDrag===true;B.modal=b.modal!==false;B.mask=b.modal!==false?q:false;if(!B.isVisible()){document.body.appendChild(u.el.dom);B.setAnimateTarget(b.animEl);B.on("show",function(){if(x===true){B.keyMap.enable()}else{B.keyMap.disable()}},this,{single:true});B.show(b.animEl)}if(b.wait===true){n.wait(b.waitConfig)}return this},setIcon:function(x){if(!u){i=x;return}i=undefined;if(x&&x!=""){j.removeClass("x-hidden");j.replaceClass(d,x);h.addClass("x-dlg-icon");d=x}else{j.replaceClass(d,"x-hidden");h.removeClass("x-dlg-icon");d=""}return this},progress:function(z,y,x){this.show({title:z,msg:y,buttons:false,progress:true,closable:false,minWidth:this.minProgressWidth,progressText:x});return this},wait:function(z,y,x){this.show({title:y,msg:z,buttons:false,closable:false,wait:true,modal:true,minWidth:this.minProgressWidth,waitConfig:x});return this},alert:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.OK,fn:y,scope:x,minWidth:this.minWidth});return this},confirm:function(A,z,y,x){this.show({title:A,msg:z,buttons:this.YESNO,fn:y,scope:x,icon:this.QUESTION,minWidth:this.minWidth});return this},prompt:function(C,B,z,y,x,A){this.show({title:C,msg:B,buttons:this.OKCANCEL,fn:z,minWidth:this.minPromptWidth,scope:y,prompt:true,multiline:x,value:A});return this},OK:{ok:true},CANCEL:{cancel:true},OKCANCEL:{ok:true,cancel:true},YESNO:{yes:true,no:true},YESNOCANCEL:{yes:true,no:true,cancel:true},INFO:"ext-mb-info",WARNING:"ext-mb-warning",QUESTION:"ext-mb-question",ERROR:"ext-mb-error",defaultTextHeight:75,maxWidth:600,minWidth:100,minProgressWidth:250,minPromptWidth:250,buttonText:{ok:"OK",cancel:"Cancel",yes:"Yes",no:"No"}}}();Ext.Msg=Ext.MessageBox;Ext.dd.PanelProxy=Ext.extend(Object,{constructor:function(a,b){this.panel=a;this.id=this.panel.id+"-ddproxy";Ext.apply(this,b)},insertProxy:true,setStatus:Ext.emptyFn,reset:Ext.emptyFn,update:Ext.emptyFn,stop:Ext.emptyFn,sync:Ext.emptyFn,getEl:function(){return this.ghost},getGhost:function(){return this.ghost},getProxy:function(){return this.proxy},hide:function(){if(this.ghost){if(this.proxy){this.proxy.remove();delete this.proxy}this.panel.el.dom.style.display="";this.ghost.remove();delete this.ghost}},show:function(){if(!this.ghost){this.ghost=this.panel.createGhost(this.panel.initialConfig.cls,undefined,Ext.getBody());this.ghost.setXY(this.panel.el.getXY());if(this.insertProxy){this.proxy=this.panel.el.insertSibling({cls:"x-panel-dd-spacer"});this.proxy.setSize(this.panel.getSize())}this.panel.el.dom.style.display="none"}},repair:function(b,c,a){this.hide();if(typeof c=="function"){c.call(a||this)}},moveProxy:function(a,b){if(this.proxy){a.insertBefore(this.proxy.dom,b)}}});Ext.Panel.DD=Ext.extend(Ext.dd.DragSource,{constructor:function(b,a){this.panel=b;this.dragData={panel:b};this.proxy=new Ext.dd.PanelProxy(b,a);Ext.Panel.DD.superclass.constructor.call(this,b.el,a);var d=b.header,c=b.body;if(d){this.setHandleElId(d.id);c=b.header}c.setStyle("cursor","move");this.scroll=false},showFrame:Ext.emptyFn,startDrag:Ext.emptyFn,b4StartDrag:function(a,b){this.proxy.show()},b4MouseDown:function(b){var a=b.getPageX(),c=b.getPageY();this.autoOffset(a,c)},onInitDrag:function(a,b){this.onStartDrag(a,b);return true},createFrame:Ext.emptyFn,getDragEl:function(a){return this.proxy.ghost.dom},endDrag:function(a){this.proxy.hide();this.panel.saveState()},autoOffset:function(a,b){a-=this.startPageX;b-=this.startPageY;this.setDelta(a,b)}});Ext.state.Provider=Ext.extend(Ext.util.Observable,{constructor:function(){this.addEvents("statechange");this.state={};Ext.state.Provider.superclass.constructor.call(this)},get:function(b,a){return typeof this.state[b]=="undefined"?a:this.state[b]},clear:function(a){delete this.state[a];this.fireEvent("statechange",this,a,null)},set:function(a,b){this.state[a]=b;this.fireEvent("statechange",this,a,b)},decodeValue:function(b){var e=/^(a|n|d|b|s|o|e)\:(.*)$/,h=e.exec(unescape(b)),d,c,a,g;if(!h||!h[1]){return}c=h[1];a=h[2];switch(c){case"e":return null;case"n":return parseFloat(a);case"d":return new Date(Date.parse(a));case"b":return(a=="1");case"a":d=[];if(a!=""){Ext.each(a.split("^"),function(i){d.push(this.decodeValue(i))},this)}return d;case"o":d={};if(a!=""){Ext.each(a.split("^"),function(i){g=i.split("=");d[g[0]]=this.decodeValue(g[1])},this)}return d;default:return a}},encodeValue:function(c){var b,g="",e=0,a,d;if(c==null){return"e:1"}else{if(typeof c=="number"){b="n:"+c}else{if(typeof c=="boolean"){b="b:"+(c?"1":"0")}else{if(Ext.isDate(c)){b="d:"+c.toGMTString()}else{if(Ext.isArray(c)){for(a=c.length;e<a;e++){g+=this.encodeValue(c[e]);if(e!=a-1){g+="^"}}b="a:"+g}else{if(typeof c=="object"){for(d in c){if(typeof c[d]!="function"&&c[d]!==undefined){g+=d+"="+this.encodeValue(c[d])+"^"}}b="o:"+g.substring(0,g.length-1)}else{b="s:"+c}}}}}}return escape(b)}});Ext.state.Manager=function(){var a=new Ext.state.Provider();return{setProvider:function(b){a=b},get:function(c,b){return a.get(c,b)},set:function(b,c){a.set(b,c)},clear:function(b){a.clear(b)},getProvider:function(){return a}}}();Ext.state.CookieProvider=Ext.extend(Ext.state.Provider,{constructor:function(a){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,a);this.state=this.readCookies()},set:function(a,b){if(typeof b=="undefined"||b===null){this.clear(a);return}this.setCookie(a,b);Ext.state.CookieProvider.superclass.set.call(this,a,b)},clear:function(a){this.clearCookie(a);Ext.state.CookieProvider.superclass.clear.call(this,a)},readCookies:function(){var d={},h=document.cookie+";",b=/\s?(.*?)=(.*?);/g,g,a,e;while((g=b.exec(h))!=null){a=g[1];e=g[2];if(a&&a.substring(0,3)=="ys-"){d[a.substr(3)]=this.decodeValue(e)}}return d},setCookie:function(a,b){document.cookie="ys-"+a+"="+this.encodeValue(b)+((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(a){document.cookie="ys-"+a+"=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":"")}});Ext.DataView=Ext.extend(Ext.BoxComponent,{selectedClass:"x-view-selected",emptyText:"",deferEmptyText:true,trackOver:false,blockRefresh:false,last:false,initComponent:function(){Ext.DataView.superclass.initComponent.call(this);if(Ext.isString(this.tpl)||Ext.isArray(this.tpl)){this.tpl=new Ext.XTemplate(this.tpl)}this.addEvents("beforeclick","click","mouseenter","mouseleave","containerclick","dblclick","contextmenu","containercontextmenu","selectionchange","beforeselect");this.store=Ext.StoreMgr.lookup(this.store);this.all=new Ext.CompositeElementLite();this.selected=new Ext.CompositeElementLite()},afterRender:function(){Ext.DataView.superclass.afterRender.call(this);this.mon(this.getTemplateTarget(),{click:this.onClick,dblclick:this.onDblClick,contextmenu:this.onContextMenu,scope:this});if(this.overClass||this.trackOver){this.mon(this.getTemplateTarget(),{mouseover:this.onMouseOver,mouseout:this.onMouseOut,scope:this})}if(this.store){this.bindStore(this.store,true)}},refresh:function(){this.clearSelections(false,true);var b=this.getTemplateTarget(),a=this.store.getRange();b.update("");if(a.length<1){if(!this.deferEmptyText||this.hasSkippedEmptyText){b.update(this.emptyText)}this.all.clear()}else{this.tpl.overwrite(b,this.collectData(a,0));this.all.fill(Ext.query(this.itemSelector,b.dom));this.updateIndexes(0)}this.hasSkippedEmptyText=true},getTemplateTarget:function(){return this.el},prepareData:function(a){return a},collectData:function(b,e){var d=[],c=0,a=b.length;for(;c<a;c++){d[d.length]=this.prepareData(b[c].data,e+c,b[c])}return d},bufferRender:function(a,b){var c=document.createElement("div");this.tpl.overwrite(c,this.collectData(a,b));return Ext.query(this.itemSelector,c)},onUpdate:function(g,a){var b=this.store.indexOf(a);if(b>-1){var e=this.isSelected(b),c=this.all.elements[b],d=this.bufferRender([a],b)[0];this.all.replaceElement(b,d,true);if(e){this.selected.replaceElement(c,d);this.all.item(b).addClass(this.selectedClass)}this.updateIndexes(b,b)}},onAdd:function(g,d,e){if(this.all.getCount()===0){this.refresh();return}var c=this.bufferRender(d,e),h,b=this.all.elements;if(e<this.all.getCount()){h=this.all.item(e).insertSibling(c,"before",true);b.splice.apply(b,[e,0].concat(c))}else{h=this.all.last().insertSibling(c,"after",true);b.push.apply(b,c)}this.updateIndexes(e)},onRemove:function(c,a,b){this.deselect(b);this.all.removeElement(b,true);this.updateIndexes(b);if(this.store.getCount()===0){this.refresh()}},refreshNode:function(a){this.onUpdate(this.store,this.store.getAt(a))},updateIndexes:function(d,c){var b=this.all.elements;d=d||0;c=c||((c===0)?0:(b.length-1));for(var a=d;a<=c;a++){b[a].viewIndex=a}},getStore:function(){return this.store},bindStore:function(a,b){if(!b&&this.store){if(a!==this.store&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("datachanged",this.onDataChanged,this);this.store.un("add",this.onAdd,this);this.store.un("remove",this.onRemove,this);this.store.un("update",this.onUpdate,this);this.store.un("clear",this.refresh,this)}if(!a){this.store=null}}if(a){a=Ext.StoreMgr.lookup(a);a.on({scope:this,beforeload:this.onBeforeLoad,datachanged:this.onDataChanged,add:this.onAdd,remove:this.onRemove,update:this.onUpdate,clear:this.refresh})}this.store=a;if(a){this.refresh()}},onDataChanged:function(){if(this.blockRefresh!==true){this.refresh.apply(this,arguments)}},findItemFromChild:function(a){return Ext.fly(a).findParent(this.itemSelector,this.getTemplateTarget())},onClick:function(c){var b=c.getTarget(this.itemSelector,this.getTemplateTarget()),a;if(b){a=this.indexOf(b);if(this.onItemClick(b,a,c)!==false){this.fireEvent("click",this,a,b,c)}}else{if(this.fireEvent("containerclick",this,c)!==false){this.onContainerClick(c)}}},onContainerClick:function(a){this.clearSelections()},onContextMenu:function(b){var a=b.getTarget(this.itemSelector,this.getTemplateTarget());if(a){this.fireEvent("contextmenu",this,this.indexOf(a),a,b)}else{this.fireEvent("containercontextmenu",this,b)}},onDblClick:function(b){var a=b.getTarget(this.itemSelector,this.getTemplateTarget());if(a){this.fireEvent("dblclick",this,this.indexOf(a),a,b)}},onMouseOver:function(b){var a=b.getTarget(this.itemSelector,this.getTemplateTarget());if(a&&a!==this.lastItem){this.lastItem=a;Ext.fly(a).addClass(this.overClass);this.fireEvent("mouseenter",this,this.indexOf(a),a,b)}},onMouseOut:function(a){if(this.lastItem){if(!a.within(this.lastItem,true,true)){Ext.fly(this.lastItem).removeClass(this.overClass);this.fireEvent("mouseleave",this,this.indexOf(this.lastItem),this.lastItem,a);delete this.lastItem}}},onItemClick:function(b,a,c){if(this.fireEvent("beforeclick",this,a,b,c)===false){return false}if(this.multiSelect){this.doMultiSelection(b,a,c);c.preventDefault()}else{if(this.singleSelect){this.doSingleSelection(b,a,c);c.preventDefault()}}return true},doSingleSelection:function(b,a,c){if(c.ctrlKey&&this.isSelected(a)){this.deselect(a)}else{this.select(a,false)}},doMultiSelection:function(c,a,d){if(d.shiftKey&&this.last!==false){var b=this.last;this.selectRange(b,a,d.ctrlKey);this.last=b}else{if((d.ctrlKey||this.simpleSelect)&&this.isSelected(a)){this.deselect(a)}else{this.select(a,d.ctrlKey||d.shiftKey||this.simpleSelect)}}},getSelectionCount:function(){return this.selected.getCount()},getSelectedNodes:function(){return this.selected.elements},getSelectedIndexes:function(){var b=[],d=this.selected.elements,c=0,a=d.length;for(;c<a;c++){b.push(d[c].viewIndex)}return b},getSelectedRecords:function(){return this.getRecords(this.selected.elements)},getRecords:function(c){var b=[],d=0,a=c.length;for(;d<a;d++){b[b.length]=this.store.getAt(c[d].viewIndex)}return b},getRecord:function(a){return this.store.getAt(a.viewIndex)},clearSelections:function(a,b){if((this.multiSelect||this.singleSelect)&&this.selected.getCount()>0){if(!b){this.selected.removeClass(this.selectedClass)}this.selected.clear();this.last=false;if(!a){this.fireEvent("selectionchange",this,this.selected.elements)}}},isSelected:function(a){return this.selected.contains(this.getNode(a))},deselect:function(a){if(this.isSelected(a)){a=this.getNode(a);this.selected.removeElement(a);if(this.last==a.viewIndex){this.last=false}Ext.fly(a).removeClass(this.selectedClass);this.fireEvent("selectionchange",this,this.selected.elements)}},select:function(d,g,b){if(Ext.isArray(d)){if(!g){this.clearSelections(true)}for(var c=0,a=d.length;c<a;c++){this.select(d[c],true,true)}if(!b){this.fireEvent("selectionchange",this,this.selected.elements)}}else{var e=this.getNode(d);if(!g){this.clearSelections(true)}if(e&&!this.isSelected(e)){if(this.fireEvent("beforeselect",this,e,this.selected.elements)!==false){Ext.fly(e).addClass(this.selectedClass);this.selected.add(e);this.last=e.viewIndex;if(!b){this.fireEvent("selectionchange",this,this.selected.elements)}}}}},selectRange:function(c,a,b){if(!b){this.clearSelections(true)}this.select(this.getNodes(c,a),true)},getNode:function(b){if(Ext.isString(b)){return document.getElementById(b)}else{if(Ext.isNumber(b)){return this.all.elements[b]}else{if(b instanceof Ext.data.Record){var a=this.store.indexOf(b);return this.all.elements[a]}}}return b},getNodes:function(e,a){var d=this.all.elements,b=[],c;e=e||0;a=!Ext.isDefined(a)?Math.max(d.length-1,0):a;if(e<=a){for(c=e;c<=a&&d[c];c++){b.push(d[c])}}else{for(c=e;c>=a&&d[c];c--){b.push(d[c])}}return b},indexOf:function(a){a=this.getNode(a);if(Ext.isNumber(a.viewIndex)){return a.viewIndex}return this.all.indexOf(a)},onBeforeLoad:function(){if(this.loadingText){this.clearSelections(false,true);this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+"</div>");this.all.clear()}},onDestroy:function(){this.all.clear();this.selected.clear();Ext.DataView.superclass.onDestroy.call(this);this.bindStore(null)}});Ext.DataView.prototype.setStore=Ext.DataView.prototype.bindStore;Ext.reg("dataview",Ext.DataView);Ext.list.ListView=Ext.extend(Ext.DataView,{itemSelector:"dl",selectedClass:"x-list-selected",overClass:"x-list-over",scrollOffset:undefined,columnResize:true,columnSort:true,maxColumnWidth:Ext.isIE9m?99:100,initComponent:function(){if(this.columnResize){this.colResizer=new Ext.list.ColumnResizer(this.colResizer);this.colResizer.init(this)}if(this.columnSort){this.colSorter=new Ext.list.Sorter(this.columnSort);this.colSorter.init(this)}if(!this.internalTpl){this.internalTpl=new Ext.XTemplate('<div class="x-list-header"><div class="x-list-header-inner">','<tpl for="columns">','<div style="width:{[values.width*100]}%;text-align:{align};"><em class="x-unselectable" unselectable="on" id="',this.id,'-xlhd-{#}">',"{header}","</em></div>","</tpl>",'<div class="x-clear"></div>',"</div></div>",'<div class="x-list-body"><div class="x-list-body-inner">',"</div></div>")}if(!this.tpl){this.tpl=new Ext.XTemplate('<tpl for="rows">',"<dl>",'<tpl for="parent.columns">','<dt style="width:{[values.width*100]}%;text-align:{align};">','<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',"{[values.tpl.apply(parent)]}","</em></dt>","</tpl>",'<div class="x-clear"></div>',"</dl>","</tpl>")}var l=this.columns,h=0,k=0,m=l.length,b=[];for(var g=0;g<m;g++){var n=l[g];if(!n.isColumn){n.xtype=n.xtype?(/^lv/.test(n.xtype)?n.xtype:"lv"+n.xtype):"lvcolumn";n=Ext.create(n)}if(n.width){h+=n.width*100;if(h>this.maxColumnWidth){n.width-=(h-this.maxColumnWidth)/100}k++}b.push(n)}l=this.columns=b;if(k<m){var d=m-k;if(h<this.maxColumnWidth){var a=((this.maxColumnWidth-h)/d)/100;for(var e=0;e<m;e++){var n=l[e];if(!n.width){n.width=a}}}}Ext.list.ListView.superclass.initComponent.call(this)},onRender:function(){this.autoEl={cls:"x-list-wrap"};Ext.list.ListView.superclass.onRender.apply(this,arguments);this.internalTpl.overwrite(this.el,{columns:this.columns});this.innerBody=Ext.get(this.el.dom.childNodes[1].firstChild);this.innerHd=Ext.get(this.el.dom.firstChild.firstChild);if(this.hideHeaders){this.el.dom.firstChild.style.display="none"}},getTemplateTarget:function(){return this.innerBody},collectData:function(){var a=Ext.list.ListView.superclass.collectData.apply(this,arguments);return{columns:this.columns,rows:a}},verifyInternalSize:function(){if(this.lastSize){this.onResize(this.lastSize.width,this.lastSize.height)}},onResize:function(c,e){var b=this.innerBody.dom,g=this.innerHd.dom,d=c-Ext.num(this.scrollOffset,Ext.getScrollBarWidth())+"px",a;if(!b){return}a=b.parentNode;if(Ext.isNumber(c)){if(this.reserveScrollOffset||((a.offsetWidth-a.clientWidth)>10)){b.style.width=d;g.style.width=d}else{b.style.width=c+"px";g.style.width=c+"px";setTimeout(function(){if((a.offsetWidth-a.clientWidth)>10){b.style.width=d;g.style.width=d}},10)}}if(Ext.isNumber(e)){a.style.height=Math.max(0,e-g.parentNode.offsetHeight)+"px"}},updateIndexes:function(){Ext.list.ListView.superclass.updateIndexes.apply(this,arguments);this.verifyInternalSize()},findHeaderIndex:function(g){g=g.dom||g;var a=g.parentNode,d=a.parentNode.childNodes,b=0,e;for(;e=d[b];b++){if(e==a){return b}}return -1},setHdWidths:function(){var d=this.innerHd.dom.getElementsByTagName("div"),c=0,b=this.columns,a=b.length;for(;c<a;c++){d[c].style.width=(b[c].width*100)+"%"}}});Ext.reg("listview",Ext.list.ListView);Ext.ListView=Ext.list.ListView;Ext.list.Column=Ext.extend(Object,{isColumn:true,align:"left",header:"",width:null,cls:"",constructor:function(a){if(!a.tpl){a.tpl=new Ext.XTemplate("{"+a.dataIndex+"}")}else{if(Ext.isString(a.tpl)){a.tpl=new Ext.XTemplate(a.tpl)}}Ext.apply(this,a)}});Ext.reg("lvcolumn",Ext.list.Column);Ext.list.NumberColumn=Ext.extend(Ext.list.Column,{format:"0,000.00",constructor:function(a){a.tpl=a.tpl||new Ext.XTemplate("{"+a.dataIndex+':number("'+(a.format||this.format)+'")}');Ext.list.NumberColumn.superclass.constructor.call(this,a)}});Ext.reg("lvnumbercolumn",Ext.list.NumberColumn);Ext.list.DateColumn=Ext.extend(Ext.list.Column,{format:"m/d/Y",constructor:function(a){a.tpl=a.tpl||new Ext.XTemplate("{"+a.dataIndex+':date("'+(a.format||this.format)+'")}');Ext.list.DateColumn.superclass.constructor.call(this,a)}});Ext.reg("lvdatecolumn",Ext.list.DateColumn);Ext.list.BooleanColumn=Ext.extend(Ext.list.Column,{trueText:"true",falseText:"false",undefinedText:"&#160;",constructor:function(e){e.tpl=e.tpl||new Ext.XTemplate("{"+e.dataIndex+":this.format}");var b=this.trueText,d=this.falseText,a=this.undefinedText;e.tpl.format=function(c){if(c===undefined){return a}if(!c||c==="false"){return d}return b};Ext.list.DateColumn.superclass.constructor.call(this,e)}});Ext.reg("lvbooleancolumn",Ext.list.BooleanColumn);Ext.list.ColumnResizer=Ext.extend(Ext.util.Observable,{minPct:0.05,constructor:function(a){Ext.apply(this,a);Ext.list.ColumnResizer.superclass.constructor.call(this)},init:function(a){this.view=a;a.on("render",this.initEvents,this)},initEvents:function(a){a.mon(a.innerHd,"mousemove",this.handleHdMove,this);this.tracker=new Ext.dd.DragTracker({onBeforeStart:this.onBeforeStart.createDelegate(this),onStart:this.onStart.createDelegate(this),onDrag:this.onDrag.createDelegate(this),onEnd:this.onEnd.createDelegate(this),tolerance:3,autoStart:300});this.tracker.initEl(a.innerHd);a.on("beforedestroy",this.tracker.destroy,this.tracker)},handleHdMove:function(i,d){var c=5,b=i.getPageX(),j=i.getTarget("em",3,true);if(j){var h=j.getRegion(),g=j.dom.style,a=j.dom.parentNode;if(b-h.left<=c&&a!=a.parentNode.firstChild){this.activeHd=Ext.get(a.previousSibling.firstChild);g.cursor=Ext.isWebKit?"e-resize":"col-resize"}else{if(h.right-b<=c&&a!=a.parentNode.lastChild.previousSibling){this.activeHd=j;g.cursor=Ext.isWebKit?"w-resize":"col-resize"}else{delete this.activeHd;g.cursor=""}}}},onBeforeStart:function(a){this.dragHd=this.activeHd;return !!this.dragHd},onStart:function(g){var d=this,b=d.view,c=d.dragHd,a=d.tracker.getXY()[0];d.proxy=b.el.createChild({cls:"x-list-resizer"});d.dragX=c.getX();d.headerIndex=b.findHeaderIndex(c);d.headersDisabled=b.disableHeaders;b.disableHeaders=true;d.proxy.setHeight(b.el.getHeight());d.proxy.setX(d.dragX);d.proxy.setWidth(a-d.dragX);this.setBoundaries()},setBoundaries:function(j){var k=this.view,h=this.headerIndex,c=k.innerHd.getWidth(),j=k.innerHd.getX(),b=Math.ceil(c*this.minPct),l=c-b,e=k.columns.length,d=k.innerHd.select("em",true),g=b+j,a=l+j,i;if(e==2){this.minX=g;this.maxX=a}else{i=d.item(h+2);this.minX=d.item(h).getX()+b;this.maxX=i?i.getX()-b:a;if(h==0){this.minX=g}else{if(h==e-2){this.maxX=a}}}},onDrag:function(c){var b=this,a=b.tracker.getXY()[0].constrain(b.minX,b.maxX);b.proxy.setWidth(a-this.dragX)},onEnd:function(i){var g=this.proxy.getWidth(),h=this.headerIndex,l=this.view,c=l.columns,b=l.innerHd.getWidth(),k=Math.ceil(g*l.maxColumnWidth/b)/100,d=this.headersDisabled,m=c[h],j=c[h+1],a=m.width+j.width;this.proxy.remove();m.width=k;j.width=a-k;delete this.dragHd;l.setHdWidths();l.refresh();setTimeout(function(){l.disableHeaders=d},100)}});Ext.ListView.ColumnResizer=Ext.list.ColumnResizer;Ext.list.Sorter=Ext.extend(Ext.util.Observable,{sortClasses:["sort-asc","sort-desc"],constructor:function(a){Ext.apply(this,a);Ext.list.Sorter.superclass.constructor.call(this)},init:function(a){this.view=a;a.on("render",this.initEvents,this)},initEvents:function(a){a.mon(a.innerHd,"click",this.onHdClick,this);a.innerHd.setStyle("cursor","pointer");a.mon(a.store,"datachanged",this.updateSortState,this);this.updateSortState.defer(10,this,[a.store])},updateSortState:function(c){var g=c.getSortState();if(!g){return}this.sortState=g;var e=this.view.columns,h=-1;for(var d=0,a=e.length;d<a;d++){if(e[d].dataIndex==g.field){h=d;break}}if(h!=-1){var b=g.direction;this.updateSortIcon(h,b)}},updateSortIcon:function(b,a){var d=this.sortClasses;var c=this.view.innerHd.select("em").removeClass(d);c.item(b).addClass(d[a=="DESC"?1:0])},onHdClick:function(c){var b=c.getTarget("em",3);if(b&&!this.view.disableHeaders){var a=this.view.findHeaderIndex(b);this.view.store.sort(this.view.columns[a].dataIndex)}}});Ext.ListView.Sorter=Ext.list.Sorter;Ext.TabPanel=Ext.extend(Ext.Panel,{deferredRender:true,tabWidth:120,minTabWidth:30,resizeTabs:false,enableTabScroll:false,scrollIncrement:0,scrollRepeatInterval:400,scrollDuration:0.35,animScroll:true,tabPosition:"top",baseCls:"x-tab-panel",autoTabs:false,autoTabSelector:"div.x-tab",activeTab:undefined,tabMargin:2,plain:false,wheelIncrement:20,idDelimiter:"__",itemCls:"x-tab-item",elements:"body",headerAsText:false,frame:false,hideBorders:true,initComponent:function(){this.frame=false;Ext.TabPanel.superclass.initComponent.call(this);this.addEvents("beforetabchange","tabchange","contextmenu");this.setLayout(new Ext.layout.CardLayout(Ext.apply({layoutOnCardChange:this.layoutOnTabChange,deferredRender:this.deferredRender},this.layoutConfig)));if(this.tabPosition=="top"){this.elements+=",header";this.stripTarget="header"}else{this.elements+=",footer";this.stripTarget="footer"}if(!this.stack){this.stack=Ext.TabPanel.AccessStack()}this.initItems()},onRender:function(c,a){Ext.TabPanel.superclass.onRender.call(this,c,a);if(this.plain){var g=this.tabPosition=="top"?"header":"footer";this[g].addClass("x-tab-panel-"+g+"-plain")}var b=this[this.stripTarget];this.stripWrap=b.createChild({cls:"x-tab-strip-wrap",cn:{tag:"ul",cls:"x-tab-strip x-tab-strip-"+this.tabPosition}});var e=(this.tabPosition=="bottom"?this.stripWrap:null);b.createChild({cls:"x-tab-strip-spacer"},e);this.strip=new Ext.Element(this.stripWrap.dom.firstChild);this.edge=this.strip.createChild({tag:"li",cls:"x-tab-edge",cn:[{tag:"span",cls:"x-tab-strip-text",cn:"&#160;"}]});this.strip.createChild({cls:"x-clear"});this.body.addClass("x-tab-panel-body-"+this.tabPosition);if(!this.itemTpl){var d=new Ext.Template('<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>','<a class="x-tab-right" href="#"><em class="x-tab-left">','<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',"</em></a></li>");d.disableFormats=true;d.compile();Ext.TabPanel.prototype.itemTpl=d}this.items.each(this.initTab,this)},afterRender:function(){Ext.TabPanel.superclass.afterRender.call(this);if(this.autoTabs){this.readTabs(false)}if(this.activeTab!==undefined){var a=Ext.isObject(this.activeTab)?this.activeTab:this.items.get(this.activeTab);delete this.activeTab;this.setActiveTab(a)}},initEvents:function(){Ext.TabPanel.superclass.initEvents.call(this);this.mon(this.strip,{scope:this,mousedown:this.onStripMouseDown,contextmenu:this.onStripContextMenu});if(this.enableTabScroll){this.mon(this.strip,"mousewheel",this.onWheel,this)}},findTargets:function(c){var b=null,a=c.getTarget("li:not(.x-tab-edge)",this.strip);if(a){b=this.getComponent(a.id.split(this.idDelimiter)[1]);if(b.disabled){return{close:null,item:null,el:null}}}return{close:c.getTarget(".x-tab-strip-close",this.strip),item:b,el:a}},onStripMouseDown:function(b){if(b.button!==0){return}b.preventDefault();var a=this.findTargets(b);if(a.close){if(a.item.fireEvent("beforeclose",a.item)!==false){a.item.fireEvent("close",a.item);this.remove(a.item)}return}if(a.item&&a.item!=this.activeTab){this.setActiveTab(a.item)}},onStripContextMenu:function(b){b.preventDefault();var a=this.findTargets(b);if(a.item){this.fireEvent("contextmenu",this,a.item,b)}},readTabs:function(d){if(d===true){this.items.each(function(h){this.remove(h)},this)}var c=this.el.query(this.autoTabSelector);for(var b=0,a=c.length;b<a;b++){var e=c[b],g=e.getAttribute("title");e.removeAttribute("title");this.add({title:g,contentEl:e})}},initTab:function(d,b){var e=this.strip.dom.childNodes[b],g=this.getTemplateArgs(d),c=e?this.itemTpl.insertBefore(e,g):this.itemTpl.append(this.strip,g),a="x-tab-strip-over",h=Ext.get(c);h.hover(function(){if(!d.disabled){h.addClass(a)}},function(){h.removeClass(a)});if(d.tabTip){h.child("span.x-tab-strip-text",true).qtip=d.tabTip}d.tabEl=c;h.select("a").on("click",function(i){if(!i.getPageX()){this.onStripMouseDown(i)}},this,{preventDefault:true});d.on({scope:this,disable:this.onItemDisabled,enable:this.onItemEnabled,titlechange:this.onItemTitleChanged,iconchange:this.onItemIconChanged,beforeshow:this.onBeforeShowItem})},getTemplateArgs:function(b){var a=b.closable?"x-tab-strip-closable":"";if(b.disabled){a+=" x-item-disabled"}if(b.iconCls){a+=" x-tab-with-icon"}if(b.tabCls){a+=" "+b.tabCls}return{id:this.id+this.idDelimiter+b.getItemId(),text:b.title,cls:a,iconCls:b.iconCls||""}},onAdd:function(b){Ext.TabPanel.superclass.onAdd.call(this,b);if(this.rendered){var a=this.items;this.initTab(b,a.indexOf(b));this.delegateUpdates()}},onBeforeAdd:function(b){var a=b.events?(this.items.containsKey(b.getItemId())?b:null):this.items.get(b);if(a){this.setActiveTab(b);return false}Ext.TabPanel.superclass.onBeforeAdd.apply(this,arguments);var c=b.elements;b.elements=c?c.replace(",header",""):c;b.border=(b.border===true)},onRemove:function(d){var b=Ext.get(d.tabEl);if(b){b.select("a").removeAllListeners();Ext.destroy(b)}Ext.TabPanel.superclass.onRemove.call(this,d);this.stack.remove(d);delete d.tabEl;d.un("disable",this.onItemDisabled,this);d.un("enable",this.onItemEnabled,this);d.un("titlechange",this.onItemTitleChanged,this);d.un("iconchange",this.onItemIconChanged,this);d.un("beforeshow",this.onBeforeShowItem,this);if(d==this.activeTab){var a=this.stack.next();if(a){this.setActiveTab(a)}else{if(this.items.getCount()>0){this.setActiveTab(0)}else{this.setActiveTab(null)}}}if(!this.destroying){this.delegateUpdates()}},onBeforeShowItem:function(a){if(a!=this.activeTab){this.setActiveTab(a);return false}},onItemDisabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).addClass("x-item-disabled")}this.stack.remove(b)},onItemEnabled:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).removeClass("x-item-disabled")}},onItemTitleChanged:function(b){var a=this.getTabEl(b);if(a){Ext.fly(a).child("span.x-tab-strip-text",true).innerHTML=b.title;this.delegateUpdates()}},onItemIconChanged:function(d,a,c){var b=this.getTabEl(d);if(b){b=Ext.get(b);b.child("span.x-tab-strip-text").replaceClass(c,a);b[Ext.isEmpty(a)?"removeClass":"addClass"]("x-tab-with-icon");this.delegateUpdates()}},getTabEl:function(a){var b=this.getComponent(a);return b?b.tabEl:null},onResize:function(){Ext.TabPanel.superclass.onResize.apply(this,arguments);this.delegateUpdates()},beginUpdate:function(){this.suspendUpdates=true},endUpdate:function(){this.suspendUpdates=false;this.delegateUpdates()},hideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="none";this.delegateUpdates()}this.stack.remove(b)},unhideTabStripItem:function(b){b=this.getComponent(b);var a=this.getTabEl(b);if(a){a.style.display="";this.delegateUpdates()}},delegateUpdates:function(){var a=this.rendered;if(this.suspendUpdates){return}if(this.resizeTabs&&a){this.autoSizeTabs()}if(this.enableTabScroll&&a){this.autoScrollTabs()}},autoSizeTabs:function(){var h=this.items.length,b=this.tabPosition!="bottom"?"header":"footer",c=this[b].dom.offsetWidth,a=this[b].dom.clientWidth;if(!this.resizeTabs||h<1||!a){return}var k=Math.max(Math.min(Math.floor((a-4)/h)-this.tabMargin,this.tabWidth),this.minTabWidth);this.lastTabWidth=k;var m=this.strip.query("li:not(.x-tab-edge)");for(var e=0,j=m.length;e<j;e++){var l=m[e],n=Ext.fly(l).child(".x-tab-strip-inner",true),g=l.offsetWidth,d=n.offsetWidth;n.style.width=(k-(g-d))+"px"}},adjustBodyWidth:function(a){if(this.header){this.header.setWidth(a)}if(this.footer){this.footer.setWidth(a)}return a},setActiveTab:function(c){c=this.getComponent(c);if(this.fireEvent("beforetabchange",this,c,this.activeTab)===false){return}if(!this.rendered){this.activeTab=c;return}if(this.activeTab!=c){if(this.activeTab){var a=this.getTabEl(this.activeTab);if(a){Ext.fly(a).removeClass("x-tab-strip-active")}}this.activeTab=c;if(c){var b=this.getTabEl(c);Ext.fly(b).addClass("x-tab-strip-active");this.stack.add(c);this.layout.setActiveItem(c);this.delegateUpdates();if(this.scrolling){this.scrollToTab(c,this.animScroll)}}this.fireEvent("tabchange",this,c)}},getActiveTab:function(){return this.activeTab||null},getItem:function(a){return this.getComponent(a)},autoScrollTabs:function(){this.pos=this.tabPosition=="bottom"?this.footer:this.header;var h=this.items.length,d=this.pos.dom.offsetWidth,c=this.pos.dom.clientWidth,g=this.stripWrap,e=g.dom,b=e.offsetWidth,i=this.getScrollPos(),a=this.edge.getOffsetsTo(this.stripWrap)[0]+i;if(!this.enableTabScroll||b<20){return}if(h==0||a<=c){e.scrollLeft=0;g.setWidth(c);if(this.scrolling){this.scrolling=false;this.pos.removeClass("x-tab-scrolling");this.scrollLeft.hide();this.scrollRight.hide();if(Ext.isAir||Ext.isWebKit){e.style.marginLeft="";e.style.marginRight=""}}}else{if(!this.scrolling){this.pos.addClass("x-tab-scrolling");if(Ext.isAir||Ext.isWebKit){e.style.marginLeft="18px";e.style.marginRight="18px"}}c-=g.getMargins("lr");g.setWidth(c>20?c:20);if(!this.scrolling){if(!this.scrollLeft){this.createScrollers()}else{this.scrollLeft.show();this.scrollRight.show()}}this.scrolling=true;if(i>(a-c)){e.scrollLeft=a-c}else{this.scrollToTab(this.activeTab,false)}this.updateScrollButtons()}},createScrollers:function(){this.pos.addClass("x-tab-scrolling-"+this.tabPosition);var c=this.stripWrap.dom.offsetHeight;var a=this.pos.insertFirst({cls:"x-tab-scroller-left"});a.setHeight(c);a.addClassOnOver("x-tab-scroller-left-over");this.leftRepeater=new Ext.util.ClickRepeater(a,{interval:this.scrollRepeatInterval,handler:this.onScrollLeft,scope:this});this.scrollLeft=a;var b=this.pos.insertFirst({cls:"x-tab-scroller-right"});b.setHeight(c);b.addClassOnOver("x-tab-scroller-right-over");this.rightRepeater=new Ext.util.ClickRepeater(b,{interval:this.scrollRepeatInterval,handler:this.onScrollRight,scope:this});this.scrollRight=b},getScrollWidth:function(){return this.edge.getOffsetsTo(this.stripWrap)[0]+this.getScrollPos()},getScrollPos:function(){return parseInt(this.stripWrap.dom.scrollLeft,10)||0},getScrollArea:function(){return parseInt(this.stripWrap.dom.clientWidth,10)||0},getScrollAnim:function(){return{duration:this.scrollDuration,callback:this.updateScrollButtons,scope:this}},getScrollIncrement:function(){return this.scrollIncrement||(this.resizeTabs?this.lastTabWidth+2:100)},scrollToTab:function(e,a){if(!e){return}var c=this.getTabEl(e),h=this.getScrollPos(),d=this.getScrollArea(),g=Ext.fly(c).getOffsetsTo(this.stripWrap)[0]+h,b=g+c.offsetWidth;if(g<h){this.scrollTo(g,a)}else{if(b>(h+d)){this.scrollTo(b-d,a)}}},scrollTo:function(b,a){this.stripWrap.scrollTo("left",b,a?this.getScrollAnim():false);if(!a){this.updateScrollButtons()}},onWheel:function(g){var h=g.getWheelDelta()*this.wheelIncrement*-1;g.stopEvent();var i=this.getScrollPos(),c=i+h,a=this.getScrollWidth()-this.getScrollArea();var b=Math.max(0,Math.min(a,c));if(b!=i){this.scrollTo(b,false)}},onScrollRight:function(){var a=this.getScrollWidth()-this.getScrollArea(),c=this.getScrollPos(),b=Math.min(a,c+this.getScrollIncrement());if(b!=c){this.scrollTo(b,this.animScroll)}},onScrollLeft:function(){var b=this.getScrollPos(),a=Math.max(0,b-this.getScrollIncrement());if(a!=b){this.scrollTo(a,this.animScroll)}},updateScrollButtons:function(){var a=this.getScrollPos();this.scrollLeft[a===0?"addClass":"removeClass"]("x-tab-scroller-left-disabled");this.scrollRight[a>=(this.getScrollWidth()-this.getScrollArea())?"addClass":"removeClass"]("x-tab-scroller-right-disabled")},beforeDestroy:function(){Ext.destroy(this.leftRepeater,this.rightRepeater);this.deleteMembers("strip","edge","scrollLeft","scrollRight","stripWrap");this.activeTab=null;Ext.TabPanel.superclass.beforeDestroy.apply(this)}});Ext.reg("tabpanel",Ext.TabPanel);Ext.TabPanel.prototype.activate=Ext.TabPanel.prototype.setActiveTab;Ext.TabPanel.AccessStack=function(){var a=[];return{add:function(b){a.push(b);if(a.length>10){a.shift()}},remove:function(e){var d=[];for(var c=0,b=a.length;c<b;c++){if(a[c]!=e){d.push(a[c])}}a=d},next:function(){return a.pop()}}};Ext.Button=Ext.extend(Ext.BoxComponent,{hidden:false,disabled:false,pressed:false,enableToggle:false,menuAlign:"tl-bl?",type:"button",menuClassTarget:"tr:nth(2)",clickEvent:"click",handleMouseEvents:true,tooltipType:"qtip",buttonSelector:"button:first-child",scale:"small",iconAlign:"left",arrowAlign:"right",initComponent:function(){if(this.menu){if(Ext.isArray(this.menu)){this.menu={items:this.menu}}if(Ext.isObject(this.menu)){this.menu.ownerCt=this}this.menu=Ext.menu.MenuMgr.get(this.menu);this.menu.ownerCt=undefined}Ext.Button.superclass.initComponent.call(this);this.addEvents("click","toggle","mouseover","mouseout","menushow","menuhide","menutriggerover","menutriggerout");if(Ext.isString(this.toggleGroup)){this.enableToggle=true}},getTemplateArgs:function(){return[this.type,"x-btn-"+this.scale+" x-btn-icon-"+this.scale+"-"+this.iconAlign,this.getMenuClass(),this.cls,this.id]},setButtonClass:function(){if(this.useSetClass){if(!Ext.isEmpty(this.oldCls)){this.el.removeClass([this.oldCls,"x-btn-pressed"])}this.oldCls=(this.iconCls||this.icon)?(this.text?"x-btn-text-icon":"x-btn-icon"):"x-btn-noicon";this.el.addClass([this.oldCls,this.pressed?"x-btn-pressed":null])}},getMenuClass:function(){return this.menu?(this.arrowAlign!="bottom"?"x-btn-arrow":"x-btn-arrow-bottom"):""},onRender:function(c,a){if(!this.template){if(!Ext.Button.buttonTemplate){Ext.Button.buttonTemplate=new Ext.Template('<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">','<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>','<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{2} x-unselectable" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>','<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',"</tbody></table>");Ext.Button.buttonTemplate.compile()}this.template=Ext.Button.buttonTemplate}var b,d=this.getTemplateArgs();if(a){b=this.template.insertBefore(a,d,true)}else{b=this.template.append(c,d,true)}this.btnEl=b.child(this.buttonSelector);this.mon(this.btnEl,{scope:this,focus:this.onFocus,blur:this.onBlur});this.initButtonEl(b,this.btnEl);Ext.ButtonToggleMgr.register(this)},initButtonEl:function(b,c){this.el=b;this.setIcon(this.icon);this.setText(this.text);this.setIconClass(this.iconCls);if(Ext.isDefined(this.tabIndex)){c.dom.tabIndex=this.tabIndex}if(this.tooltip){this.setTooltip(this.tooltip,true)}if(this.handleMouseEvents){this.mon(b,{scope:this,mouseover:this.onMouseOver,mousedown:this.onMouseDown})}if(this.menu){this.mon(this.menu,{scope:this,show:this.onMenuShow,hide:this.onMenuHide})}if(this.repeat){var a=new Ext.util.ClickRepeater(b,Ext.isObject(this.repeat)?this.repeat:{});this.mon(a,"click",this.onRepeatClick,this)}else{this.mon(b,this.clickEvent,this.onClick,this)}},afterRender:function(){Ext.Button.superclass.afterRender.call(this);this.useSetClass=true;this.setButtonClass();this.doc=Ext.getDoc();this.doAutoWidth()},setIconClass:function(a){this.iconCls=a;if(this.el){this.btnEl.dom.className="";this.btnEl.addClass(["x-btn-text",a||""]);this.setButtonClass()}return this},setTooltip:function(b,a){if(this.rendered){if(!a){this.clearTip()}if(Ext.isObject(b)){Ext.QuickTips.register(Ext.apply({target:this.btnEl.id},b));this.tooltip=b}else{this.btnEl.dom[this.tooltipType]=b}}else{this.tooltip=b}return this},clearTip:function(){if(Ext.isObject(this.tooltip)){Ext.QuickTips.unregister(this.btnEl)}},beforeDestroy:function(){if(this.rendered){this.clearTip()}if(this.menu&&this.destroyMenu!==false){Ext.destroy(this.btnEl,this.menu)}Ext.destroy(this.repeater)},onDestroy:function(){if(this.rendered){this.doc.un("mouseover",this.monitorMouseOver,this);this.doc.un("mouseup",this.onMouseUp,this);delete this.doc;delete this.btnEl;Ext.ButtonToggleMgr.unregister(this)}Ext.Button.superclass.onDestroy.call(this)},doAutoWidth:function(){if(this.autoWidth!==false&&this.el&&this.text&&this.width===undefined){this.el.setWidth("auto");if(Ext.isIE7&&Ext.isStrict){var a=this.btnEl;if(a&&a.getWidth()>20){a.clip();a.setWidth(Ext.util.TextMetrics.measure(a,this.text).width+a.getFrameWidth("lr"))}}if(this.minWidth){if(this.el.getWidth()<this.minWidth){this.el.setWidth(this.minWidth)}}}},setHandler:function(b,a){this.handler=b;this.scope=a;return this},setText:function(a){this.text=a;if(this.el){this.btnEl.update(a||"&#160;");this.setButtonClass()}this.doAutoWidth();return this},setIcon:function(a){this.icon=a;if(this.el){this.btnEl.setStyle("background-image",a?"url("+a+")":"");this.setButtonClass()}return this},getText:function(){return this.text},toggle:function(b,a){b=b===undefined?!this.pressed:!!b;if(b!=this.pressed){if(this.rendered){this.el[b?"addClass":"removeClass"]("x-btn-pressed")}this.pressed=b;if(!a){this.fireEvent("toggle",this,b);if(this.toggleHandler){this.toggleHandler.call(this.scope||this,this,b)}}}return this},onDisable:function(){this.onDisableChange(true)},onEnable:function(){this.onDisableChange(false)},onDisableChange:function(a){if(this.el){if(!Ext.isIE6||!this.text){this.el[a?"addClass":"removeClass"](this.disabledClass)}this.el.dom.disabled=a}this.disabled=a},showMenu:function(){if(this.rendered&&this.menu){if(this.tooltip){Ext.QuickTips.getQuickTip().cancelShow(this.btnEl)}if(this.menu.isVisible()){this.menu.hide()}this.menu.ownerCt=this;this.menu.show(this.el,this.menuAlign)}return this},hideMenu:function(){if(this.hasVisibleMenu()){this.menu.hide()}return this},hasVisibleMenu:function(){return this.menu&&this.menu.ownerCt==this&&this.menu.isVisible()},onRepeatClick:function(a,b){this.onClick(b)},onClick:function(a){if(a){a.preventDefault()}if(a.button!==0){return}if(!this.disabled){this.doToggle();if(this.menu&&!this.hasVisibleMenu()&&!this.ignoreNextClick){this.showMenu()}this.fireEvent("click",this,a);if(this.handler){this.handler.call(this.scope||this,this,a)}}},doToggle:function(){if(this.enableToggle&&(this.allowDepress!==false||!this.pressed)){this.toggle()}},isMenuTriggerOver:function(b,a){return this.menu&&!a},isMenuTriggerOut:function(b,a){return this.menu&&!a},onMouseOver:function(b){if(!this.disabled){var a=b.within(this.el,true);if(!a){this.el.addClass("x-btn-over");if(!this.monitoringMouseOver){this.doc.on("mouseover",this.monitorMouseOver,this);this.monitoringMouseOver=true}this.fireEvent("mouseover",this,b)}if(this.isMenuTriggerOver(b,a)){this.fireEvent("menutriggerover",this,this.menu,b)}}},monitorMouseOver:function(a){if(a.target!=this.el.dom&&!a.within(this.el)){if(this.monitoringMouseOver){this.doc.un("mouseover",this.monitorMouseOver,this);this.monitoringMouseOver=false}this.onMouseOut(a)}},onMouseOut:function(b){var a=b.within(this.el)&&b.target!=this.el.dom;this.el.removeClass("x-btn-over");this.fireEvent("mouseout",this,b);if(this.isMenuTriggerOut(b,a)){this.fireEvent("menutriggerout",this,this.menu,b)}},focus:function(){this.btnEl.focus()},blur:function(){this.btnEl.blur()},onFocus:function(a){if(!this.disabled){this.el.addClass("x-btn-focus")}},onBlur:function(a){this.el.removeClass("x-btn-focus")},getClickEl:function(b,a){return this.el},onMouseDown:function(a){if(!this.disabled&&a.button===0){this.getClickEl(a).addClass("x-btn-click");this.doc.on("mouseup",this.onMouseUp,this)}},onMouseUp:function(a){if(a.button===0){this.getClickEl(a,true).removeClass("x-btn-click");this.doc.un("mouseup",this.onMouseUp,this)}},onMenuShow:function(a){if(this.menu.ownerCt==this){this.menu.ownerCt=this;this.ignoreNextClick=0;this.el.addClass("x-btn-menu-active");this.fireEvent("menushow",this,this.menu)}},onMenuHide:function(a){if(this.menu.ownerCt==this){this.el.removeClass("x-btn-menu-active");this.ignoreNextClick=this.restoreClick.defer(250,this);this.fireEvent("menuhide",this,this.menu);delete this.menu.ownerCt}},restoreClick:function(){this.ignoreNextClick=0}});Ext.reg("button",Ext.Button);Ext.ButtonToggleMgr=function(){var a={};function b(e,j){if(j){var h=a[e.toggleGroup];for(var d=0,c=h.length;d<c;d++){if(h[d]!=e){h[d].toggle(false)}}}}return{register:function(c){if(!c.toggleGroup){return}var d=a[c.toggleGroup];if(!d){d=a[c.toggleGroup]=[]}d.push(c);c.on("toggle",b)},unregister:function(c){if(!c.toggleGroup){return}var d=a[c.toggleGroup];if(d){d.remove(c);c.un("toggle",b)}},getPressed:function(h){var e=a[h];if(e){for(var d=0,c=e.length;d<c;d++){if(e[d].pressed===true){return e[d]}}}return null}}}();Ext.SplitButton=Ext.extend(Ext.Button,{arrowSelector:"em",split:true,initComponent:function(){Ext.SplitButton.superclass.initComponent.call(this);this.addEvents("arrowclick")},onRender:function(){Ext.SplitButton.superclass.onRender.apply(this,arguments);if(this.arrowTooltip){this.el.child(this.arrowSelector).dom[this.tooltipType]=this.arrowTooltip}},setArrowHandler:function(b,a){this.arrowHandler=b;this.scope=a},getMenuClass:function(){return"x-btn-split"+(this.arrowAlign=="bottom"?"-bottom":"")},isClickOnArrow:function(c){if(this.arrowAlign!="bottom"){var b=this.el.child("em.x-btn-split");var a=b.getRegion().right-b.getPadding("r");return c.getPageX()>a}else{return c.getPageY()>this.btnEl.getRegion().bottom}},onClick:function(b,a){b.preventDefault();if(!this.disabled){if(this.isClickOnArrow(b)){if(this.menu&&!this.menu.isVisible()&&!this.ignoreNextClick){this.showMenu()}this.fireEvent("arrowclick",this,b);if(this.arrowHandler){this.arrowHandler.call(this.scope||this,this,b)}}else{this.doToggle();this.fireEvent("click",this,b);if(this.handler){this.handler.call(this.scope||this,this,b)}}}},isMenuTriggerOver:function(a){return this.menu&&a.target.tagName==this.arrowSelector},isMenuTriggerOut:function(b,a){return this.menu&&b.target.tagName!=this.arrowSelector}});Ext.reg("splitbutton",Ext.SplitButton);Ext.CycleButton=Ext.extend(Ext.SplitButton,{getItemText:function(a){if(a&&this.showText===true){var b="";if(this.prependText){b+=this.prependText}b+=a.text;return b}return undefined},setActiveItem:function(c,a){if(!Ext.isObject(c)){c=this.menu.getComponent(c)}if(c){if(!this.rendered){this.text=this.getItemText(c);this.iconCls=c.iconCls}else{var b=this.getItemText(c);if(b){this.setText(b)}this.setIconClass(c.iconCls)}this.activeItem=c;if(!c.checked){c.setChecked(true,a)}if(this.forceIcon){this.setIconClass(this.forceIcon)}if(!a){this.fireEvent("change",this,c)}}},getActiveItem:function(){return this.activeItem},initComponent:function(){this.addEvents("change");if(this.changeHandler){this.on("change",this.changeHandler,this.scope||this);delete this.changeHandler}this.itemCount=this.items.length;this.menu={cls:"x-cycle-menu",items:[]};var a=0;Ext.each(this.items,function(c,b){Ext.apply(c,{group:c.group||this.id,itemIndex:b,checkHandler:this.checkHandler,scope:this,checked:c.checked||false});this.menu.items.push(c);if(c.checked){a=b}},this);Ext.CycleButton.superclass.initComponent.call(this);this.on("click",this.toggleSelected,this);this.setActiveItem(a,true)},checkHandler:function(a,b){if(b){this.setActiveItem(a)}},toggleSelected:function(){var a=this.menu;a.render();if(!a.hasLayout){a.doLayout()}var d,b;for(var c=1;c<this.itemCount;c++){d=(this.activeItem.itemIndex+c)%this.itemCount;b=a.items.itemAt(d);if(!b.disabled){b.setChecked(true);break}}}});Ext.reg("cycle",Ext.CycleButton);Ext.Toolbar=function(a){if(Ext.isArray(a)){a={items:a,layout:"toolbar"}}else{a=Ext.apply({layout:"toolbar"},a);if(a.buttons){a.items=a.buttons}}Ext.Toolbar.superclass.constructor.call(this,a)};(function(){var a=Ext.Toolbar;Ext.extend(a,Ext.Container,{defaultType:"button",enableOverflow:false,trackMenus:true,internalDefaults:{removeMode:"container",hideParent:true},toolbarCls:"x-toolbar",initComponent:function(){a.superclass.initComponent.call(this);this.addEvents("overflowchange")},onRender:function(c,b){if(!this.el){if(!this.autoCreate){this.autoCreate={cls:this.toolbarCls+" x-small-editor"}}this.el=c.createChild(Ext.apply({id:this.id},this.autoCreate),b);Ext.Toolbar.superclass.onRender.apply(this,arguments)}},lookupComponent:function(b){if(Ext.isString(b)){if(b=="-"){b=new a.Separator()}else{if(b==" "){b=new a.Spacer()}else{if(b=="->"){b=new a.Fill()}else{b=new a.TextItem(b)}}}this.applyDefaults(b)}else{if(b.isFormField||b.render){b=this.createComponent(b)}else{if(b.tag){b=new a.Item({autoEl:b})}else{if(b.tagName){b=new a.Item({el:b})}else{if(Ext.isObject(b)){b=b.xtype?this.createComponent(b):this.constructButton(b)}}}}}return b},applyDefaults:function(e){if(!Ext.isString(e)){e=Ext.Toolbar.superclass.applyDefaults.call(this,e);var b=this.internalDefaults;if(e.events){Ext.applyIf(e.initialConfig,b);Ext.apply(e,b)}else{Ext.applyIf(e,b)}}return e},addSeparator:function(){return this.add(new a.Separator())},addSpacer:function(){return this.add(new a.Spacer())},addFill:function(){this.add(new a.Fill())},addElement:function(b){return this.addItem(new a.Item({el:b}))},addItem:function(b){return this.add.apply(this,arguments)},addButton:function(c){if(Ext.isArray(c)){var e=[];for(var d=0,b=c.length;d<b;d++){e.push(this.addButton(c[d]))}return e}return this.add(this.constructButton(c))},addText:function(b){return this.addItem(new a.TextItem(b))},addDom:function(b){return this.add(new a.Item({autoEl:b}))},addField:function(b){return this.add(b)},insertButton:function(c,g){if(Ext.isArray(g)){var e=[];for(var d=0,b=g.length;d<b;d++){e.push(this.insertButton(c+d,g[d]))}return e}return Ext.Toolbar.superclass.insert.call(this,c,g)},trackMenu:function(c,b){if(this.trackMenus&&c.menu){var d=b?"mun":"mon";this[d](c,"menutriggerover",this.onButtonTriggerOver,this);this[d](c,"menushow",this.onButtonMenuShow,this);this[d](c,"menuhide",this.onButtonMenuHide,this)}},constructButton:function(d){var c=d.events?d:this.createComponent(d,d.split?"splitbutton":this.defaultType);return c},onAdd:function(b){Ext.Toolbar.superclass.onAdd.call(this);this.trackMenu(b);if(this.disabled){b.disable()}},onRemove:function(b){Ext.Toolbar.superclass.onRemove.call(this);if(b==this.activeMenuBtn){delete this.activeMenuBtn}this.trackMenu(b,true)},onDisable:function(){this.items.each(function(b){if(b.disable){b.disable()}})},onEnable:function(){this.items.each(function(b){if(b.enable){b.enable()}})},onButtonTriggerOver:function(b){if(this.activeMenuBtn&&this.activeMenuBtn!=b){this.activeMenuBtn.hideMenu();b.showMenu();this.activeMenuBtn=b}},onButtonMenuShow:function(b){this.activeMenuBtn=b},onButtonMenuHide:function(b){delete this.activeMenuBtn}});Ext.reg("toolbar",Ext.Toolbar);a.Item=Ext.extend(Ext.BoxComponent,{hideParent:true,enable:Ext.emptyFn,disable:Ext.emptyFn,focus:Ext.emptyFn});Ext.reg("tbitem",a.Item);a.Separator=Ext.extend(a.Item,{onRender:function(c,b){this.el=c.createChild({tag:"span",cls:"xtb-sep"},b)}});Ext.reg("tbseparator",a.Separator);a.Spacer=Ext.extend(a.Item,{onRender:function(c,b){this.el=c.createChild({tag:"div",cls:"xtb-spacer",style:this.width?"width:"+this.width+"px":""},b)}});Ext.reg("tbspacer",a.Spacer);a.Fill=Ext.extend(a.Item,{render:Ext.emptyFn,isFill:true});Ext.reg("tbfill",a.Fill);a.TextItem=Ext.extend(a.Item,{constructor:function(b){a.TextItem.superclass.constructor.call(this,Ext.isString(b)?{text:b}:b)},onRender:function(c,b){this.autoEl={cls:"xtb-text",html:this.text||""};a.TextItem.superclass.onRender.call(this,c,b)},setText:function(b){if(this.rendered){this.el.update(b)}else{this.text=b}}});Ext.reg("tbtext",a.TextItem);a.Button=Ext.extend(Ext.Button,{});a.SplitButton=Ext.extend(Ext.SplitButton,{});Ext.reg("tbbutton",a.Button);Ext.reg("tbsplit",a.SplitButton)})();Ext.ButtonGroup=Ext.extend(Ext.Panel,{baseCls:"x-btn-group",layout:"table",defaultType:"button",frame:true,internalDefaults:{removeMode:"container",hideParent:true},initComponent:function(){this.layoutConfig=this.layoutConfig||{};Ext.applyIf(this.layoutConfig,{columns:this.columns});if(!this.title){this.addClass("x-btn-group-notitle")}this.on("afterlayout",this.onAfterLayout,this);Ext.ButtonGroup.superclass.initComponent.call(this)},applyDefaults:function(b){b=Ext.ButtonGroup.superclass.applyDefaults.call(this,b);var a=this.internalDefaults;if(b.events){Ext.applyIf(b.initialConfig,a);Ext.apply(b,a)}else{Ext.applyIf(b,a)}return b},onAfterLayout:function(){var a=this.body.getFrameWidth("lr")+this.body.dom.firstChild.offsetWidth;this.body.setWidth(a);this.el.setWidth(a+this.getFrameWidth())}});Ext.reg("buttongroup",Ext.ButtonGroup);(function(){var a=Ext.Toolbar;Ext.PagingToolbar=Ext.extend(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",initComponent:function(){var c=[this.first=new a.Button({tooltip:this.firstText,overflowText:this.firstText,iconCls:"x-tbar-page-first",disabled:true,handler:this.moveFirst,scope:this}),this.prev=new a.Button({tooltip:this.prevText,overflowText:this.prevText,iconCls:"x-tbar-page-prev",disabled:true,handler:this.movePrevious,scope:this}),"-",this.beforePageText,this.inputItem=new Ext.form.NumberField({cls:"x-tbar-page-number",allowDecimals:false,allowNegative:false,enableKeyEvents:true,selectOnFocus:true,submitValue:false,listeners:{scope:this,keydown:this.onPagingKeyDown,blur:this.onPagingBlur}}),this.afterTextItem=new a.TextItem({text:String.format(this.afterPageText,1)}),"-",this.next=new a.Button({tooltip:this.nextText,overflowText:this.nextText,iconCls:"x-tbar-page-next",disabled:true,handler:this.moveNext,scope:this}),this.last=new a.Button({tooltip:this.lastText,overflowText:this.lastText,iconCls:"x-tbar-page-last",disabled:true,handler:this.moveLast,scope:this}),"-",this.refresh=new a.Button({tooltip:this.refreshText,overflowText:this.refreshText,iconCls:"x-tbar-loading",handler:this.doRefresh,scope:this})];var b=this.items||this.buttons||[];if(this.prependButtons){this.items=b.concat(c)}else{this.items=c.concat(b)}delete this.buttons;if(this.displayInfo){this.items.push("->");this.items.push(this.displayItem=new a.TextItem({}))}Ext.PagingToolbar.superclass.initComponent.call(this);this.addEvents("change","beforechange");this.on("afterlayout",this.onFirstLayout,this,{single:true});this.cursor=0;this.bindStore(this.store,true)},onFirstLayout:function(){if(this.dsLoaded){this.onLoad.apply(this,this.dsLoaded)}},updateInfo:function(){if(this.displayItem){var b=this.store.getCount();var c=b==0?this.emptyMsg:String.format(this.displayMsg,this.cursor+1,this.cursor+b,this.store.getTotalCount());this.displayItem.setText(c)}},onLoad:function(b,e,j){if(!this.rendered){this.dsLoaded=[b,e,j];return}var g=this.getParams();this.cursor=(j.params&&j.params[g.start])?j.params[g.start]:0;var i=this.getPageData(),c=i.activePage,h=i.pages;this.afterTextItem.setText(String.format(this.afterPageText,i.pages));this.inputItem.setValue(c);this.first.setDisabled(c==1);this.prev.setDisabled(c==1);this.next.setDisabled(c==h);this.last.setDisabled(c==h);this.refresh.enable();this.updateInfo();this.fireEvent("change",this,i)},getPageData:function(){var b=this.store.getTotalCount();return{total:b,activePage:Math.ceil((this.cursor+this.pageSize)/this.pageSize),pages:b<this.pageSize?1:Math.ceil(b/this.pageSize)}},changePage:function(b){this.doLoad(((b-1)*this.pageSize).constrain(0,this.store.getTotalCount()))},onLoadError:function(){if(!this.rendered){return}this.refresh.enable()},readPage:function(e){var b=this.inputItem.getValue(),c;if(!b||isNaN(c=parseInt(b,10))){this.inputItem.setValue(e.activePage);return false}return c},onPagingFocus:function(){this.inputItem.select()},onPagingBlur:function(b){this.inputItem.setValue(this.getPageData().activePage)},onPagingKeyDown:function(i,h){var c=h.getKey(),j=this.getPageData(),g;if(c==h.RETURN){h.stopEvent();g=this.readPage(j);if(g!==false){g=Math.min(Math.max(1,g),j.pages)-1;this.doLoad(g*this.pageSize)}}else{if(c==h.HOME||c==h.END){h.stopEvent();g=c==h.HOME?1:j.pages;i.setValue(g)}else{if(c==h.UP||c==h.PAGEUP||c==h.DOWN||c==h.PAGEDOWN){h.stopEvent();if((g=this.readPage(j))){var b=h.shiftKey?10:1;if(c==h.DOWN||c==h.PAGEDOWN){b*=-1}g+=b;if(g>=1&g<=j.pages){i.setValue(g)}}}}}},getParams:function(){return this.paramNames||this.store.paramNames},beforeLoad:function(){if(this.rendered&&this.refresh){this.refresh.disable()}},doLoad:function(d){var c={},b=this.getParams();c[b.start]=d;c[b.limit]=this.pageSize;if(this.fireEvent("beforechange",this,c)!==false){this.store.load({params:c})}},moveFirst:function(){this.doLoad(0)},movePrevious:function(){this.doLoad(Math.max(0,this.cursor-this.pageSize))},moveNext:function(){this.doLoad(this.cursor+this.pageSize)},moveLast:function(){var c=this.store.getTotalCount(),b=c%this.pageSize;this.doLoad(b?(c-b):c-this.pageSize)},doRefresh:function(){this.doLoad(this.cursor)},bindStore:function(c,d){var b;if(!d&&this.store){if(c!==this.store&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.beforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.onLoadError,this)}if(!c){this.store=null}}if(c){c=Ext.StoreMgr.lookup(c);c.on({scope:this,beforeload:this.beforeLoad,load:this.onLoad,exception:this.onLoadError});b=true}this.store=c;if(b){this.onLoad(c,null,{})}},unbind:function(b){this.bindStore(null)},bind:function(b){this.bindStore(b)},onDestroy:function(){this.bindStore(null);Ext.PagingToolbar.superclass.onDestroy.call(this)}})})();Ext.reg("paging",Ext.PagingToolbar);Ext.History=(function(){var e,c;var k=false;var d;function g(){var l=location.href,m=l.indexOf("#"),n=m>=0?l.substr(m+1):null;if(Ext.isGecko){n=decodeURIComponent(n)}return n}function a(){c.value=d}function h(l){d=l;Ext.History.fireEvent("change",l)}function i(m){var l=['<html><body><div id="state">',Ext.util.Format.htmlEncode(m),"</div></body></html>"].join("");try{var o=e.contentWindow.document;o.open();o.write(l);o.close();return true}catch(n){return false}}function b(){if(!e.contentWindow||!e.contentWindow.document){setTimeout(b,10);return}var o=e.contentWindow.document;var m=o.getElementById("state");var l=m?m.innerText:null;var n=g();setInterval(function(){o=e.contentWindow.document;m=o.getElementById("state");var q=m?m.innerText:null;var p=g();if(q!==l){l=q;h(l);location.hash=l;n=l;a()}else{if(p!==n){n=p;i(p)}}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}function j(){d=c.value?c.value:g();if(Ext.isIE){b()}else{var l=g();setInterval(function(){var m=g();if(m!==l){l=m;h(l);a()}},50);k=true;Ext.History.fireEvent("ready",Ext.History)}}return{fieldId:"x-history-field",iframeId:"x-history-frame",events:{},init:function(m,l){if(k){Ext.callback(m,l,[this]);return}if(!Ext.isReady){Ext.onReady(function(){Ext.History.init(m,l)});return}c=Ext.getDom(Ext.History.fieldId);if(Ext.isIE){e=Ext.getDom(Ext.History.iframeId)}this.addEvents("ready","change");if(m){this.on("ready",m,l,{single:true})}j()},add:function(l,m){if(m!==false){if(this.getToken()==l){return true}}if(Ext.isIE){return i(l)}else{location.hash=l;return true}},back:function(){history.go(-1)},forward:function(){history.go(1)},getToken:function(){return k?d:g()}}})();Ext.apply(Ext.History,new Ext.util.Observable());Ext.Tip=Ext.extend(Ext.Panel,{minWidth:40,maxWidth:300,shadow:"sides",defaultAlign:"tl-bl?",autoRender:true,quickShowInterval:250,frame:true,hidden:true,baseCls:"x-tip",floating:{shadow:true,shim:true,useDisplay:true,constrain:false},autoHeight:true,closeAction:"hide",initComponent:function(){Ext.Tip.superclass.initComponent.call(this);if(this.closable&&!this.title){this.elements+=",header"}},afterRender:function(){Ext.Tip.superclass.afterRender.call(this);if(this.closable){this.addTool({id:"close",handler:this[this.closeAction],scope:this})}},showAt:function(a){Ext.Tip.superclass.show.call(this);if(this.measureWidth!==false&&(!this.initialConfig||typeof this.initialConfig.width!="number")){this.doAutoWidth()}if(this.constrainPosition){a=this.el.adjustForConstraints(a)}this.setPagePosition(a[0],a[1])},doAutoWidth:function(a){a=a||0;var b=this.body.getTextWidth();if(this.title){b=Math.max(b,this.header.child("span").getTextWidth(this.title))}b+=this.getFrameWidth()+(this.closable?20:0)+this.body.getPadding("lr")+a;this.setWidth(b.constrain(this.minWidth,this.maxWidth));if(Ext.isIE7&&!this.repainted){this.el.repaint();this.repainted=true}},showBy:function(a,b){if(!this.rendered){this.render(Ext.getBody())}this.showAt(this.el.getAlignToXY(a,b||this.defaultAlign))},initDraggable:function(){this.dd=new Ext.Tip.DD(this,typeof this.draggable=="boolean"?null:this.draggable);this.header.addClass("x-tip-draggable")}});Ext.reg("tip",Ext.Tip);Ext.Tip.DD=function(b,a){Ext.apply(this,a);this.tip=b;Ext.Tip.DD.superclass.constructor.call(this,b.el.id,"WindowDD-"+b.id);this.setHandleElId(b.header.id);this.scroll=false};Ext.extend(Ext.Tip.DD,Ext.dd.DD,{moveOnly:true,scroll:false,headerOffsets:[100,25],startDrag:function(){this.tip.el.disableShadow()},endDrag:function(a){this.tip.el.enableShadow(true)}});Ext.ToolTip=Ext.extend(Ext.Tip,{showDelay:500,hideDelay:200,dismissDelay:5000,trackMouse:false,anchorToTarget:true,anchorOffset:0,targetCounter:0,constrainPosition:false,initComponent:function(){Ext.ToolTip.superclass.initComponent.call(this);this.lastActive=new Date();this.initTarget(this.target);this.origAnchor=this.anchor},onRender:function(b,a){Ext.ToolTip.superclass.onRender.call(this,b,a);this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl=this.el.createChild({cls:"x-tip-anchor "+this.anchorCls})},afterRender:function(){Ext.ToolTip.superclass.afterRender.call(this);this.anchorEl.setStyle("z-index",this.el.getZIndex()+1).setVisibilityMode(Ext.Element.DISPLAY)},initTarget:function(c){var a;if((a=Ext.get(c))){if(this.target){var b=Ext.get(this.target);this.mun(b,"mouseover",this.onTargetOver,this);this.mun(b,"mouseout",this.onTargetOut,this);this.mun(b,"mousemove",this.onMouseMove,this)}this.mon(a,{mouseover:this.onTargetOver,mouseout:this.onTargetOut,mousemove:this.onMouseMove,scope:this});this.target=a}if(this.anchor){this.anchorTarget=this.target}},onMouseMove:function(b){var a=this.delegate?b.getTarget(this.delegate):this.triggerElement=true;if(a){this.targetXY=b.getXY();if(a===this.triggerElement){if(!this.hidden&&this.trackMouse){this.setPagePosition(this.getTargetXY())}}else{this.hide();this.lastActive=new Date(0);this.onTargetOver(b)}}else{if(!this.closable&&this.isVisible()){this.hide()}}},getTargetXY:function(){if(this.delegate){this.anchorTarget=this.triggerElement}if(this.anchor){this.targetCounter++;var c=this.getOffsets(),l=(this.anchorToTarget&&!this.trackMouse)?this.el.getAlignToXY(this.anchorTarget,this.getAnchorAlign()):this.targetXY,a=Ext.lib.Dom.getViewWidth()-5,h=Ext.lib.Dom.getViewHeight()-5,i=document.documentElement,e=document.body,k=(i.scrollLeft||e.scrollLeft||0)+5,j=(i.scrollTop||e.scrollTop||0)+5,b=[l[0]+c[0],l[1]+c[1]],g=this.getSize();this.anchorEl.removeClass(this.anchorCls);if(this.targetCounter<2){if(b[0]<k){if(this.anchorToTarget){this.defaultAlign="l-r";if(this.mouseOffset){this.mouseOffset[0]*=-1}}this.anchor="left";return this.getTargetXY()}if(b[0]+g.width>a){if(this.anchorToTarget){this.defaultAlign="r-l";if(this.mouseOffset){this.mouseOffset[0]*=-1}}this.anchor="right";return this.getTargetXY()}if(b[1]<j){if(this.anchorToTarget){this.defaultAlign="t-b";if(this.mouseOffset){this.mouseOffset[1]*=-1}}this.anchor="top";return this.getTargetXY()}if(b[1]+g.height>h){if(this.anchorToTarget){this.defaultAlign="b-t";if(this.mouseOffset){this.mouseOffset[1]*=-1}}this.anchor="bottom";return this.getTargetXY()}}this.anchorCls="x-tip-anchor-"+this.getAnchorPosition();this.anchorEl.addClass(this.anchorCls);this.targetCounter=0;return b}else{var d=this.getMouseOffset();return[this.targetXY[0]+d[0],this.targetXY[1]+d[1]]}},getMouseOffset:function(){var a=this.anchor?[0,0]:[15,18];if(this.mouseOffset){a[0]+=this.mouseOffset[0];a[1]+=this.mouseOffset[1]}return a},getAnchorPosition:function(){if(this.anchor){this.tipAnchor=this.anchor.charAt(0)}else{var a=this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);if(!a){throw"AnchorTip.defaultAlign is invalid"}this.tipAnchor=a[1].charAt(0)}switch(this.tipAnchor){case"t":return"top";case"b":return"bottom";case"r":return"right"}return"left"},getAnchorAlign:function(){switch(this.anchor){case"top":return"tl-bl";case"left":return"tl-tr";case"right":return"tr-tl";default:return"bl-tl"}},getOffsets:function(){var b,a=this.getAnchorPosition().charAt(0);if(this.anchorToTarget&&!this.trackMouse){switch(a){case"t":b=[0,9];break;case"b":b=[0,-13];break;case"r":b=[-13,0];break;default:b=[9,0];break}}else{switch(a){case"t":b=[-15-this.anchorOffset,30];break;case"b":b=[-19-this.anchorOffset,-13-this.el.dom.offsetHeight];break;case"r":b=[-15-this.el.dom.offsetWidth,-13-this.anchorOffset];break;default:b=[25,-13-this.anchorOffset];break}}var c=this.getMouseOffset();b[0]+=c[0];b[1]+=c[1];return b},onTargetOver:function(b){if(this.disabled||b.within(this.target.dom,true)){return}var a=b.getTarget(this.delegate);if(a){this.triggerElement=a;this.clearTimer("hide");this.targetXY=b.getXY();this.delayShow()}},delayShow:function(){if(this.hidden&&!this.showTimer){if(this.lastActive.getElapsed()<this.quickShowInterval){this.show()}else{this.showTimer=this.show.defer(this.showDelay,this)}}else{if(!this.hidden&&this.autoHide!==false){this.show()}}},onTargetOut:function(a){if(this.disabled||a.within(this.target.dom,true)){return}this.clearTimer("show");if(this.autoHide!==false){this.delayHide()}},delayHide:function(){if(!this.hidden&&!this.hideTimer){this.hideTimer=this.hide.defer(this.hideDelay,this)}},hide:function(){this.clearTimer("dismiss");this.lastActive=new Date();if(this.anchorEl){this.anchorEl.hide()}Ext.ToolTip.superclass.hide.call(this);delete this.triggerElement},show:function(){if(this.anchor){this.showAt([-1000,-1000]);this.origConstrainPosition=this.constrainPosition;this.constrainPosition=false;this.anchor=this.origAnchor}this.showAt(this.getTargetXY());if(this.anchor){this.anchorEl.show();this.syncAnchor();this.constrainPosition=this.origConstrainPosition}else{this.anchorEl.hide()}},showAt:function(a){this.lastActive=new Date();this.clearTimers();Ext.ToolTip.superclass.showAt.call(this,a);if(this.dismissDelay&&this.autoHide!==false){this.dismissTimer=this.hide.defer(this.dismissDelay,this)}if(this.anchor&&!this.anchorEl.isVisible()){this.syncAnchor();this.anchorEl.show()}else{this.anchorEl.hide()}},syncAnchor:function(){var a,b,c;switch(this.tipAnchor.charAt(0)){case"t":a="b";b="tl";c=[20+this.anchorOffset,2];break;case"r":a="l";b="tr";c=[-2,11+this.anchorOffset];break;case"b":a="t";b="bl";c=[20+this.anchorOffset,-2];break;default:a="r";b="tl";c=[2,11+this.anchorOffset];break}this.anchorEl.alignTo(this.el,a+"-"+b,c)},setPagePosition:function(a,b){Ext.ToolTip.superclass.setPagePosition.call(this,a,b);if(this.anchor){this.syncAnchor()}},clearTimer:function(a){a=a+"Timer";clearTimeout(this[a]);delete this[a]},clearTimers:function(){this.clearTimer("show");this.clearTimer("dismiss");this.clearTimer("hide")},onShow:function(){Ext.ToolTip.superclass.onShow.call(this);Ext.getDoc().on("mousedown",this.onDocMouseDown,this)},onHide:function(){Ext.ToolTip.superclass.onHide.call(this);Ext.getDoc().un("mousedown",this.onDocMouseDown,this)},onDocMouseDown:function(a){if(this.autoHide!==true&&!this.closable&&!a.within(this.el.dom)){this.disable();this.doEnable.defer(100,this)}},doEnable:function(){if(!this.isDestroyed){this.enable()}},onDisable:function(){this.clearTimers();this.hide()},adjustPosition:function(a,d){if(this.constrainPosition){var c=this.targetXY[1],b=this.getSize().height;if(d<=c&&(d+b)>=c){d=c-b-5}}return{x:a,y:d}},beforeDestroy:function(){this.clearTimers();Ext.destroy(this.anchorEl);delete this.anchorEl;delete this.target;delete this.anchorTarget;delete this.triggerElement;Ext.ToolTip.superclass.beforeDestroy.call(this)},onDestroy:function(){Ext.getDoc().un("mousedown",this.onDocMouseDown,this);Ext.ToolTip.superclass.onDestroy.call(this)}});Ext.reg("tooltip",Ext.ToolTip);Ext.QuickTip=Ext.extend(Ext.ToolTip,{interceptTitles:false,tagConfig:{namespace:"ext",attribute:"qtip",width:"qwidth",target:"target",title:"qtitle",hide:"hide",cls:"qclass",align:"qalign",anchor:"anchor"},initComponent:function(){this.target=this.target||Ext.getDoc();this.targets=this.targets||{};Ext.QuickTip.superclass.initComponent.call(this)},register:function(e){var h=Ext.isArray(e)?e:arguments;for(var g=0,a=h.length;g<a;g++){var l=h[g];var k=l.target;if(k){if(Ext.isArray(k)){for(var d=0,b=k.length;d<b;d++){this.targets[Ext.id(k[d])]=l}}else{this.targets[Ext.id(k)]=l}}}},unregister:function(a){delete this.targets[Ext.id(a)]},cancelShow:function(b){var a=this.activeTarget;b=Ext.get(b).dom;if(this.isVisible()){if(a&&a.el==b){this.hide()}}else{if(a&&a.el==b){this.clearTimer("show")}}},getTipCfg:function(d){var b=d.getTarget(),c,a;if(this.interceptTitles&&b.title&&Ext.isString(b.title)){c=b.title;b.qtip=c;b.removeAttribute("title");d.preventDefault()}else{a=this.tagConfig;c=b.qtip||Ext.fly(b).getAttribute(a.attribute,a.namespace)}return c},onTargetOver:function(i){if(this.disabled){return}this.targetXY=i.getXY();var c=i.getTarget();if(!c||c.nodeType!==1||c==document||c==document.body){return}if(this.activeTarget&&((c==this.activeTarget.el)||Ext.fly(this.activeTarget.el).contains(c))){this.clearTimer("hide");this.show();return}if(c&&this.targets[c.id]){this.activeTarget=this.targets[c.id];this.activeTarget.el=c;this.anchor=this.activeTarget.anchor;if(this.anchor){this.anchorTarget=c}this.delayShow();return}var g,h=Ext.fly(c),b=this.tagConfig,d=b.namespace;if(g=this.getTipCfg(i)){var a=h.getAttribute(b.hide,d);this.activeTarget={el:c,text:g,width:h.getAttribute(b.width,d),autoHide:a!="user"&&a!=="false",title:h.getAttribute(b.title,d),cls:h.getAttribute(b.cls,d),align:h.getAttribute(b.align,d)};this.anchor=h.getAttribute(b.anchor,d);if(this.anchor){this.anchorTarget=c}this.delayShow()}},onTargetOut:function(a){if(this.activeTarget&&a.within(this.activeTarget.el)&&!this.getTipCfg(a)){return}this.clearTimer("show");if(this.autoHide!==false){this.delayHide()}},showAt:function(b){var a=this.activeTarget;if(a){if(!this.rendered){this.render(Ext.getBody());this.activeTarget=a}if(a.width){this.setWidth(a.width);this.body.setWidth(this.adjustBodyWidth(a.width-this.getFrameWidth()));this.measureWidth=false}else{this.measureWidth=true}this.setTitle(a.title||"");this.body.update(a.text);this.autoHide=a.autoHide;this.dismissDelay=a.dismissDelay||this.dismissDelay;if(this.lastCls){this.el.removeClass(this.lastCls);delete this.lastCls}if(a.cls){this.el.addClass(a.cls);this.lastCls=a.cls}if(this.anchor){this.constrainPosition=false}else{if(a.align){b=this.el.getAlignToXY(a.el,a.align);this.constrainPosition=false}else{this.constrainPosition=true}}}Ext.QuickTip.superclass.showAt.call(this,b)},hide:function(){delete this.activeTarget;Ext.QuickTip.superclass.hide.call(this)}});Ext.reg("quicktip",Ext.QuickTip);Ext.QuickTips=function(){var b,a=false;return{init:function(c){if(!b){if(!Ext.isReady){Ext.onReady(function(){Ext.QuickTips.init(c)});return}b=new Ext.QuickTip({elements:"header,body",disabled:a});if(c!==false){b.render(Ext.getBody())}}},ddDisable:function(){if(b&&!a){b.disable()}},ddEnable:function(){if(b&&!a){b.enable()}},enable:function(){if(b){b.enable()}a=false},disable:function(){if(b){b.disable()}a=true},isEnabled:function(){return b!==undefined&&!b.disabled},getQuickTip:function(){return b},register:function(){b.register.apply(b,arguments)},unregister:function(){b.unregister.apply(b,arguments)},tips:function(){b.register.apply(b,arguments)}}}();Ext.slider.Tip=Ext.extend(Ext.Tip,{minWidth:10,offsets:[0,-10],init:function(a){a.on({scope:this,dragstart:this.onSlide,drag:this.onSlide,dragend:this.hide,destroy:this.destroy})},onSlide:function(b,c,a){this.show();this.body.update(this.getText(a));this.doAutoWidth();this.el.alignTo(a.el,"b-t?",this.offsets)},getText:function(a){return String(a.value)}});Ext.ux.SliderTip=Ext.slider.Tip;Ext.tree.TreePanel=Ext.extend(Ext.Panel,{rootVisible:true,animate:Ext.enableFx,lines:true,enableDD:false,hlDrop:Ext.enableFx,pathSeparator:"/",bubbleEvents:[],initComponent:function(){Ext.tree.TreePanel.superclass.initComponent.call(this);if(!this.eventModel){this.eventModel=new Ext.tree.TreeEventModel(this)}var a=this.loader;if(!a){a=new Ext.tree.TreeLoader({dataUrl:this.dataUrl,requestMethod:this.requestMethod})}else{if(Ext.isObject(a)&&!a.load){a=new Ext.tree.TreeLoader(a)}}this.loader=a;this.nodeHash={};if(this.root){var b=this.root;delete this.root;this.setRootNode(b)}this.addEvents("append","remove","movenode","insert","beforeappend","beforeremove","beforemovenode","beforeinsert","beforeload","load","textchange","beforeexpandnode","beforecollapsenode","expandnode","disabledchange","collapsenode","beforeclick","click","containerclick","checkchange","beforedblclick","dblclick","containerdblclick","contextmenu","containercontextmenu","beforechildrenrendered","startdrag","enddrag","dragdrop","beforenodedrop","nodedrop","nodedragover");if(this.singleExpand){this.on("beforeexpandnode",this.restrictExpand,this)}},proxyNodeEvent:function(c,b,a,h,g,e,d){if(c=="collapse"||c=="expand"||c=="beforecollapse"||c=="beforeexpand"||c=="move"||c=="beforemove"){c=c+"node"}return this.fireEvent(c,b,a,h,g,e,d)},getRootNode:function(){return this.root},setRootNode:function(b){this.destroyRoot();if(!b.render){b=this.loader.createNode(b)}this.root=b;b.ownerTree=this;b.isRoot=true;this.registerNode(b);if(!this.rootVisible){var a=b.attributes.uiProvider;b.ui=a?new a(b):new Ext.tree.RootTreeNodeUI(b)}if(this.innerCt){this.clearInnerCt();this.renderRoot()}return b},clearInnerCt:function(){this.innerCt.update("")},renderRoot:function(){this.root.render();if(!this.rootVisible){this.root.renderChildren()}},getNodeById:function(a){return this.nodeHash[a]},registerNode:function(a){this.nodeHash[a.id]=a},unregisterNode:function(a){delete this.nodeHash[a.id]},toString:function(){return"[Tree"+(this.id?" "+this.id:"")+"]"},restrictExpand:function(a){var b=a.parentNode;if(b){if(b.expandedChild&&b.expandedChild.parentNode==b){b.expandedChild.collapse()}b.expandedChild=a}},getChecked:function(b,c){c=c||this.root;var d=[];var e=function(){if(this.attributes.checked){d.push(!b?this:(b=="id"?this.id:this.attributes[b]))}};c.cascade(e);return d},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(g,a,h){if(Ext.isEmpty(g)){if(h){h(false,undefined)}return}a=a||"id";var d=g.split(this.pathSeparator);var c=this.root;if(c.attributes[a]!=d[1]){if(h){h(false,null)}return}var b=1;var e=function(){if(++b==d.length){if(h){h(true,c)}return}var i=c.findChild(a,d[b]);if(!i){if(h){h(false,c)}return}c=i;i.expand(false,false,e)};c.expand(false,false,e)},selectPath:function(e,a,g){if(Ext.isEmpty(e)){if(g){g(false,undefined)}return}a=a||"id";var c=e.split(this.pathSeparator),b=c.pop();if(c.length>1){var d=function(i,h){if(i&&h){var j=h.findChild(a,b);if(j){j.select();if(g){g(true,j)}}else{if(g){g(false,j)}}}else{if(g){g(false,j)}}};this.expandPath(c.join(this.pathSeparator),a,d)}else{this.root.select();if(g){g(true,this.root)}}},getTreeEl:function(){return this.body},onRender:function(b,a){Ext.tree.TreePanel.superclass.onRender.call(this,b,a);this.el.addClass("x-tree");this.innerCt=this.body.createChild({tag:"ul",cls:"x-tree-root-ct "+(this.useArrows?"x-tree-arrows":this.lines?"x-tree-lines":"x-tree-no-lines")})},initEvents:function(){Ext.tree.TreePanel.superclass.initEvents.call(this);if(this.containerScroll){Ext.dd.ScrollManager.register(this.body)}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)},afterRender:function(){Ext.tree.TreePanel.superclass.afterRender.call(this);this.renderRoot()},beforeDestroy:function(){if(this.rendered){Ext.dd.ScrollManager.unregister(this.body);Ext.destroy(this.dropZone,this.dragZone)}this.destroyRoot();Ext.destroy(this.loader);this.nodeHash=this.root=this.loader=null;Ext.tree.TreePanel.superclass.beforeDestroy.call(this)},destroyRoot:function(){if(this.root&&this.root.destroy){this.root.destroy(true)}}});Ext.tree.TreePanel.nodeTypes={};Ext.reg("treepanel",Ext.tree.TreePanel);Ext.tree.TreeEventModel=function(a){this.tree=a;this.tree.on("render",this.initEvents,this)};Ext.tree.TreeEventModel.prototype={initEvents:function(){var a=this.tree;if(a.trackMouseOver!==false){a.mon(a.innerCt,{scope:this,mouseover:this.delegateOver,mouseout:this.delegateOut})}a.mon(a.getTreeEl(),{scope:this,click:this.delegateClick,dblclick:this.delegateDblClick,contextmenu:this.delegateContextMenu})},getNode:function(b){var a;if(a=b.getTarget(".x-tree-node-el",10)){var c=Ext.fly(a,"_treeEvents").getAttribute("tree-node-id","ext");if(c){return this.tree.getNodeById(c)}}return null},getNodeTarget:function(b){var a=b.getTarget(".x-tree-node-icon",1);if(!a){a=b.getTarget(".x-tree-node-el",6)}return a},delegateOut:function(b,a){if(!this.beforeEvent(b)){return}if(b.getTarget(".x-tree-ec-icon",1)){var c=this.getNode(b);this.onIconOut(b,c);if(c==this.lastEcOver){delete this.lastEcOver}}if((a=this.getNodeTarget(b))&&!b.within(a,true)){this.onNodeOut(b,this.getNode(b))}},delegateOver:function(b,a){if(!this.beforeEvent(b)){return}if(Ext.isGecko&&!this.trackingDoc){Ext.getBody().on("mouseover",this.trackExit,this);this.trackingDoc=true}if(this.lastEcOver){this.onIconOut(b,this.lastEcOver);delete this.lastEcOver}if(b.getTarget(".x-tree-ec-icon",1)){this.lastEcOver=this.getNode(b);this.onIconOver(b,this.lastEcOver)}if(a=this.getNodeTarget(b)){this.onNodeOver(b,this.getNode(b))}},trackExit:function(a){if(this.lastOverNode){if(this.lastOverNode.ui&&!a.within(this.lastOverNode.ui.getEl())){this.onNodeOut(a,this.lastOverNode)}delete this.lastOverNode;Ext.getBody().un("mouseover",this.trackExit,this);this.trackingDoc=false}},delegateClick:function(b,a){if(this.beforeEvent(b)){if(b.getTarget("input[type=checkbox]",1)){this.onCheckboxClick(b,this.getNode(b))}else{if(b.getTarget(".x-tree-ec-icon",1)){this.onIconClick(b,this.getNode(b))}else{if(this.getNodeTarget(b)){this.onNodeClick(b,this.getNode(b))}}}}else{this.checkContainerEvent(b,"click")}},delegateDblClick:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeDblClick(b,this.getNode(b))}}else{this.checkContainerEvent(b,"dblclick")}},delegateContextMenu:function(b,a){if(this.beforeEvent(b)){if(this.getNodeTarget(b)){this.onNodeContextMenu(b,this.getNode(b))}}else{this.checkContainerEvent(b,"contextmenu")}},checkContainerEvent:function(b,a){if(this.disabled){b.stopEvent();return false}this.onContainerEvent(b,a)},onContainerEvent:function(b,a){this.tree.fireEvent("container"+a,this.tree,b)},onNodeClick:function(b,a){a.ui.onClick(b)},onNodeOver:function(b,a){this.lastOverNode=a;a.ui.onOver(b)},onNodeOut:function(b,a){a.ui.onOut(b)},onIconOver:function(b,a){a.ui.addClass("x-tree-ec-over")},onIconOut:function(b,a){a.ui.removeClass("x-tree-ec-over")},onIconClick:function(b,a){a.ui.ecClick(b)},onCheckboxClick:function(b,a){a.ui.onCheckChange(b)},onNodeDblClick:function(b,a){a.ui.onDblClick(b)},onNodeContextMenu:function(b,a){a.ui.onContextMenu(b)},beforeEvent:function(b){var a=this.getNode(b);if(this.disabled||!a||!a.ui){b.stopEvent();return false}return true},disable:function(){this.disabled=true},enable:function(){this.disabled=false}};Ext.tree.DefaultSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNode=null;this.addEvents("selectionchange","beforeselect");Ext.apply(this,a);Ext.tree.DefaultSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){this.select(a)},select:function(c,a){if(!Ext.fly(c.ui.wrap).isVisible()&&a){return a.call(this,c)}var b=this.selNode;if(c==b){c.ui.onSelectedChange(true)}else{if(this.fireEvent("beforeselect",this,c,b)!==false){if(b&&b.ui){b.ui.onSelectedChange(false)}this.selNode=c;c.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,c,b)}}return c},unselect:function(b,a){if(this.selNode==b){this.clearSelections(a)}},clearSelections:function(a){var b=this.selNode;if(b){b.ui.onSelectedChange(false);this.selNode=null;if(a!==true){this.fireEvent("selectionchange",this,null)}}return b},getSelectedNode:function(){return this.selNode},isSelected:function(a){return this.selNode==a},selectPrevious:function(a){if(!(a=a||this.selNode||this.lastSelNode)){return null}var c=a.previousSibling;if(c){if(!c.isExpanded()||c.childNodes.length<1){return this.select(c,this.selectPrevious)}else{var b=c.lastChild;while(b&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()&&b.childNodes.length>0){b=b.lastChild}return this.select(b,this.selectPrevious)}}else{if(a.parentNode&&(this.tree.rootVisible||!a.parentNode.isRoot)){return this.select(a.parentNode,this.selectPrevious)}}return null},selectNext:function(b){if(!(b=b||this.selNode||this.lastSelNode)){return null}if(b.firstChild&&b.isExpanded()&&Ext.fly(b.ui.wrap).isVisible()){return this.select(b.firstChild,this.selectNext)}else{if(b.nextSibling){return this.select(b.nextSibling,this.selectNext)}else{if(b.parentNode){var a=null;b.parentNode.bubble(function(){if(this.nextSibling){a=this.getOwnerTree().selModel.select(this.nextSibling,this.selectNext);return false}});return a}}}return null},onKeyDown:function(c){var b=this.selNode||this.lastSelNode;var d=this;if(!b){return}var a=c.getKey();switch(a){case c.DOWN:c.stopEvent();this.selectNext();break;case c.UP:c.stopEvent();this.selectPrevious();break;case c.RIGHT:c.preventDefault();if(b.hasChildNodes()){if(!b.isExpanded()){b.expand()}else{if(b.firstChild){this.select(b.firstChild,c)}}}break;case c.LEFT:c.preventDefault();if(b.hasChildNodes()&&b.isExpanded()){b.collapse()}else{if(b.parentNode&&(this.tree.rootVisible||b.parentNode!=this.tree.getRootNode())){this.select(b.parentNode,c)}}break}}});Ext.tree.MultiSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(a){this.selNodes=[];this.selMap={};this.addEvents("selectionchange");Ext.apply(this,a);Ext.tree.MultiSelectionModel.superclass.constructor.call(this)},init:function(a){this.tree=a;a.mon(a.getTreeEl(),"keydown",this.onKeyDown,this);a.on("click",this.onNodeClick,this)},onNodeClick:function(a,b){if(b.ctrlKey&&this.isSelected(a)){this.unselect(a)}else{this.select(a,b,b.ctrlKey)}},select:function(a,c,b){if(b!==true){this.clearSelections(true)}if(this.isSelected(a)){this.lastSelNode=a;return a}this.selNodes.push(a);this.selMap[a.id]=a;this.lastSelNode=a;a.ui.onSelectedChange(true);this.fireEvent("selectionchange",this,this.selNodes);return a},unselect:function(b){if(this.selMap[b.id]){b.ui.onSelectedChange(false);var c=this.selNodes;var a=c.indexOf(b);if(a!=-1){this.selNodes.splice(a,1)}delete this.selMap[b.id];this.fireEvent("selectionchange",this,this.selNodes)}},clearSelections:function(b){var d=this.selNodes;if(d.length>0){for(var c=0,a=d.length;c<a;c++){d[c].ui.onSelectedChange(false)}this.selNodes=[];this.selMap={};if(b!==true){this.fireEvent("selectionchange",this,this.selNodes)}}},isSelected:function(a){return this.selMap[a.id]?true:false},getSelectedNodes:function(){return this.selNodes.concat([])},onKeyDown:Ext.tree.DefaultSelectionModel.prototype.onKeyDown,selectNext:Ext.tree.DefaultSelectionModel.prototype.selectNext,selectPrevious:Ext.tree.DefaultSelectionModel.prototype.selectPrevious});Ext.data.Tree=Ext.extend(Ext.util.Observable,{constructor:function(a){this.nodeHash={};this.root=null;if(a){this.setRootNode(a)}this.addEvents("append","remove","move","insert","beforeappend","beforeremove","beforemove","beforeinsert");Ext.data.Tree.superclass.constructor.call(this)},pathSeparator:"/",proxyNodeEvent:function(){return this.fireEvent.apply(this,arguments)},getRootNode:function(){return this.root},setRootNode:function(a){this.root=a;a.ownerTree=this;a.isRoot=true;this.registerNode(a);return a},getNodeById:function(a){return this.nodeHash[a]},registerNode:function(a){this.nodeHash[a.id]=a},unregisterNode:function(a){delete this.nodeHash[a.id]},toString:function(){return"[Tree"+(this.id?" "+this.id:"")+"]"}});Ext.data.Node=Ext.extend(Ext.util.Observable,{constructor:function(a){this.attributes=a||{};this.leaf=this.attributes.leaf;this.id=this.attributes.id;if(!this.id){this.id=Ext.id(null,"xnode-");this.attributes.id=this.id}this.childNodes=[];this.parentNode=null;this.firstChild=null;this.lastChild=null;this.previousSibling=null;this.nextSibling=null;this.addEvents({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)},fireEvent:function(b){if(Ext.data.Node.superclass.fireEvent.apply(this,arguments)===false){return false}var a=this.getOwnerTree();if(a){if(a.proxyNodeEvent.apply(a,arguments)===false){return false}}return true},isLeaf:function(){return this.leaf===true},setFirstChild:function(a){this.firstChild=a},setLastChild:function(a){this.lastChild=a},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},isExpandable:function(){return this.attributes.expandable||this.hasChildNodes()},appendChild:function(e){var g=false;if(Ext.isArray(e)){g=e}else{if(arguments.length>1){g=arguments}}if(g){for(var d=0,a=g.length;d<a;d++){this.appendChild(g[d])}}else{if(this.fireEvent("beforeappend",this.ownerTree,this,e)===false){return false}var b=this.childNodes.length;var c=e.parentNode;if(c){if(e.fireEvent("beforemove",e.getOwnerTree(),e,c,this,b)===false){return false}c.removeChild(e)}b=this.childNodes.length;if(b===0){this.setFirstChild(e)}this.childNodes.push(e);e.parentNode=this;var h=this.childNodes[b-1];if(h){e.previousSibling=h;h.nextSibling=e}else{e.previousSibling=null}e.nextSibling=null;this.setLastChild(e);e.setOwnerTree(this.getOwnerTree());this.fireEvent("append",this.ownerTree,this,e,b);if(c){e.fireEvent("move",this.ownerTree,e,c,this,b)}return e}},removeChild:function(c,b){var a=this.childNodes.indexOf(c);if(a==-1){return false}if(this.fireEvent("beforeremove",this.ownerTree,this,c)===false){return false}this.childNodes.splice(a,1);if(c.previousSibling){c.previousSibling.nextSibling=c.nextSibling}if(c.nextSibling){c.nextSibling.previousSibling=c.previousSibling}if(this.firstChild==c){this.setFirstChild(c.nextSibling)}if(this.lastChild==c){this.setLastChild(c.previousSibling)}this.fireEvent("remove",this.ownerTree,this,c);if(b){c.destroy(true)}else{c.clear()}return c},clear:function(a){this.setOwnerTree(null,a);this.parentNode=this.previousSibling=this.nextSibling=null;if(a){this.firstChild=this.lastChild=null}},destroy:function(a){if(a===true){this.purgeListeners();this.clear(true);Ext.each(this.childNodes,function(b){b.destroy(true)});this.childNodes=null}else{this.remove(true)}},insertBefore:function(d,a){if(!a){return this.appendChild(d)}if(d==a){return false}if(this.fireEvent("beforeinsert",this.ownerTree,this,d,a)===false){return false}var b=this.childNodes.indexOf(a);var c=d.parentNode;var e=b;if(c==this&&this.childNodes.indexOf(d)<b){e--}if(c){if(d.fireEvent("beforemove",d.getOwnerTree(),d,c,this,b,a)===false){return false}c.removeChild(d)}if(e===0){this.setFirstChild(d)}this.childNodes.splice(e,0,d);d.parentNode=this;var g=this.childNodes[e-1];if(g){d.previousSibling=g;g.nextSibling=d}else{d.previousSibling=null}d.nextSibling=a;a.previousSibling=d;d.setOwnerTree(this.getOwnerTree());this.fireEvent("insert",this.ownerTree,this,d,a);if(c){d.fireEvent("move",this.ownerTree,d,c,this,e,a)}return d},remove:function(a){if(this.parentNode){this.parentNode.removeChild(this,a)}return this},removeAll:function(a){var c=this.childNodes,b;while((b=c[0])){this.removeChild(b,a)}return this},item:function(a){return this.childNodes[a]},replaceChild:function(a,c){var b=c?c.nextSibling:null;this.removeChild(c);this.insertBefore(a,b);return c},indexOf:function(a){return this.childNodes.indexOf(a)},getOwnerTree:function(){if(!this.ownerTree){var a=this;while(a){if(a.ownerTree){this.ownerTree=a.ownerTree;break}a=a.parentNode}}return this.ownerTree},getDepth:function(){var b=0;var a=this;while(a.parentNode){++b;a=a.parentNode}return b},setOwnerTree:function(a,b){if(a!=this.ownerTree){if(this.ownerTree){this.ownerTree.unregisterNode(this)}this.ownerTree=a;if(b!==true){Ext.each(this.childNodes,function(c){c.setOwnerTree(a)})}if(a){a.registerNode(this)}}},setId:function(b){if(b!==this.id){var a=this.ownerTree;if(a){a.unregisterNode(this)}this.id=this.attributes.id=b;if(a){a.registerNode(this)}this.onIdChange(b)}},onIdChange:Ext.emptyFn,getPath:function(c){c=c||"id";var e=this.parentNode;var a=[this.attributes[c]];while(e){a.unshift(e.attributes[c]);e=e.parentNode}var d=this.getOwnerTree().pathSeparator;return d+a.join(d)},bubble:function(c,b,a){var d=this;while(d){if(c.apply(b||d,a||[d])===false){break}d=d.parentNode}},cascade:function(g,e,b){if(g.apply(e||this,b||[this])!==false){var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){d[c].cascade(g,e,b)}}},eachChild:function(g,e,b){var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){if(g.apply(e||d[c],b||[d[c]])===false){break}}},findChild:function(b,c,a){return this.findChildBy(function(){return this.attributes[b]==c},null,a)},findChildBy:function(h,g,b){var e=this.childNodes,a=e.length,d=0,j,c;for(;d<a;d++){j=e[d];if(h.call(g||j,j)===true){return j}else{if(b){c=j.findChildBy(h,g,b);if(c!=null){return c}}}}return null},sort:function(e,d){var c=this.childNodes;var a=c.length;if(a>0){var g=d?function(){e.apply(d,arguments)}:e;c.sort(g);for(var b=0;b<a;b++){var h=c[b];h.previousSibling=c[b-1];h.nextSibling=c[b+1];if(b===0){this.setFirstChild(h)}if(b==a-1){this.setLastChild(h)}}}},contains:function(a){return a.isAncestor(this)},isAncestor:function(a){var b=this.parentNode;while(b){if(b==a){return true}b=b.parentNode}return false},toString:function(){return"[Node"+(this.id?" "+this.id:"")+"]"}});Ext.tree.TreeNode=Ext.extend(Ext.data.Node,{constructor:function(a){a=a||{};if(Ext.isString(a)){a={text:a}}this.childrenRendered=false;this.rendered=false;Ext.tree.TreeNode.superclass.constructor.call(this,a);this.expanded=a.expanded===true;this.isTarget=a.isTarget!==false;this.draggable=a.draggable!==false&&a.allowDrag!==false;this.allowChildren=a.allowChildren!==false&&a.allowDrop!==false;this.text=a.text;this.disabled=a.disabled===true;this.hidden=a.hidden===true;this.addEvents("textchange","beforeexpand","beforecollapse","expand","disabledchange","collapse","beforeclick","click","checkchange","beforedblclick","dblclick","contextmenu","beforechildrenrendered");var b=this.attributes.uiProvider||this.defaultUI||Ext.tree.TreeNodeUI;this.ui=new b(this)},preventHScroll:true,isExpanded:function(){return this.expanded},getUI:function(){return this.ui},getLoader:function(){var a;return this.loader||((a=this.getOwnerTree())&&a.loader?a.loader:(this.loader=new Ext.tree.TreeLoader()))},setFirstChild:function(a){var b=this.firstChild;Ext.tree.TreeNode.superclass.setFirstChild.call(this,a);if(this.childrenRendered&&b&&a!=b){b.renderIndent(true,true)}if(this.rendered){this.renderIndent(true,true)}},setLastChild:function(b){var a=this.lastChild;Ext.tree.TreeNode.superclass.setLastChild.call(this,b);if(this.childrenRendered&&a&&b!=a){a.renderIndent(true,true)}if(this.rendered){this.renderIndent(true,true)}},appendChild:function(b){if(!b.render&&!Ext.isArray(b)){b=this.getLoader().createNode(b)}var a=Ext.tree.TreeNode.superclass.appendChild.call(this,b);if(a&&this.childrenRendered){a.render()}this.ui.updateExpandIcon();return a},removeChild:function(b,a){this.ownerTree.getSelectionModel().unselect(b);Ext.tree.TreeNode.superclass.removeChild.apply(this,arguments);if(!a){var c=b.ui.rendered;if(c){b.ui.remove()}if(c&&this.childNodes.length<1){this.collapse(false,false)}else{this.ui.updateExpandIcon()}if(!this.firstChild&&!this.isHiddenRoot()){this.childrenRendered=false}}return b},insertBefore:function(c,a){if(!c.render){c=this.getLoader().createNode(c)}var b=Ext.tree.TreeNode.superclass.insertBefore.call(this,c,a);if(b&&a&&this.childrenRendered){c.render()}this.ui.updateExpandIcon();return b},setText:function(b){var a=this.text;this.text=this.attributes.text=b;if(this.rendered){this.ui.onTextChange(this,b,a)}this.fireEvent("textchange",this,b,a)},setIconCls:function(b){var a=this.attributes.iconCls;this.attributes.iconCls=b;if(this.rendered){this.ui.onIconClsChange(this,b,a)}},setTooltip:function(a,b){this.attributes.qtip=a;this.attributes.qtipTitle=b;if(this.rendered){this.ui.onTipChange(this,a,b)}},setIcon:function(a){this.attributes.icon=a;if(this.rendered){this.ui.onIconChange(this,a)}},setHref:function(a,b){this.attributes.href=a;this.attributes.hrefTarget=b;if(this.rendered){this.ui.onHrefChange(this,a,b)}},setCls:function(b){var a=this.attributes.cls;this.attributes.cls=b;if(this.rendered){this.ui.onClsChange(this,b,a)}},select:function(){var a=this.getOwnerTree();if(a){a.getSelectionModel().select(this)}},unselect:function(a){var b=this.getOwnerTree();if(b){b.getSelectionModel().unselect(this,a)}},isSelected:function(){var a=this.getOwnerTree();return a?a.getSelectionModel().isSelected(this):false},expand:function(a,c,d,b){if(!this.expanded){if(this.fireEvent("beforeexpand",this,a,c)===false){return}if(!this.childrenRendered){this.renderChildren()}this.expanded=true;if(!this.isHiddenRoot()&&(this.getOwnerTree().animate&&c!==false)||c){this.ui.animExpand(function(){this.fireEvent("expand",this);this.runCallback(d,b||this,[this]);if(a===true){this.expandChildNodes(true,true)}}.createDelegate(this));return}else{this.ui.expand();this.fireEvent("expand",this);this.runCallback(d,b||this,[this])}}else{this.runCallback(d,b||this,[this])}if(a===true){this.expandChildNodes(true)}},runCallback:function(a,c,b){if(Ext.isFunction(a)){a.apply(c,b)}},isHiddenRoot:function(){return this.isRoot&&!this.getOwnerTree().rootVisible},collapse:function(b,g,h,e){if(this.expanded&&!this.isHiddenRoot()){if(this.fireEvent("beforecollapse",this,b,g)===false){return}this.expanded=false;if((this.getOwnerTree().animate&&g!==false)||g){this.ui.animCollapse(function(){this.fireEvent("collapse",this);this.runCallback(h,e||this,[this]);if(b===true){this.collapseChildNodes(true)}}.createDelegate(this));return}else{this.ui.collapse();this.fireEvent("collapse",this);this.runCallback(h,e||this,[this])}}else{if(!this.expanded){this.runCallback(h,e||this,[this])}}if(b===true){var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){d[c].collapse(true,false)}}},delayedExpand:function(a){if(!this.expandProcId){this.expandProcId=this.expand.defer(a,this)}},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId)}this.expandProcId=false},toggle:function(){if(this.expanded){this.collapse()}else{this.expand()}},ensureVisible:function(c,b){var a=this.getOwnerTree();a.expandPath(this.parentNode?this.parentNode.getPath():this.getPath(),false,function(){var d=a.getNodeById(this.id);a.getTreeEl().scrollChildIntoView(d.ui.anchor);this.runCallback(c,b||this,[this])}.createDelegate(this))},expandChildNodes:function(b,e){var d=this.childNodes,c,a=d.length;for(c=0;c<a;c++){d[c].expand(b,e)}},collapseChildNodes:function(b){var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){d[c].collapse(b)}},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(b){if(b!==false){this.fireEvent("beforechildrenrendered",this)}var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){d[c].render(true)}this.childrenRendered=true},sort:function(e,d){Ext.tree.TreeNode.superclass.sort.apply(this,arguments);if(this.childrenRendered){var c=this.childNodes;for(var b=0,a=c.length;b<a;b++){c[b].render(true)}}},render:function(a){this.ui.render(a);if(!this.rendered){this.getOwnerTree().registerNode(this);this.rendered=true;if(this.expanded){this.expanded=false;this.expand(false,false)}}},renderIndent:function(b,e){if(e){this.ui.childIndent=null}this.ui.renderIndent();if(b===true&&this.childrenRendered){var d=this.childNodes;for(var c=0,a=d.length;c<a;c++){d[c].renderIndent(true,e)}}},beginUpdate:function(){this.childrenRendered=false},endUpdate:function(){if(this.expanded&&this.rendered){this.renderChildren()}},destroy:function(a){if(a===true){this.unselect(true)}Ext.tree.TreeNode.superclass.destroy.call(this,a);Ext.destroy(this.ui,this.loader);this.ui=this.loader=null},onIdChange:function(a){this.ui.onIdChange(a)}});Ext.tree.TreePanel.nodeTypes.node=Ext.tree.TreeNode;Ext.tree.AsyncTreeNode=function(a){this.loaded=a&&a.loaded===true;this.loading=false;Ext.tree.AsyncTreeNode.superclass.constructor.apply(this,arguments);this.addEvents("beforeload","load")};Ext.extend(Ext.tree.AsyncTreeNode,Ext.tree.TreeNode,{expand:function(b,e,h,c){if(this.loading){var g;var d=function(){if(!this.loading){clearInterval(g);this.expand(b,e,h,c)}}.createDelegate(this);g=setInterval(d,200);return}if(!this.loaded){if(this.fireEvent("beforeload",this)===false){return}this.loading=true;this.ui.beforeLoad(this);var a=this.loader||this.attributes.loader||this.getOwnerTree().getLoader();if(a){a.load(this,this.loadComplete.createDelegate(this,[b,e,h,c]),this);return}}Ext.tree.AsyncTreeNode.superclass.expand.call(this,b,e,h,c)},isLoading:function(){return this.loading},loadComplete:function(a,c,d,b){this.loading=false;this.loaded=true;this.ui.afterLoad(this);this.fireEvent("load",this);this.expand(a,c,d,b)},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,a){this.collapse(false,false);while(this.firstChild){this.removeChild(this.firstChild).destroy()}this.childrenRendered=false;this.loaded=false;if(this.isHiddenRoot()){this.expanded=false}this.expand(false,false,b,a)}});Ext.tree.TreePanel.nodeTypes.async=Ext.tree.AsyncTreeNode;Ext.tree.TreeNodeUI=Ext.extend(Object,{constructor:function(a){Ext.apply(this,{node:a,rendered:false,animating:false,wasLeaf:true,ecc:"x-tree-ec-icon x-tree-elbow",emptyIcon:Ext.BLANK_IMAGE_URL})},removeChild:function(a){if(this.rendered){this.ctNode.removeChild(a.ui.getEl())}},beforeLoad:function(){this.addClass("x-tree-node-loading")},afterLoad:function(){this.removeClass("x-tree-node-loading")},onTextChange:function(b,c,a){if(this.rendered){this.textNode.innerHTML=c}},onIconClsChange:function(c,a,b){if(this.rendered){Ext.fly(this.iconNode).replaceClass(b,a)}},onIconChange:function(b,a){if(this.rendered){var c=Ext.isEmpty(a);this.iconNode.src=c?this.emptyIcon:a;Ext.fly(this.iconNode)[c?"removeClass":"addClass"]("x-tree-node-inline-icon")}},onTipChange:function(b,c,d){if(this.rendered){var a=Ext.isDefined(d);if(this.textNode.setAttributeNS){this.textNode.setAttributeNS("ext","qtip",c);if(a){this.textNode.setAttributeNS("ext","qtitle",d)}}else{this.textNode.setAttribute("ext:qtip",c);if(a){this.textNode.setAttribute("ext:qtitle",d)}}}},onHrefChange:function(b,a,c){if(this.rendered){this.anchor.href=this.getHref(a);if(Ext.isDefined(c)){this.anchor.target=c}}},onClsChange:function(c,a,b){if(this.rendered){Ext.fly(this.elNode).replaceClass(b,a)}},onDisableChange:function(a,b){this.disabled=b;if(this.checkbox){this.checkbox.disabled=b}this[b?"addClass":"removeClass"]("x-tree-node-disabled")},onSelectedChange:function(a){if(a){this.focus();this.addClass("x-tree-selected")}else{this.removeClass("x-tree-selected")}},onMove:function(a,h,e,g,d,b){this.childIndent=null;if(this.rendered){var i=g.ui.getContainer();if(!i){this.holder=document.createElement("div");this.holder.appendChild(this.wrap);return}var c=b?b.ui.getEl():null;if(c){i.insertBefore(this.wrap,c)}else{i.appendChild(this.wrap)}this.node.renderIndent(true,e!=g)}},addClass:function(a){if(this.elNode){Ext.fly(this.elNode).addClass(a)}},removeClass:function(a){if(this.elNode){Ext.fly(this.elNode).removeClass(a)}},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);if(this.node.disabled){this.onDisableChange(this.node,true)}if(this.node.hidden){this.hide()}var b=this.node.getOwnerTree();var a=b.enableDD||b.enableDrag||b.enableDrop;if(a&&(!this.node.isRoot||b.rootVisible)){Ext.dd.Registry.register(this.elNode,{node:this.node,handles:this.getDDHandles(),isHandle:false})}},getDDHandles:function(){return[this.iconNode,this.textNode,this.elNode]},hide:function(){this.node.hidden=true;if(this.wrap){this.wrap.style.display="none"}},show:function(){this.node.hidden=false;if(this.wrap){this.wrap.style.display=""}},onContextMenu:function(a){if(this.node.hasListener("contextmenu")||this.node.getOwnerTree().hasListener("contextmenu")){a.preventDefault();this.focus();this.fireEvent("contextmenu",this.node,a)}},onClick:function(c){if(this.dropping){c.stopEvent();return}if(this.fireEvent("beforeclick",this.node,c)!==false){var b=c.getTarget("a");if(!this.disabled&&this.node.attributes.href&&b){this.fireEvent("click",this.node,c);return}else{if(b&&c.ctrlKey){c.stopEvent()}}c.preventDefault();if(this.disabled){return}if(this.node.attributes.singleClickExpand&&!this.animating&&this.node.isExpandable()){this.node.toggle()}this.fireEvent("click",this.node,c)}else{c.stopEvent()}},onDblClick:function(a){a.preventDefault();if(this.disabled){return}if(this.fireEvent("beforedblclick",this.node,a)!==false){if(this.checkbox){this.toggleCheck()}if(!this.animating&&this.node.isExpandable()){this.node.toggle()}this.fireEvent("dblclick",this.node,a)}},onOver:function(a){this.addClass("x-tree-node-over")},onOut:function(a){this.removeClass("x-tree-node-over")},onCheckChange:function(){var a=this.checkbox.checked;this.checkbox.defaultChecked=a;this.node.attributes.checked=a;this.fireEvent("checkchange",this.node,a)},ecClick:function(a){if(!this.animating&&this.node.isExpandable()){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(c){}}else{try{var b=this.node.getOwnerTree().getTreeEl().dom;var a=b.scrollLeft;this.anchor.focus();b.scrollLeft=a}catch(c){}}},toggleCheck:function(b){var a=this.checkbox;if(a){a.checked=(b===undefined?!a.checked:b);this.onCheckChange()}},blur:function(){try{this.anchor.blur()}catch(a){}},animExpand:function(b){var a=Ext.get(this.ctNode);a.stopFx();if(!this.node.isExpandable()){this.updateExpandIcon();this.ctNode.style.display="";Ext.callback(b);return}this.animating=true;this.updateExpandIcon();a.slideIn("t",{callback:function(){this.animating=false;Ext.callback(b)},scope:this,duration:this.node.ownerTree.duration||0.25})},highlight:function(){var a=this.node.getOwnerTree();Ext.fly(this.wrap).highlight(a.hlColor||"C3DAF9",{endColor:a.hlBaseColor})},collapse:function(){this.updateExpandIcon();this.ctNode.style.display="none"},animCollapse:function(b){var a=Ext.get(this.ctNode);a.enableDisplayMode("block");a.stopFx();this.animating=true;this.updateExpandIcon();a.slideOut("t",{callback:function(){this.animating=false;Ext.callback(b)},scope:this,duration:this.node.ownerTree.duration||0.25})},getContainer:function(){return this.ctNode},getEl:function(){return this.wrap},appendDDGhost:function(a){a.appendChild(this.elNode.cloneNode(true))},getDDRepairXY:function(){return Ext.lib.Dom.getXY(this.iconNode)},onRender:function(){this.render()},render:function(c){var e=this.node,b=e.attributes;var d=e.parentNode?e.parentNode.ui.getContainer():e.ownerTree.innerCt.dom;if(!this.rendered){this.rendered=true;this.renderElements(e,b,d,c);if(b.qtip){this.onTipChange(e,b.qtip,b.qtipTitle)}else{if(b.qtipCfg){b.qtipCfg.target=Ext.id(this.textNode);Ext.QuickTips.register(b.qtipCfg)}}this.initEvents();if(!this.node.expanded){this.updateExpandIcon(true)}}else{if(c===true){d.appendChild(this.wrap)}}},renderElements:function(e,k,j,l){this.indentMarkup=e.parentNode?e.parentNode.ui.getChildIndent():"";var g=Ext.isBoolean(k.checked),b,c=this.getHref(k.href),d=['<li class="x-tree-node"><div ext:tree-node-id="',e.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ',k.cls,'" unselectable="on">','<span class="x-tree-node-indent">',this.indentMarkup,"</span>",'<img alt="" src="',this.emptyIcon,'" class="x-tree-ec-icon x-tree-elbow" />','<img alt="" src="',k.icon||this.emptyIcon,'" class="x-tree-node-icon',(k.icon?" x-tree-node-inline-icon":""),(k.iconCls?" "+k.iconCls:""),'" unselectable="on" />',g?('<input class="x-tree-node-cb" type="checkbox" '+(k.checked?'checked="checked" />':"/>")):"",'<a hidefocus="on" class="x-tree-node-anchor" href="',c,'" tabIndex="1" ',k.hrefTarget?' target="'+k.hrefTarget+'"':"",'><span unselectable="on">',e.text,"</span></a></div>",'<ul class="x-tree-node-ct" style="display:none;"></ul>',"</li>"].join("");if(l!==true&&e.nextSibling&&(b=e.nextSibling.ui.getEl())){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",b,d)}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",j,d)}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1];var i=this.elNode.childNodes;this.indentNode=i[0];this.ecNode=i[1];this.iconNode=i[2];var h=3;if(g){this.checkbox=i[3];this.checkbox.defaultChecked=this.checkbox.checked;h++}this.anchor=i[h];this.textNode=i[h].firstChild},getHref:function(a){return Ext.isEmpty(a)?(Ext.isGecko?"":"#"):a},getAnchor:function(){return this.anchor},getTextEl:function(){return this.textNode},getIconEl:function(){return this.iconNode},isChecked:function(){return this.checkbox?this.checkbox.checked:false},updateExpandIcon:function(){if(this.rendered){var g=this.node,d,c,a=g.isLast()?"x-tree-elbow-end":"x-tree-elbow",e=g.hasChildNodes();if(e||g.attributes.expandable){if(g.expanded){a+="-minus";d="x-tree-node-collapsed";c="x-tree-node-expanded"}else{a+="-plus";d="x-tree-node-expanded";c="x-tree-node-collapsed"}if(this.wasLeaf){this.removeClass("x-tree-node-leaf");this.wasLeaf=false}if(this.c1!=d||this.c2!=c){Ext.fly(this.elNode).replaceClass(d,c);this.c1=d;this.c2=c}}else{if(!this.wasLeaf){Ext.fly(this.elNode).replaceClass("x-tree-node-expanded","x-tree-node-collapsed");delete this.c1;delete this.c2;this.wasLeaf=true}}var b="x-tree-ec-icon "+a;if(this.ecc!=b){this.ecNode.className=b;this.ecc=b}}},onIdChange:function(a){if(this.rendered){this.elNode.setAttribute("ext:tree-node-id",a)}},getChildIndent:function(){if(!this.childIndent){var a=[],b=this.node;while(b){if(!b.isRoot||(b.isRoot&&b.ownerTree.rootVisible)){if(!b.isLast()){a.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />')}else{a.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />')}}b=b.parentNode}this.childIndent=a.join("")}return this.childIndent},renderIndent:function(){if(this.rendered){var a="",b=this.node.parentNode;if(b){a=b.ui.getChildIndent()}if(this.indentMarkup!=a){this.indentNode.innerHTML=a;this.indentMarkup=a}this.updateExpandIcon()}},destroy:function(){if(this.elNode){Ext.dd.Registry.unregister(this.elNode.id)}Ext.each(["textnode","anchor","checkbox","indentNode","ecNode","iconNode","elNode","ctNode","wrap","holder"],function(a){if(this[a]){Ext.fly(this[a]).remove();delete this[a]}},this);delete this.node}});Ext.tree.RootTreeNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{render:function(){if(!this.rendered){var a=this.node.ownerTree.innerCt.dom;this.node.expanded=true;a.innerHTML='<div class="x-tree-root-node"></div>';this.wrap=this.ctNode=a.firstChild}},collapse:Ext.emptyFn,expand:Ext.emptyFn});Ext.tree.TreeLoader=function(a){this.baseParams={};Ext.apply(this,a);this.addEvents("beforeload","load","loadexception");Ext.tree.TreeLoader.superclass.constructor.call(this);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}};Ext.extend(Ext.tree.TreeLoader,Ext.util.Observable,{uiProviders:{},clearOnLoad:true,paramOrder:undefined,paramsAsHash:false,nodeParameter:"node",directFn:undefined,load:function(b,c,a){if(this.clearOnLoad){while(b.firstChild){b.removeChild(b.firstChild)}}if(this.doPreload(b)){this.runCallback(c,a||b,[b])}else{if(this.directFn||this.dataUrl||this.url){this.requestData(b,c,a||b)}}},doPreload:function(d){if(d.attributes.children){if(d.childNodes.length<1){var c=d.attributes.children;d.beginUpdate();for(var b=0,a=c.length;b<a;b++){var e=d.appendChild(this.createNode(c[b]));if(this.preloadChildren){this.doPreload(e)}}d.endUpdate()}return true}return false},getParams:function(g){var e=Ext.apply({},this.baseParams),h=this.nodeParameter,b=this.paramOrder;h&&(e[h]=g.id);if(this.directFn){var c=[g.id];if(b){if(h&&b.indexOf(h)>-1){c=[]}for(var d=0,a=b.length;d<a;d++){c.push(e[b[d]])}}else{if(this.paramsAsHash){c=[e]}}return c}else{return e}},requestData:function(c,d,b){if(this.fireEvent("beforeload",this,c,d)!==false){if(this.directFn){var a=this.getParams(c);a.push(this.processDirectResponse.createDelegate(this,[{callback:d,node:c,scope:b}],true));this.directFn.apply(window,a)}else{this.transId=Ext.Ajax.request({method:this.requestMethod,url:this.dataUrl||this.url,success:this.handleResponse,failure:this.handleFailure,scope:this,argument:{callback:d,node:c,scope:b},params:this.getParams(c)})}}else{this.runCallback(d,b||c,[])}},processDirectResponse:function(a,b,c){if(b.status){this.handleResponse({responseData:Ext.isArray(a)?a:null,responseText:a,argument:c})}else{this.handleFailure({argument:c})}},runCallback:function(a,c,b){if(Ext.isFunction(a)){a.apply(c,b)}},isLoading:function(){return !!this.transId},abort:function(){if(this.isLoading()){Ext.Ajax.abort(this.transId)}},createNode:function(attr){if(this.baseAttrs){Ext.applyIf(attr,this.baseAttrs)}if(this.applyLoader!==false&&!attr.loader){attr.loader=this}if(Ext.isString(attr.uiProvider)){attr.uiProvider=this.uiProviders[attr.uiProvider]||eval(attr.uiProvider)}if(attr.nodeType){return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr)}else{return attr.leaf?new Ext.tree.TreeNode(attr):new Ext.tree.AsyncTreeNode(attr)}},processResponse:function(d,c,k,l){var m=d.responseText;try{var a=d.responseData||Ext.decode(m);c.beginUpdate();for(var g=0,h=a.length;g<h;g++){var b=this.createNode(a[g]);if(b){c.appendChild(b)}}c.endUpdate();this.runCallback(k,l||c,[c])}catch(j){this.handleFailure(d)}},handleResponse:function(c){this.transId=false;var b=c.argument;this.processResponse(c,b.node,b.callback,b.scope);this.fireEvent("load",this,b.node,c)},handleFailure:function(c){this.transId=false;var b=c.argument;this.fireEvent("loadexception",this,b.node,c);this.runCallback(b.callback,b.scope||b.node,[b.node])},destroy:function(){this.abort();this.purgeListeners()}});Ext.tree.TreeFilter=function(a,b){this.tree=a;this.filtered={};Ext.apply(this,b)};Ext.tree.TreeFilter.prototype={clearBlank:false,reverse:false,autoClear:false,remove:false,filter:function(d,a,b){a=a||"text";var c;if(typeof d=="string"){var e=d.length;if(e==0&&this.clearBlank){this.clear();return}d=d.toLowerCase();c=function(g){return g.attributes[a].substr(0,e).toLowerCase()==d}}else{if(d.exec){c=function(g){return d.test(g.attributes[a])}}else{throw"Illegal filter type, must be string or regex"}}this.filterBy(c,null,b)},filterBy:function(d,c,b){b=b||this.tree.root;if(this.autoClear){this.clear()}var a=this.filtered,i=this.reverse;var e=function(k){if(k==b){return true}if(a[k.id]){return false}var j=d.call(c||k,k);if(!j||i){a[k.id]=k;k.ui.hide();return false}return true};b.cascade(e);if(this.remove){for(var h in a){if(typeof h!="function"){var g=a[h];if(g&&g.parentNode){g.parentNode.removeChild(g)}}}}},clear:function(){var b=this.tree;var a=this.filtered;for(var d in a){if(typeof d!="function"){var c=a[d];if(c){c.ui.show()}}}this.filtered={}}};Ext.tree.TreeSorter=Ext.extend(Object,{constructor:function(a,c){Ext.apply(this,c);a.on({scope:this,beforechildrenrendered:this.doSort,append:this.updateSort,insert:this.updateSort,textchange:this.updateSortParent});var e=this.dir&&this.dir.toLowerCase()=="desc",i=this.property||"text",d=this.sortType,h=this.folderSort,b=this.caseSensitive===true,g=this.leafAttr||"leaf";if(Ext.isString(d)){d=Ext.data.SortTypes[d]}this.sortFn=function(o,m){var k=o.attributes,j=m.attributes;if(h){if(k[g]&&!j[g]){return 1}if(!k[g]&&j[g]){return -1}}var n=k[i],l=j[i],q=d?d(n,o):(b?n:n.toUpperCase()),p=d?d(l,m):(b?l:l.toUpperCase());if(q<p){return e?1:-1}else{if(q>p){return e?-1:1}}return 0}},doSort:function(a){a.sort(this.sortFn)},updateSort:function(a,b){if(b.childrenRendered){this.doSort.defer(1,this,[b])}},updateSortParent:function(a){var b=a.parentNode;if(b&&b.childrenRendered){this.doSort.defer(1,this,[b])}}});if(Ext.dd.DropZone){Ext.tree.TreeDropZone=function(a,b){this.allowParentInsert=b.allowParentInsert||false;this.allowContainerDrop=b.allowContainerDrop||false;this.appendOnly=b.appendOnly||false;Ext.tree.TreeDropZone.superclass.constructor.call(this,a.getTreeEl(),b);this.tree=a;this.dragOverData={};this.lastInsertClass="x-tree-no-status"};Ext.extend(Ext.tree.TreeDropZone,Ext.dd.DropZone,{ddGroup:"TreeDD",expandDelay:1000,expandNode:function(a){if(a.hasChildNodes()&&!a.isExpanded()){a.expand(false,null,this.triggerCacheRefresh.createDelegate(this))}},queueExpand:function(a){this.expandProcId=this.expandNode.defer(this.expandDelay,this,[a])},cancelExpand:function(){if(this.expandProcId){clearTimeout(this.expandProcId);this.expandProcId=false}},isValidDropPoint:function(a,k,i,d,c){if(!a||!c){return false}var g=a.node;var h=c.node;if(!(g&&g.isTarget&&k)){return false}if(k=="append"&&g.allowChildren===false){return false}if((k=="above"||k=="below")&&(g.parentNode&&g.parentNode.allowChildren===false)){return false}if(h&&(g==h||h.contains(g))){return false}var b=this.dragOverData;b.tree=this.tree;b.target=g;b.data=c;b.point=k;b.source=i;b.rawEvent=d;b.dropNode=h;b.cancel=false;var j=this.tree.fireEvent("nodedragover",b);return b.cancel===false&&j!==false},getDropPoint:function(h,g,l){var m=g.node;if(m.isRoot){return m.allowChildren!==false?"append":false}var c=g.ddel;var o=Ext.lib.Dom.getY(c),j=o+c.offsetHeight;var i=Ext.lib.Event.getPageY(h);var k=m.allowChildren===false||m.isLeaf();if(this.appendOnly||m.parentNode.allowChildren===false){return k?false:"append"}var d=false;if(!this.allowParentInsert){d=m.hasChildNodes()&&m.isExpanded()}var a=(j-o)/(k?2:3);if(i>=o&&i<(o+a)){return"above"}else{if(!d&&(k||i>=j-a&&i<=j)){return"below"}else{return"append"}}},onNodeEnter:function(d,a,c,b){this.cancelExpand()},onContainerOver:function(a,c,b){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,c,b)){return this.dropAllowed}return this.dropNotAllowed},onNodeOver:function(b,i,h,g){var k=this.getDropPoint(h,b,i);var c=b.node;if(!this.expandProcId&&k=="append"&&c.hasChildNodes()&&!b.node.isExpanded()){this.queueExpand(c)}else{if(k!="append"){this.cancelExpand()}}var d=this.dropNotAllowed;if(this.isValidDropPoint(b,k,i,h,g)){if(k){var a=b.ddel;var j;if(k=="above"){d=b.node.isFirst()?"x-tree-drop-ok-above":"x-tree-drop-ok-between";j="x-tree-drag-insert-above"}else{if(k=="below"){d=b.node.isLast()?"x-tree-drop-ok-below":"x-tree-drop-ok-between";j="x-tree-drag-insert-below"}else{d="x-tree-drop-ok-append";j="x-tree-drag-append"}}if(this.lastInsertClass!=j){Ext.fly(a).replaceClass(this.lastInsertClass,j);this.lastInsertClass=j}}}return d},onNodeOut:function(d,a,c,b){this.cancelExpand();this.removeDropIndicators(d)},onNodeDrop:function(i,b,h,d){var a=this.getDropPoint(h,i,b);var g=i.node;g.ui.startDrop();if(!this.isValidDropPoint(i,a,b,h,d)){g.ui.endDrop();return false}var c=d.node||(b.getTreeNode?b.getTreeNode(d,g,a,h):null);return this.processDrop(g,d,a,b,h,c)},onContainerDrop:function(a,g,c){if(this.allowContainerDrop&&this.isValidDropPoint({ddel:this.tree.getRootNode().ui.elNode,node:this.tree.getRootNode()},"append",a,g,c)){var d=this.tree.getRootNode();d.ui.startDrop();var b=c.node||(a.getTreeNode?a.getTreeNode(c,d,"append",g):null);return this.processDrop(d,c,"append",a,g,b)}return false},processDrop:function(j,h,b,a,i,d){var g={tree:this.tree,target:j,data:h,point:b,source:a,rawEvent:i,dropNode:d,cancel:!d,dropStatus:false};var c=this.tree.fireEvent("beforenodedrop",g);if(c===false||g.cancel===true||!g.dropNode){j.ui.endDrop();return g.dropStatus}j=g.target;if(b=="append"&&!j.isExpanded()){j.expand(false,null,function(){this.completeDrop(g)}.createDelegate(this))}else{this.completeDrop(g)}return true},completeDrop:function(h){var d=h.dropNode,e=h.point,c=h.target;if(!Ext.isArray(d)){d=[d]}var g;for(var b=0,a=d.length;b<a;b++){g=d[b];if(e=="above"){c.parentNode.insertBefore(g,c)}else{if(e=="below"){c.parentNode.insertBefore(g,c.nextSibling)}else{c.appendChild(g)}}}g.ui.focus();if(Ext.enableFx&&this.tree.hlDrop){g.ui.highlight()}c.ui.endDrop();this.tree.fireEvent("nodedrop",h)},afterNodeMoved:function(a,c,g,d,b){if(Ext.enableFx&&this.tree.hlDrop){b.ui.focus();b.ui.highlight()}this.tree.fireEvent("nodedrop",this.tree,d,c,a,g)},getTree:function(){return this.tree},removeDropIndicators:function(b){if(b&&b.ddel){var a=b.ddel;Ext.fly(a).removeClass(["x-tree-drag-insert-above","x-tree-drag-insert-below","x-tree-drag-append"]);this.lastInsertClass="_noclass"}},beforeDragDrop:function(b,a,c){this.cancelExpand();return true},afterRepair:function(a){if(a&&Ext.enableFx){a.node.ui.highlight()}this.hideProxy()}})}if(Ext.dd.DragZone){Ext.tree.TreeDragZone=function(a,b){Ext.tree.TreeDragZone.superclass.constructor.call(this,a.innerCt,b);this.tree=a};Ext.extend(Ext.tree.TreeDragZone,Ext.dd.DragZone,{ddGroup:"TreeDD",onBeforeDrag:function(a,b){var c=a.node;return c&&c.draggable&&!c.disabled},onInitDrag:function(b){var a=this.dragData;this.tree.getSelectionModel().select(a.node);this.tree.eventModel.disable();this.proxy.update("");a.node.ui.appendDDGhost(this.proxy.ghost.dom);this.tree.fireEvent("startdrag",this.tree,a.node,b)},getRepairXY:function(b,a){return a.node.ui.getDDRepairXY()},onEndDrag:function(a,b){this.tree.eventModel.enable.defer(100,this.tree.eventModel);this.tree.fireEvent("enddrag",this.tree,a.node,b)},onValidDrop:function(a,b,c){this.tree.fireEvent("dragdrop",this.tree,this.dragData.node,a,b);this.hideProxy()},beforeInvalidDrop:function(a,c){var b=this.tree.getSelectionModel();b.clearSelections();b.select(this.dragData.node)},afterRepair:function(){if(Ext.enableFx&&this.tree.hlDrop){Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor||"c3daf9")}this.dragging=false}})}Ext.tree.TreeEditor=function(a,c,b){c=c||{};var d=c.events?c:new Ext.form.TextField(c);Ext.tree.TreeEditor.superclass.constructor.call(this,d,b);this.tree=a;if(!a.rendered){a.on("render",this.initEditor,this)}else{this.initEditor(a)}};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,editDelay:350,initEditor:function(a){a.on({scope:this,beforeclick:this.beforeNodeClick,dblclick:this.onNodeDblClick});this.on({scope:this,complete:this.updateNode,beforestartedit:this.fitToTree,specialkey:this.onSpecialKey});this.on("startedit",this.bindScroll,this,{delay:10})},fitToTree:function(b,c){var e=this.tree.getTreeEl().dom,d=c.dom;if(e.scrollLeft>d.offsetLeft){e.scrollLeft=d.offsetLeft}var a=Math.min(this.maxWidth,(e.clientWidth>20?e.clientWidth:e.offsetWidth)-Math.max(0,d.offsetLeft-e.scrollLeft)-5);this.setSize(a,"")},triggerEdit:function(a,c){this.completeEdit();if(a.attributes.editable!==false){this.editNode=a;if(this.tree.autoScroll){Ext.fly(a.ui.getEl()).scrollIntoView(this.tree.body)}var b=a.text||"";if(!Ext.isGecko&&Ext.isEmpty(a.text)){a.setText("&#160;")}this.autoEditTimer=this.startEdit.defer(this.editDelay,this,[a.ui.textNode,b]);return false}},bindScroll:function(){this.tree.getTreeEl().on("scroll",this.cancelEdit,this)},beforeNodeClick:function(a,b){clearTimeout(this.autoEditTimer);if(this.tree.getSelectionModel().isSelected(a)){b.stopEvent();return this.triggerEdit(a)}},onNodeDblClick:function(a,b){clearTimeout(this.autoEditTimer)},updateNode:function(a,b){this.tree.getTreeEl().un("scroll",this.cancelEdit,this);this.editNode.setText(b)},onHide:function(){Ext.tree.TreeEditor.superclass.onHide.call(this);if(this.editNode){this.editNode.ui.focus.defer(50,this.editNode.ui)}},onSpecialKey:function(c,b){var a=b.getKey();if(a==b.ESC){b.stopEvent();this.cancelEdit()}else{if(a==b.ENTER&&!b.hasModifier()){b.stopEvent();this.completeEdit()}}},onDestroy:function(){clearTimeout(this.autoEditTimer);Ext.tree.TreeEditor.superclass.onDestroy.call(this);var a=this.tree;a.un("beforeclick",this.beforeNodeClick,this);a.un("dblclick",this.onNodeDblClick,this)}});var swfobject=function(){var E="undefined",s="object",T="Shockwave Flash",X="ShockwaveFlash.ShockwaveFlash",r="application/x-shockwave-flash",S="SWFObjectExprInst",y="onreadystatechange",P=window,k=document,u=navigator,U=false,V=[i],p=[],O=[],J=[],m,R,F,C,K=false,a=false,o,H,n=true,N=function(){var ab=typeof k.getElementById!=E&&typeof k.getElementsByTagName!=E&&typeof k.createElement!=E,ai=u.userAgent.toLowerCase(),Z=u.platform.toLowerCase(),af=Z?(/win/).test(Z):/win/.test(ai),ad=Z?(/mac/).test(Z):/mac/.test(ai),ag=/webkit/.test(ai)?parseFloat(ai.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,Y=!+"\v1",ah=[0,0,0],ac=null;if(typeof u.plugins!=E&&typeof u.plugins[T]==s){ac=u.plugins[T].description;if(ac&&!(typeof u.mimeTypes!=E&&u.mimeTypes[r]&&!u.mimeTypes[r].enabledPlugin)){U=true;Y=false;ac=ac.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ah[0]=parseInt(ac.replace(/^(.*)\..*$/,"$1"),10);ah[1]=parseInt(ac.replace(/^.*\.(.*)\s.*$/,"$1"),10);ah[2]=/[a-zA-Z]/.test(ac)?parseInt(ac.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof P.ActiveXObject!=E){try{var ae=new ActiveXObject(X);if(ae){ac=ae.GetVariable("$version");if(ac){Y=true;ac=ac.split(" ")[1].split(",");ah=[parseInt(ac[0],10),parseInt(ac[1],10),parseInt(ac[2],10)]}}}catch(aa){}}}return{w3:ab,pv:ah,wk:ag,ie:Y,win:af,mac:ad}}(),l=function(){if(!N.w3){return}if((typeof k.readyState!=E&&k.readyState=="complete")||(typeof k.readyState==E&&(k.getElementsByTagName("body")[0]||k.body))){g()}if(!K){if(typeof k.addEventListener!=E){k.addEventListener("DOMContentLoaded",g,false)}if(N.ie&&N.win){k.attachEvent(y,function(){if(k.readyState=="complete"){k.detachEvent(y,arguments.callee);g()}});if(P==top){(function(){if(K){return}try{k.documentElement.doScroll("left")}catch(Y){setTimeout(arguments.callee,0);return}g()})()}}if(N.wk){(function(){if(K){return}if(!(/loaded|complete/).test(k.readyState)){setTimeout(arguments.callee,0);return}g()})()}t(g)}}();function g(){if(K){return}try{var aa=k.getElementsByTagName("body")[0].appendChild(D("span"));aa.parentNode.removeChild(aa)}catch(ab){return}K=true;var Y=V.length;for(var Z=0;Z<Y;Z++){V[Z]()}}function L(Y){if(K){Y()}else{V[V.length]=Y}}function t(Z){if(typeof P.addEventListener!=E){P.addEventListener("load",Z,false)}else{if(typeof k.addEventListener!=E){k.addEventListener("load",Z,false)}else{if(typeof P.attachEvent!=E){j(P,"onload",Z)}else{if(typeof P.onload=="function"){var Y=P.onload;P.onload=function(){Y();Z()}}else{P.onload=Z}}}}}function i(){I()}function W(){var Y=k.getElementsByTagName("body")[0];var ab=D(s);ab.setAttribute("type",r);var aa=Y.appendChild(ab);if(aa){var Z=0;(function(){if(typeof aa.GetVariable!=E){var ac=aa.GetVariable("$version");if(ac){ac=ac.split(" ")[1].split(",");N.pv=[parseInt(ac[0],10),parseInt(ac[1],10),parseInt(ac[2],10)]}}else{if(Z<10){Z++;setTimeout(arguments.callee,10);return}}Y.removeChild(ab);aa=null;I()})()}else{I()}}function I(){var ah=p.length;if(ah>0){for(var ag=0;ag<ah;ag++){var Z=p[ag].id;var ac=p[ag].callbackFn;var ab={success:false,id:Z};if(N.pv[0]>0){var af=c(Z);if(af){if(G(p[ag].swfVersion)&&!(N.wk&&N.wk<312)){x(Z,true);if(ac){ab.success=true;ab.ref=A(Z);ac(ab)}}else{if(p[ag].expressInstall&&B()){var aj={};aj.data=p[ag].expressInstall;aj.width=af.getAttribute("width")||"0";aj.height=af.getAttribute("height")||"0";if(af.getAttribute("class")){aj.styleclass=af.getAttribute("class")}if(af.getAttribute("align")){aj.align=af.getAttribute("align")}var ai={};var Y=af.getElementsByTagName("param");var ad=Y.length;for(var ae=0;ae<ad;ae++){if(Y[ae].getAttribute("name").toLowerCase()!="movie"){ai[Y[ae].getAttribute("name")]=Y[ae].getAttribute("value")}}Q(aj,ai,Z,ac)}else{q(af);if(ac){ac(ab)}}}}}else{x(Z,true);if(ac){var aa=A(Z);if(aa&&typeof aa.SetVariable!=E){ab.success=true;ab.ref=aa}ac(ab)}}}}}function A(ab){var Y=null;var Z=c(ab);if(Z&&Z.nodeName=="OBJECT"){if(typeof Z.SetVariable!=E){Y=Z}else{var aa=Z.getElementsByTagName(s)[0];if(aa){Y=aa}}}return Y}function B(){return !a&&G("6.0.65")&&(N.win||N.mac)&&!(N.wk&&N.wk<312)}function Q(ab,ac,Y,aa){a=true;F=aa||null;C={success:false,id:Y};var af=c(Y);if(af){if(af.nodeName=="OBJECT"){m=h(af);R=null}else{m=af;R=Y}ab.id=S;if(typeof ab.width==E||(!(/%$/).test(ab.width)&&parseInt(ab.width,10)<310)){ab.width="310"}if(typeof ab.height==E||(!(/%$/).test(ab.height)&&parseInt(ab.height,10)<137)){ab.height="137"}k.title=k.title.slice(0,47)+" - Flash Player Installation";var ae=N.ie&&N.win?"ActiveX":"PlugIn",ad="MMredirectURL="+P.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ae+"&MMdoctitle="+k.title;if(typeof ac.flashvars!=E){ac.flashvars+="&"+ad}else{ac.flashvars=ad}if(N.ie&&N.win&&af.readyState!=4){var Z=D("div");Y+="SWFObjectNew";Z.setAttribute("id",Y);af.parentNode.insertBefore(Z,af);af.style.display="none";(function(){if(af.readyState==4){af.parentNode.removeChild(af)}else{setTimeout(arguments.callee,10)}})()}v(ab,ac,Y)}}function q(Z){if(N.ie&&N.win&&Z.readyState!=4){var Y=D("div");Z.parentNode.insertBefore(Y,Z);Y.parentNode.replaceChild(h(Z),Y);Z.style.display="none";(function(){if(Z.readyState==4){Z.parentNode.removeChild(Z)}else{setTimeout(arguments.callee,10)}})()}else{Z.parentNode.replaceChild(h(Z),Z)}}function h(ad){var ab=D("div");if(N.win&&N.ie){ab.innerHTML=ad.innerHTML}else{var Z=ad.getElementsByTagName(s)[0];if(Z){var ae=Z.childNodes;if(ae){var Y=ae.length;for(var aa=0;aa<Y;aa++){if(!(ae[aa].nodeType==1&&ae[aa].nodeName=="PARAM")&&!(ae[aa].nodeType==8)){ab.appendChild(ae[aa].cloneNode(true))}}}}}return ab}function v(aj,ah,Z){var Y,ab=c(Z);if(N.wk&&N.wk<312){return Y}if(ab){if(typeof aj.id==E){aj.id=Z}if(N.ie&&N.win){var ai="";for(var af in aj){if(aj[af]!=Object.prototype[af]){if(af.toLowerCase()=="data"){ah.movie=aj[af]}else{if(af.toLowerCase()=="styleclass"){ai+=' class="'+aj[af]+'"'}else{if(af.toLowerCase()!="classid"){ai+=" "+af+'="'+aj[af]+'"'}}}}}var ag="";for(var ae in ah){if(ah[ae]!=Object.prototype[ae]){ag+='<param name="'+ae+'" value="'+ah[ae]+'" />'}}ab.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ai+">"+ag+"</object>";O[O.length]=aj.id;Y=c(aj.id)}else{var aa=D(s);aa.setAttribute("type",r);for(var ad in aj){if(aj[ad]!=Object.prototype[ad]){if(ad.toLowerCase()=="styleclass"){aa.setAttribute("class",aj[ad])}else{if(ad.toLowerCase()!="classid"){aa.setAttribute(ad,aj[ad])}}}}for(var ac in ah){if(ah[ac]!=Object.prototype[ac]&&ac.toLowerCase()!="movie"){e(aa,ac,ah[ac])}}ab.parentNode.replaceChild(aa,ab);Y=aa}}return Y}function e(aa,Y,Z){var ab=D("param");ab.setAttribute("name",Y);ab.setAttribute("value",Z);aa.appendChild(ab)}function z(Z){var Y=c(Z);if(Y&&Y.nodeName=="OBJECT"){if(N.ie&&N.win){Y.style.display="none";(function(){if(Y.readyState==4){b(Z)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.removeChild(Y)}}}function b(aa){var Z=c(aa);if(Z){for(var Y in Z){if(typeof Z[Y]=="function"){Z[Y]=null}}Z.parentNode.removeChild(Z)}}function c(aa){var Y=null;try{Y=k.getElementById(aa)}catch(Z){}return Y}function D(Y){return k.createElement(Y)}function j(aa,Y,Z){aa.attachEvent(Y,Z);J[J.length]=[aa,Y,Z]}function G(aa){var Z=N.pv,Y=aa.split(".");Y[0]=parseInt(Y[0],10);Y[1]=parseInt(Y[1],10)||0;Y[2]=parseInt(Y[2],10)||0;return(Z[0]>Y[0]||(Z[0]==Y[0]&&Z[1]>Y[1])||(Z[0]==Y[0]&&Z[1]==Y[1]&&Z[2]>=Y[2]))?true:false}function w(ad,Z,ae,ac){if(N.ie&&N.mac){return}var ab=k.getElementsByTagName("head")[0];if(!ab){return}var Y=(ae&&typeof ae=="string")?ae:"screen";if(ac){o=null;H=null}if(!o||H!=Y){var aa=D("style");aa.setAttribute("type","text/css");aa.setAttribute("media",Y);o=ab.appendChild(aa);if(N.ie&&N.win&&typeof k.styleSheets!=E&&k.styleSheets.length>0){o=k.styleSheets[k.styleSheets.length-1]}H=Y}if(N.ie&&N.win){if(o&&typeof o.addRule==s){o.addRule(ad,Z)}}else{if(o&&typeof k.createTextNode!=E){o.appendChild(k.createTextNode(ad+" {"+Z+"}"))}}}function x(aa,Y){if(!n){return}var Z=Y?"visible":"hidden";if(K&&c(aa)){c(aa).style.visibility=Z}else{w("#"+aa,"visibility:"+Z)}}function M(Z){var aa=/[\\\"<>\.;]/;var Y=aa.exec(Z)!=null;return Y&&typeof encodeURIComponent!=E?encodeURIComponent(Z):Z}var d=function(){if(N.ie&&N.win){window.attachEvent("onunload",function(){var ad=J.length;for(var ac=0;ac<ad;ac++){J[ac][0].detachEvent(J[ac][1],J[ac][2])}var aa=O.length;for(var ab=0;ab<aa;ab++){z(O[ab])}for(var Z in N){N[Z]=null}N=null;for(var Y in swfobject){swfobject[Y]=null}swfobject=null;window.detachEvent("onunload",arguments.callee)})}}();return{registerObject:function(ac,Y,ab,aa){if(N.w3&&ac&&Y){var Z={};Z.id=ac;Z.swfVersion=Y;Z.expressInstall=ab;Z.callbackFn=aa;p[p.length]=Z;x(ac,false)}else{if(aa){aa({success:false,id:ac})}}},getObjectById:function(Y){if(N.w3){return A(Y)}},embedSWF:function(ac,ai,af,ah,Z,ab,aa,ae,ag,ad){var Y={success:false,id:ai};if(N.w3&&!(N.wk&&N.wk<312)&&ac&&ai&&af&&ah&&Z){x(ai,false);L(function(){af+="";ah+="";var ak={};if(ag&&typeof ag===s){for(var am in ag){ak[am]=ag[am]}}ak.data=ac;ak.width=af;ak.height=ah;var an={};if(ae&&typeof ae===s){for(var al in ae){an[al]=ae[al]}}if(aa&&typeof aa===s){for(var aj in aa){if(typeof an.flashvars!=E){an.flashvars+="&"+aj+"="+aa[aj]}else{an.flashvars=aj+"="+aa[aj]}}}if(G(Z)){var ao=v(ak,an,ai);if(ak.id==ai){x(ai,true)}Y.success=true;Y.ref=ao}else{if(ab&&B()){ak.data=ab;Q(ak,an,ai,ad);return}else{x(ai,true)}}if(ad){ad(Y)}})}else{if(ad){ad(Y)}}},switchOffAutoHideShow:function(){n=false},ua:N,getFlashPlayerVersion:function(){return{major:N.pv[0],minor:N.pv[1],release:N.pv[2]}},hasFlashPlayerVersion:G,createSWF:function(aa,Z,Y){if(N.w3){return v(aa,Z,Y)}else{return undefined}},showExpressInstall:function(aa,ab,Y,Z){if(N.w3&&B()){Q(aa,ab,Y,Z)}},removeSWF:function(Y){if(N.w3){z(Y)}},createCSS:function(ab,aa,Z,Y){if(N.w3){w(ab,aa,Z,Y)}},addDomLoadEvent:L,addLoadEvent:t,getQueryParamValue:function(ab){var aa=k.location.search||k.location.hash;if(aa){if(/\?/.test(aa)){aa=aa.split("?")[1]}if(ab==null){return M(aa)}var Z=aa.split("&");for(var Y=0;Y<Z.length;Y++){if(Z[Y].substring(0,Z[Y].indexOf("="))==ab){return M(Z[Y].substring((Z[Y].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var Y=c(S);if(Y&&m){Y.parentNode.replaceChild(m,Y);if(R){x(R,true);if(N.ie&&N.win){m.style.display="block"}}if(F){F(C)}}a=false}}}}();Ext.FlashComponent=Ext.extend(Ext.BoxComponent,{flashVersion:"9.0.115",backgroundColor:"#ffffff",wmode:"opaque",flashVars:undefined,flashParams:undefined,url:undefined,swfId:undefined,swfWidth:"100%",swfHeight:"100%",expressInstall:false,initComponent:function(){Ext.FlashComponent.superclass.initComponent.call(this);this.addEvents("initialize")},onRender:function(){Ext.FlashComponent.superclass.onRender.apply(this,arguments);var b=Ext.apply({allowScriptAccess:"always",bgcolor:this.backgroundColor,wmode:this.wmode},this.flashParams),a=Ext.apply({allowedDomain:document.location.hostname,YUISwfId:this.getId(),YUIBridgeCallback:"Ext.FlashEventProxy.onEvent"},this.flashVars);new swfobject.embedSWF(this.url,this.id,this.swfWidth,this.swfHeight,this.flashVersion,this.expressInstall?Ext.FlashComponent.EXPRESS_INSTALL_URL:undefined,a,b);this.swf=Ext.getDom(this.id);this.el=Ext.get(this.swf)},getSwfId:function(){return this.swfId||(this.swfId="extswf"+(++Ext.Component.AUTO_ID))},getId:function(){return this.id||(this.id="extflashcmp"+(++Ext.Component.AUTO_ID))},onFlashEvent:function(a){switch(a.type){case"swfReady":this.initSwf();return;case"log":return}a.component=this;this.fireEvent(a.type.toLowerCase().replace(/event$/,""),a)},initSwf:function(){this.onSwfReady(!!this.isInitialized);this.isInitialized=true;this.fireEvent("initialize",this)},beforeDestroy:function(){if(this.rendered){swfobject.removeSWF(this.swf.id)}Ext.FlashComponent.superclass.beforeDestroy.call(this)},onSwfReady:Ext.emptyFn});Ext.FlashComponent.EXPRESS_INSTALL_URL="http://swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf";Ext.reg("flash",Ext.FlashComponent);Ext.FlashEventProxy={onEvent:function(c,b){var a=Ext.getCmp(c);if(a){a.onFlashEvent(b)}else{arguments.callee.defer(10,this,[c,b])}}};Ext.chart.Chart=Ext.extend(Ext.FlashComponent,{refreshBuffer:100,chartStyle:{padding:10,animationEnabled:true,font:{name:"Tahoma",color:4473924,size:11},dataTip:{padding:5,border:{color:10075112,size:1},background:{color:14346230,alpha:0.9},font:{name:"Tahoma",color:1393291,size:10,bold:true}}},extraStyle:null,seriesStyles:null,disableCaching:Ext.isIE||Ext.isOpera,disableCacheParam:"_dc",initComponent:function(){Ext.chart.Chart.superclass.initComponent.call(this);if(!this.url){this.url=Ext.chart.Chart.CHART_URL}if(this.disableCaching){this.url=Ext.urlAppend(this.url,String.format("{0}={1}",this.disableCacheParam,new Date().getTime()))}this.addEvents("itemmouseover","itemmouseout","itemclick","itemdoubleclick","itemdragstart","itemdrag","itemdragend","beforerefresh","refresh");this.store=Ext.StoreMgr.lookup(this.store)},setStyle:function(a,b){this.swf.setStyle(a,Ext.encode(b))},setStyles:function(a){this.swf.setStyles(Ext.encode(a))},setSeriesStyles:function(b){this.seriesStyles=b;var a=[];Ext.each(b,function(c){a.push(Ext.encode(c))});this.swf.setSeriesStyles(a)},setCategoryNames:function(a){this.swf.setCategoryNames(a)},setLegendRenderer:function(c,b){var a=this;b=b||a;a.removeFnProxy(a.legendFnName);a.legendFnName=a.createFnProxy(function(d){return c.call(b,d)});a.swf.setLegendLabelFunction(a.legendFnName)},setTipRenderer:function(c,b){var a=this;b=b||a;a.removeFnProxy(a.tipFnName);a.tipFnName=a.createFnProxy(function(h,e,g){var d=a.store.getAt(e);return c.call(b,a,d,e,g)});a.swf.setDataTipFunction(a.tipFnName)},setSeries:function(a){this.series=a;this.refresh()},bindStore:function(a,b){if(!b&&this.store){if(a!==this.store&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("datachanged",this.refresh,this);this.store.un("add",this.delayRefresh,this);this.store.un("remove",this.delayRefresh,this);this.store.un("update",this.delayRefresh,this);this.store.un("clear",this.refresh,this)}}if(a){a=Ext.StoreMgr.lookup(a);a.on({scope:this,datachanged:this.refresh,add:this.delayRefresh,remove:this.delayRefresh,update:this.delayRefresh,clear:this.refresh})}this.store=a;if(a&&!b){this.refresh()}},onSwfReady:function(b){Ext.chart.Chart.superclass.onSwfReady.call(this,b);var a;this.swf.setType(this.type);if(this.chartStyle){this.setStyles(Ext.apply({},this.extraStyle,this.chartStyle))}if(this.categoryNames){this.setCategoryNames(this.categoryNames)}if(this.tipRenderer){a=this.getFunctionRef(this.tipRenderer);this.setTipRenderer(a.fn,a.scope)}if(this.legendRenderer){a=this.getFunctionRef(this.legendRenderer);this.setLegendRenderer(a.fn,a.scope)}if(!b){this.bindStore(this.store,true)}this.refresh.defer(10,this)},delayRefresh:function(){if(!this.refreshTask){this.refreshTask=new Ext.util.DelayedTask(this.refresh,this)}this.refreshTask.delay(this.refreshBuffer)},refresh:function(){if(this.fireEvent("beforerefresh",this)!==false){var m=false;var k=[],c=this.store.data.items;for(var g=0,l=c.length;g<l;g++){k[g]=c[g].data}var e=[];var d=0;var n=null;var h=0;if(this.series){d=this.series.length;for(h=0;h<d;h++){n=this.series[h];var b={};for(var a in n){if(a=="style"&&n.style!==null){b.style=Ext.encode(n.style);m=true}else{b[a]=n[a]}}e.push(b)}}if(d>0){for(h=0;h<d;h++){n=e[h];if(!n.type){n.type=this.type}n.dataProvider=k}}else{e.push({type:this.type,dataProvider:k})}this.swf.setDataProvider(e);if(this.seriesStyles){this.setSeriesStyles(this.seriesStyles)}this.fireEvent("refresh",this)}},createFnProxy:function(a){var b="extFnProxy"+(++Ext.chart.Chart.PROXY_FN_ID);Ext.chart.Chart.proxyFunction[b]=a;return"Ext.chart.Chart.proxyFunction."+b},removeFnProxy:function(a){if(!Ext.isEmpty(a)){a=a.replace("Ext.chart.Chart.proxyFunction.","");delete Ext.chart.Chart.proxyFunction[a]}},getFunctionRef:function(a){if(Ext.isFunction(a)){return{fn:a,scope:this}}else{return{fn:a.fn,scope:a.scope||this}}},onDestroy:function(){if(this.refreshTask&&this.refreshTask.cancel){this.refreshTask.cancel()}Ext.chart.Chart.superclass.onDestroy.call(this);this.bindStore(null);this.removeFnProxy(this.tipFnName);this.removeFnProxy(this.legendFnName)}});Ext.reg("chart",Ext.chart.Chart);Ext.chart.Chart.PROXY_FN_ID=0;Ext.chart.Chart.proxyFunction={};Ext.chart.Chart.CHART_URL="http://yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf";Ext.chart.PieChart=Ext.extend(Ext.chart.Chart,{type:"pie",onSwfReady:function(a){Ext.chart.PieChart.superclass.onSwfReady.call(this,a);this.setDataField(this.dataField);this.setCategoryField(this.categoryField)},setDataField:function(a){this.dataField=a;this.swf.setDataField(a)},setCategoryField:function(a){this.categoryField=a;this.swf.setCategoryField(a)}});Ext.reg("piechart",Ext.chart.PieChart);Ext.chart.CartesianChart=Ext.extend(Ext.chart.Chart,{onSwfReady:function(a){Ext.chart.CartesianChart.superclass.onSwfReady.call(this,a);this.labelFn=[];if(this.xField){this.setXField(this.xField)}if(this.yField){this.setYField(this.yField)}if(this.xAxis){this.setXAxis(this.xAxis)}if(this.xAxes){this.setXAxes(this.xAxes)}if(this.yAxis){this.setYAxis(this.yAxis)}if(this.yAxes){this.setYAxes(this.yAxes)}if(Ext.isDefined(this.constrainViewport)){this.swf.setConstrainViewport(this.constrainViewport)}},setXField:function(a){this.xField=a;this.swf.setHorizontalField(a)},setYField:function(a){this.yField=a;this.swf.setVerticalField(a)},setXAxis:function(a){this.xAxis=this.createAxis("xAxis",a);this.swf.setHorizontalAxis(this.xAxis)},setXAxes:function(c){var b;for(var a=0;a<c.length;a++){b=this.createAxis("xAxis"+a,c[a]);this.swf.setHorizontalAxis(b)}},setYAxis:function(a){this.yAxis=this.createAxis("yAxis",a);this.swf.setVerticalAxis(this.yAxis)},setYAxes:function(c){var b;for(var a=0;a<c.length;a++){b=this.createAxis("yAxis"+a,c[a]);this.swf.setVerticalAxis(b)}},createAxis:function(b,d){var e=Ext.apply({},d),c,a;if(this[b]){a=this[b].labelFunction;this.removeFnProxy(a);this.labelFn.remove(a)}if(e.labelRenderer){c=this.getFunctionRef(e.labelRenderer);e.labelFunction=this.createFnProxy(function(g){return c.fn.call(c.scope,g)});delete e.labelRenderer;this.labelFn.push(e.labelFunction)}if(b.indexOf("xAxis")>-1&&e.position=="left"){e.position="bottom"}return e},onDestroy:function(){Ext.chart.CartesianChart.superclass.onDestroy.call(this);Ext.each(this.labelFn,function(a){this.removeFnProxy(a)},this)}});Ext.reg("cartesianchart",Ext.chart.CartesianChart);Ext.chart.LineChart=Ext.extend(Ext.chart.CartesianChart,{type:"line"});Ext.reg("linechart",Ext.chart.LineChart);Ext.chart.ColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"column"});Ext.reg("columnchart",Ext.chart.ColumnChart);Ext.chart.StackedColumnChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackcolumn"});Ext.reg("stackedcolumnchart",Ext.chart.StackedColumnChart);Ext.chart.BarChart=Ext.extend(Ext.chart.CartesianChart,{type:"bar"});Ext.reg("barchart",Ext.chart.BarChart);Ext.chart.StackedBarChart=Ext.extend(Ext.chart.CartesianChart,{type:"stackbar"});Ext.reg("stackedbarchart",Ext.chart.StackedBarChart);Ext.chart.Axis=function(a){Ext.apply(this,a)};Ext.chart.Axis.prototype={type:null,orientation:"horizontal",reverse:false,labelFunction:null,hideOverlappingLabels:true,labelSpacing:2};Ext.chart.NumericAxis=Ext.extend(Ext.chart.Axis,{type:"numeric",minimum:NaN,maximum:NaN,majorUnit:NaN,minorUnit:NaN,snapToUnits:true,alwaysShowZero:true,scale:"linear",roundMajorUnit:true,calculateByLabelSize:true,position:"left",adjustMaximumByMajorUnit:true,adjustMinimumByMajorUnit:true});Ext.chart.TimeAxis=Ext.extend(Ext.chart.Axis,{type:"time",minimum:null,maximum:null,majorUnit:NaN,majorTimeUnit:null,minorUnit:NaN,minorTimeUnit:null,snapToUnits:true,stackingEnabled:false,calculateByLabelSize:true});Ext.chart.CategoryAxis=Ext.extend(Ext.chart.Axis,{type:"category",categoryNames:null,calculateCategoryCount:false});Ext.chart.Series=function(a){Ext.apply(this,a)};Ext.chart.Series.prototype={type:null,displayName:null};Ext.chart.CartesianSeries=Ext.extend(Ext.chart.Series,{xField:null,yField:null,showInLegend:true,axis:"primary"});Ext.chart.ColumnSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"column"});Ext.chart.LineSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"line"});Ext.chart.BarSeries=Ext.extend(Ext.chart.CartesianSeries,{type:"bar"});Ext.chart.PieSeries=Ext.extend(Ext.chart.Series,{type:"pie",dataField:null,categoryField:null});Ext.menu.Menu=Ext.extend(Ext.Container,{minWidth:120,shadow:"sides",subMenuAlign:"tl-tr?",defaultAlign:"tl-bl?",allowOtherMenus:false,ignoreParentClicks:false,enableScrolling:true,maxHeight:null,scrollIncrement:24,showSeparator:true,defaultOffsets:[0,0],plain:false,floating:true,zIndex:15000,hidden:true,layout:"menu",hideMode:"offsets",scrollerHeight:8,autoLayout:true,defaultType:"menuitem",bufferResize:false,initComponent:function(){if(Ext.isArray(this.initialConfig)){Ext.apply(this,{items:this.initialConfig})}this.addEvents("click","mouseover","mouseout","itemclick");Ext.menu.MenuMgr.register(this);if(this.floating){Ext.EventManager.onWindowResize(this.hide,this)}else{if(this.initialConfig.hidden!==false){this.hidden=false}this.internalDefaults={hideOnClick:false}}Ext.menu.Menu.superclass.initComponent.call(this);if(this.autoLayout){var a=this.doLayout.createDelegate(this,[]);this.on({add:a,remove:a})}},getLayoutTarget:function(){return this.ul},onRender:function(b,a){if(!b){b=Ext.getBody()}var c={id:this.getId(),cls:"x-menu "+((this.floating)?"x-menu-floating x-layer ":"")+(this.cls||"")+(this.plain?" x-menu-plain":"")+(this.showSeparator?"":" x-menu-nosep"),style:this.style,cn:[{tag:"a",cls:"x-menu-focus",href:"#",onclick:"return false;",tabIndex:"-1"},{tag:"ul",cls:"x-menu-list"}]};if(this.floating){this.el=new Ext.Layer({shadow:this.shadow,dh:c,constrain:false,parentEl:b,zindex:this.zIndex})}else{this.el=b.createChild(c)}Ext.menu.Menu.superclass.onRender.call(this,b,a);if(!this.keyNav){this.keyNav=new Ext.menu.MenuNav(this)}this.focusEl=this.el.child("a.x-menu-focus");this.ul=this.el.child("ul.x-menu-list");this.mon(this.ul,{scope:this,click:this.onClick,mouseover:this.onMouseOver,mouseout:this.onMouseOut});if(this.enableScrolling){this.mon(this.el,{scope:this,delegate:".x-menu-scroller",click:this.onScroll,mouseover:this.deactivateActive})}},findTargetItem:function(b){var a=b.getTarget(".x-menu-list-item",this.ul,true);if(a&&a.menuItemId){return this.items.get(a.menuItemId)}},onClick:function(b){var a=this.findTargetItem(b);if(a){if(a.isFormField){this.setActiveItem(a)}else{if(a instanceof Ext.menu.BaseItem){if(a.menu&&this.ignoreParentClicks){a.expandMenu();b.preventDefault()}else{if(a.onClick){a.onClick(b);this.fireEvent("click",this,a,b)}}}}}},setActiveItem:function(a,b){if(a!=this.activeItem){this.deactivateActive();if((this.activeItem=a).isFormField){a.focus()}else{a.activate(b)}}else{if(b){a.expandMenu()}}},deactivateActive:function(){var b=this.activeItem;if(b){if(b.isFormField){if(b.collapse){b.collapse()}}else{b.deactivate()}delete this.activeItem}},tryActivate:function(g,e){var b=this.items;for(var c=g,a=b.length;c>=0&&c<a;c+=e){var d=b.get(c);if(d.isVisible()&&!d.disabled&&(d.canActivate||d.isFormField)){this.setActiveItem(d,false);return d}}return false},onMouseOver:function(b){var a=this.findTargetItem(b);if(a){if(a.canActivate&&!a.disabled){this.setActiveItem(a,true)}}this.over=true;this.fireEvent("mouseover",this,b,a)},onMouseOut:function(b){var a=this.findTargetItem(b);if(a){if(a==this.activeItem&&a.shouldDeactivate&&a.shouldDeactivate(b)){this.activeItem.deactivate();delete this.activeItem}}this.over=false;this.fireEvent("mouseout",this,b,a)},onScroll:function(d,b){if(d){d.stopEvent()}var a=this.ul.dom,c=Ext.fly(b).is(".x-menu-scroller-top");a.scrollTop+=this.scrollIncrement*(c?-1:1);if(c?a.scrollTop<=0:a.scrollTop+this.activeMax>=a.scrollHeight){this.onScrollerOut(null,b)}},onScrollerIn:function(d,b){var a=this.ul.dom,c=Ext.fly(b).is(".x-menu-scroller-top");if(c?a.scrollTop>0:a.scrollTop+this.activeMax<a.scrollHeight){Ext.fly(b).addClass(["x-menu-item-active","x-menu-scroller-active"])}},onScrollerOut:function(b,a){Ext.fly(a).removeClass(["x-menu-item-active","x-menu-scroller-active"])},show:function(b,c,a){if(this.floating){this.parentMenu=a;if(!this.el){this.render();this.doLayout(false,true)}this.showAt(this.el.getAlignToXY(b,c||this.defaultAlign,this.defaultOffsets),a)}else{Ext.menu.Menu.superclass.show.call(this)}},showAt:function(b,a){if(this.fireEvent("beforeshow",this)!==false){this.parentMenu=a;if(!this.el){this.render()}if(this.enableScrolling){this.el.setXY(b);b[1]=this.constrainScroll(b[1]);b=[this.el.adjustForConstraints(b)[0],b[1]]}else{b=this.el.adjustForConstraints(b)}this.el.setXY(b);this.el.show();Ext.menu.Menu.superclass.onShow.call(this);if(Ext.isIE9m){this.fireEvent("autosize",this);if(!Ext.isIE8){this.el.repaint()}}this.hidden=false;this.focus();this.fireEvent("show",this)}},constrainScroll:function(i){var b,d=this.ul.setHeight("auto").getHeight(),a=i,h,e,g,c;if(this.floating){e=Ext.fly(this.el.dom.parentNode);g=e.getScroll().top;c=e.getViewSize().height;h=i-g;b=this.maxHeight?this.maxHeight:c-h;if(d>c){b=c;a=i-h}else{if(b<d){a=i-(d-b);b=d}}}else{b=this.getHeight()}if(this.maxHeight){b=Math.min(this.maxHeight,b)}if(d>b&&b>0){this.activeMax=b-this.scrollerHeight*2-this.el.getFrameWidth("tb")-Ext.num(this.el.shadowOffset,0);this.ul.setHeight(this.activeMax);this.createScrollers();this.el.select(".x-menu-scroller").setDisplayed("")}else{this.ul.setHeight(d);this.el.select(".x-menu-scroller").setDisplayed("none")}this.ul.dom.scrollTop=0;return a},createScrollers:function(){if(!this.scroller){this.scroller={pos:0,top:this.el.insertFirst({tag:"div",cls:"x-menu-scroller x-menu-scroller-top",html:"&#160;"}),bottom:this.el.createChild({tag:"div",cls:"x-menu-scroller x-menu-scroller-bottom",html:"&#160;"})};this.scroller.top.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.topRepeater=new Ext.util.ClickRepeater(this.scroller.top,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.top],false)}});this.scroller.bottom.hover(this.onScrollerIn,this.onScrollerOut,this);this.scroller.bottomRepeater=new Ext.util.ClickRepeater(this.scroller.bottom,{listeners:{click:this.onScroll.createDelegate(this,[null,this.scroller.bottom],false)}})}},onLayout:function(){if(this.isVisible()){if(this.enableScrolling){this.constrainScroll(this.el.getTop())}if(this.floating){this.el.sync()}}},focus:function(){if(!this.hidden){this.doFocus.defer(50,this)}},doFocus:function(){if(!this.hidden){this.focusEl.focus()}},hide:function(a){if(!this.isDestroyed){this.deepHide=a;Ext.menu.Menu.superclass.hide.call(this);delete this.deepHide}},onHide:function(){Ext.menu.Menu.superclass.onHide.call(this);this.deactivateActive();if(this.el&&this.floating){this.el.hide()}var a=this.parentMenu;if(this.deepHide===true&&a){if(a.floating){a.hide(true)}else{a.deactivateActive()}}},lookupComponent:function(a){if(Ext.isString(a)){a=(a=="separator"||a=="-")?new Ext.menu.Separator():new Ext.menu.TextItem(a);this.applyDefaults(a)}else{if(Ext.isObject(a)){a=this.getMenuItem(a)}else{if(a.tagName||a.el){a=new Ext.BoxComponent({el:a})}}}return a},applyDefaults:function(b){if(!Ext.isString(b)){b=Ext.menu.Menu.superclass.applyDefaults.call(this,b);var a=this.internalDefaults;if(a){if(b.events){Ext.applyIf(b.initialConfig,a);Ext.apply(b,a)}else{Ext.applyIf(b,a)}}}return b},getMenuItem:function(a){a.ownerCt=this;if(!a.isXType){if(!a.xtype&&Ext.isBoolean(a.checked)){return new Ext.menu.CheckItem(a)}return Ext.create(a,this.defaultType)}return a},addSeparator:function(){return this.add(new Ext.menu.Separator())},addElement:function(a){return this.add(new Ext.menu.BaseItem({el:a}))},addItem:function(a){return this.add(a)},addMenuItem:function(a){return this.add(this.getMenuItem(a))},addText:function(a){return this.add(new Ext.menu.TextItem(a))},onDestroy:function(){Ext.EventManager.removeResizeListener(this.hide,this);var a=this.parentMenu;if(a&&a.activeChild==this){delete a.activeChild}delete this.parentMenu;Ext.menu.Menu.superclass.onDestroy.call(this);Ext.menu.MenuMgr.unregister(this);if(this.keyNav){this.keyNav.disable()}var b=this.scroller;if(b){Ext.destroy(b.topRepeater,b.bottomRepeater,b.top,b.bottom)}Ext.destroy(this.el,this.focusEl,this.ul)}});Ext.reg("menu",Ext.menu.Menu);Ext.menu.MenuNav=Ext.extend(Ext.KeyNav,function(){function a(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)-1,-1)){c.tryActivate(c.items.length-1,-1)}}function b(d,c){if(!c.tryActivate(c.items.indexOf(c.activeItem)+1,1)){c.tryActivate(0,1)}}return{constructor:function(c){Ext.menu.MenuNav.superclass.constructor.call(this,c.el);this.scope=this.menu=c},doRelay:function(g,d){var c=g.getKey();if(this.menu.activeItem&&this.menu.activeItem.isFormField&&c!=g.TAB){return false}if(!this.menu.activeItem&&g.isNavKeyPress()&&c!=g.SPACE&&c!=g.RETURN){this.menu.tryActivate(0,1);return false}return d.call(this.scope||this,g,this.menu)},tab:function(d,c){d.stopEvent();if(d.shiftKey){a(d,c)}else{b(d,c)}},up:a,down:b,right:function(d,c){if(c.activeItem){c.activeItem.expandMenu(true)}},left:function(d,c){c.hide();if(c.parentMenu&&c.parentMenu.activeItem){c.parentMenu.activeItem.activate()}},enter:function(d,c){if(c.activeItem){d.stopPropagation();c.activeItem.onClick(d);c.fireEvent("click",this,c.activeItem);return true}}}}());Ext.menu.MenuMgr=function(){var h,e,b,d={},a=false,l=new Date();function n(){h={};e=new Ext.util.MixedCollection();b=Ext.getDoc().addKeyListener(27,j);b.disable()}function j(){if(e&&e.length>0){var o=e.clone();o.each(function(p){p.hide()});return true}return false}function g(o){e.remove(o);if(e.length<1){b.disable();Ext.getDoc().un("mousedown",m);a=false}}function k(o){var p=e.last();l=new Date();e.add(o);if(!a){b.enable();Ext.getDoc().on("mousedown",m);a=true}if(o.parentMenu){o.getEl().setZIndex(parseInt(o.parentMenu.getEl().getStyle("z-index"),10)+3);o.parentMenu.activeChild=o}else{if(p&&!p.isDestroyed&&p.isVisible()){o.getEl().setZIndex(parseInt(p.getEl().getStyle("z-index"),10)+3)}}}function c(o){if(o.activeChild){o.activeChild.hide()}if(o.autoHideTimer){clearTimeout(o.autoHideTimer);delete o.autoHideTimer}}function i(o){var p=o.parentMenu;if(!p&&!o.allowOtherMenus){j()}else{if(p&&p.activeChild){p.activeChild.hide()}}}function m(o){if(l.getElapsed()>50&&e.length>0&&!o.getTarget(".x-menu")){j()}}return{hideAll:function(){return j()},register:function(o){if(!h){n()}h[o.id]=o;o.on({beforehide:c,hide:g,beforeshow:i,show:k})},get:function(o){if(typeof o=="string"){if(!h){return null}return h[o]}else{if(o.events){return o}else{if(typeof o.length=="number"){return new Ext.menu.Menu({items:o})}else{return Ext.create(o,"menu")}}}},unregister:function(o){delete h[o.id];o.un("beforehide",c);o.un("hide",g);o.un("beforeshow",i);o.un("show",k)},registerCheckable:function(o){var p=o.group;if(p){if(!d[p]){d[p]=[]}d[p].push(o)}},unregisterCheckable:function(o){var p=o.group;if(p){d[p].remove(o)}},onCheckChange:function(q,r){if(q.group&&r){var t=d[q.group],p=0,o=t.length,s;for(;p<o;p++){s=t[p];if(s!=q){s.setChecked(false)}}}},getCheckedItem:function(q){var r=d[q];if(r){for(var p=0,o=r.length;p<o;p++){if(r[p].checked){return r[p]}}}return null},setCheckedItem:function(q,s){var r=d[q];if(r){for(var p=0,o=r.length;p<o;p++){if(r[p].id==s){r[p].setChecked(true)}}}return null}}}();Ext.menu.BaseItem=Ext.extend(Ext.Component,{canActivate:false,activeClass:"x-menu-item-active",hideOnClick:true,clickHideDelay:1,ctype:"Ext.menu.BaseItem",actionMode:"container",initComponent:function(){Ext.menu.BaseItem.superclass.initComponent.call(this);this.addEvents("click","activate","deactivate");if(this.handler){this.on("click",this.handler,this.scope)}},onRender:function(b,a){Ext.menu.BaseItem.superclass.onRender.apply(this,arguments);if(this.ownerCt&&this.ownerCt instanceof Ext.menu.Menu){this.parentMenu=this.ownerCt}else{this.container.addClass("x-menu-list-item");this.mon(this.el,{scope:this,click:this.onClick,mouseenter:this.activate,mouseleave:this.deactivate})}},setHandler:function(b,a){if(this.handler){this.un("click",this.handler,this.scope)}this.on("click",this.handler=b,this.scope=a)},onClick:function(a){if(!this.disabled&&this.fireEvent("click",this,a)!==false&&(this.parentMenu&&this.parentMenu.fireEvent("itemclick",this,a)!==false)){this.handleClick(a)}else{a.stopEvent()}},activate:function(){if(this.disabled){return false}var a=this.container;a.addClass(this.activeClass);this.region=a.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(a){return !this.region||!this.region.contains(a.getPoint())},handleClick:function(b){var a=this.parentMenu;if(this.hideOnClick){if(a.floating){this.clickHideDelayTimer=a.hide.defer(this.clickHideDelay,a,[true])}else{a.deactivateActive()}}},beforeDestroy:function(){clearTimeout(this.clickHideDelayTimer);Ext.menu.BaseItem.superclass.beforeDestroy.call(this)},expandMenu:Ext.emptyFn,hideMenu:Ext.emptyFn});Ext.reg("menubaseitem",Ext.menu.BaseItem);Ext.menu.TextItem=Ext.extend(Ext.menu.BaseItem,{hideOnClick:false,itemCls:"x-menu-text",constructor:function(a){if(typeof a=="string"){a={text:a}}Ext.menu.TextItem.superclass.constructor.call(this,a)},onRender:function(){var a=document.createElement("span");a.className=this.itemCls;a.innerHTML=this.text;this.el=a;Ext.menu.TextItem.superclass.onRender.apply(this,arguments)}});Ext.reg("menutextitem",Ext.menu.TextItem);Ext.menu.Separator=Ext.extend(Ext.menu.BaseItem,{itemCls:"x-menu-sep",hideOnClick:false,activeClass:"",onRender:function(a){var b=document.createElement("span");b.className=this.itemCls;b.innerHTML="&#160;";this.el=b;a.addClass("x-menu-sep-li");Ext.menu.Separator.superclass.onRender.apply(this,arguments)}});Ext.reg("menuseparator",Ext.menu.Separator);Ext.menu.Item=Ext.extend(Ext.menu.BaseItem,{itemCls:"x-menu-item",canActivate:true,showDelay:200,altText:"",hideDelay:200,ctype:"Ext.menu.Item",initComponent:function(){Ext.menu.Item.superclass.initComponent.call(this);if(this.menu){if(Ext.isArray(this.menu)){this.menu={items:this.menu}}if(Ext.isObject(this.menu)){this.menu.ownerCt=this}this.menu=Ext.menu.MenuMgr.get(this.menu);this.menu.ownerCt=undefined}},onRender:function(d,b){if(!this.itemTpl){this.itemTpl=Ext.menu.Item.prototype.itemTpl=new Ext.XTemplate('<a id="{id}" class="{cls} x-unselectable" hidefocus="true" unselectable="on" href="{href}"','<tpl if="hrefTarget">',' target="{hrefTarget}"',"</tpl>",">",'<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>','<span class="x-menu-item-text">{text}</span>',"</a>")}var c=this.getTemplateArgs();this.el=b?this.itemTpl.insertBefore(b,c,true):this.itemTpl.append(d,c,true);this.iconEl=this.el.child("img.x-menu-item-icon");this.textEl=this.el.child(".x-menu-item-text");if(!this.href){this.mon(this.el,"click",Ext.emptyFn,null,{preventDefault:true})}Ext.menu.Item.superclass.onRender.call(this,d,b)},getTemplateArgs:function(){return{id:this.id,cls:this.itemCls+(this.menu?" x-menu-item-arrow":"")+(this.cls?" "+this.cls:""),href:this.href||"#",hrefTarget:this.hrefTarget,icon:this.icon||Ext.BLANK_IMAGE_URL,iconCls:this.iconCls||"",text:this.itemText||this.text||"&#160;",altText:this.altText||""}},setText:function(a){this.text=a||"&#160;";if(this.rendered){this.textEl.update(this.text);this.parentMenu.layout.doAutoSize()}},setIconClass:function(a){var b=this.iconCls;this.iconCls=a;if(this.rendered){this.iconEl.replaceClass(b,this.iconCls)}},beforeDestroy:function(){clearTimeout(this.showTimer);clearTimeout(this.hideTimer);if(this.menu){delete this.menu.ownerCt;this.menu.destroy()}Ext.menu.Item.superclass.beforeDestroy.call(this)},handleClick:function(a){if(!this.href){a.stopEvent()}Ext.menu.Item.superclass.handleClick.apply(this,arguments)},activate:function(a){if(Ext.menu.Item.superclass.activate.apply(this,arguments)){this.focus();if(a){this.expandMenu()}}return true},shouldDeactivate:function(a){if(Ext.menu.Item.superclass.shouldDeactivate.call(this,a)){if(this.menu&&this.menu.isVisible()){return !this.menu.getEl().getRegion().contains(a.getPoint())}return true}return false},deactivate:function(){Ext.menu.Item.superclass.deactivate.apply(this,arguments);this.hideMenu()},expandMenu:function(a){if(!this.disabled&&this.menu){clearTimeout(this.hideTimer);delete this.hideTimer;if(!this.menu.isVisible()&&!this.showTimer){this.showTimer=this.deferExpand.defer(this.showDelay,this,[a])}else{if(this.menu.isVisible()&&a){this.menu.tryActivate(0,1)}}}},deferExpand:function(a){delete this.showTimer;this.menu.show(this.container,this.parentMenu.subMenuAlign||"tl-tr?",this.parentMenu);if(a){this.menu.tryActivate(0,1)}},hideMenu:function(){clearTimeout(this.showTimer);delete this.showTimer;if(!this.hideTimer&&this.menu&&this.menu.isVisible()){this.hideTimer=this.deferHide.defer(this.hideDelay,this)}},deferHide:function(){delete this.hideTimer;if(this.menu.over){this.parentMenu.setActiveItem(this,false)}else{this.menu.hide()}}});Ext.reg("menuitem",Ext.menu.Item);Ext.menu.CheckItem=Ext.extend(Ext.menu.Item,{itemCls:"x-menu-item x-menu-check-item",groupClass:"x-menu-group-item",checked:false,ctype:"Ext.menu.CheckItem",initComponent:function(){Ext.menu.CheckItem.superclass.initComponent.call(this);this.addEvents("beforecheckchange","checkchange");if(this.checkHandler){this.on("checkchange",this.checkHandler,this.scope)}Ext.menu.MenuMgr.registerCheckable(this)},onRender:function(a){Ext.menu.CheckItem.superclass.onRender.apply(this,arguments);if(this.group){this.el.addClass(this.groupClass)}if(this.checked){this.checked=false;this.setChecked(true,true)}},destroy:function(){Ext.menu.MenuMgr.unregisterCheckable(this);Ext.menu.CheckItem.superclass.destroy.apply(this,arguments)},setChecked:function(b,a){var c=a===true;if(this.checked!=b&&(c||this.fireEvent("beforecheckchange",this,b)!==false)){Ext.menu.MenuMgr.onCheckChange(this,b);if(this.container){this.container[b?"addClass":"removeClass"]("x-menu-item-checked")}this.checked=b;if(!c){this.fireEvent("checkchange",this,b)}}},handleClick:function(a){if(!this.disabled&&!(this.checked&&this.group)){this.setChecked(!this.checked)}Ext.menu.CheckItem.superclass.handleClick.apply(this,arguments)}});Ext.reg("menucheckitem",Ext.menu.CheckItem);Ext.menu.DateMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,pickerId:null,cls:"x-date-menu",initComponent:function(){this.on("beforeshow",this.onBeforeShow,this);if(this.strict=(Ext.isIE7&&Ext.isStrict)){this.on("show",this.onShow,this,{single:true,delay:20})}Ext.apply(this,{plain:true,showSeparator:false,items:this.picker=new Ext.DatePicker(Ext.applyIf({internalRender:this.strict||!Ext.isIE9m,ctCls:"x-menu-date-item",id:this.pickerId},this.initialConfig))});this.picker.purgeListeners();Ext.menu.DateMenu.superclass.initComponent.call(this);this.relayEvents(this.picker,["select"]);this.on("show",this.picker.focus,this.picker);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}},onBeforeShow:function(){if(this.picker){this.picker.hideMonthPicker(true)}},onShow:function(){var a=this.picker.getEl();a.setWidth(a.getWidth())}});Ext.reg("datemenu",Ext.menu.DateMenu);Ext.menu.ColorMenu=Ext.extend(Ext.menu.Menu,{enableScrolling:false,hideOnClick:true,cls:"x-color-menu",paletteId:null,initComponent:function(){Ext.apply(this,{plain:true,showSeparator:false,items:this.palette=new Ext.ColorPalette(Ext.applyIf({id:this.paletteId},this.initialConfig))});this.palette.purgeListeners();Ext.menu.ColorMenu.superclass.initComponent.call(this);this.relayEvents(this.palette,["select"]);this.on("select",this.menuHide,this);if(this.handler){this.on("select",this.handler,this.scope||this)}},menuHide:function(){if(this.hideOnClick){this.hide(true)}}});Ext.reg("colormenu",Ext.menu.ColorMenu);Ext.form.Field=Ext.extend(Ext.BoxComponent,{invalidClass:"x-form-invalid",invalidText:"The value in this field is invalid",focusClass:"x-form-focus",validationEvent:"keyup",validateOnBlur:true,validationDelay:250,defaultAutoCreate:{tag:"input",type:"text",size:"20",autocomplete:"off"},fieldClass:"x-form-field",msgTarget:"qtip",msgFx:"normal",readOnly:false,disabled:false,submitValue:true,isFormField:true,msgDisplay:"",hasFocus:false,initComponent:function(){Ext.form.Field.superclass.initComponent.call(this);this.addEvents("focus","blur","specialkey","change","invalid","valid")},getName:function(){return this.rendered&&this.el.dom.name?this.el.dom.name:this.name||this.id||""},onRender:function(c,a){if(!this.el){var b=this.getAutoCreate();if(!b.name){b.name=this.name||this.id}if(this.inputType){b.type=this.inputType}this.autoEl=b}Ext.form.Field.superclass.onRender.call(this,c,a);if(this.submitValue===false){this.el.dom.removeAttribute("name")}var d=this.el.dom.type;if(d){if(d=="password"){d="text"}this.el.addClass("x-form-"+d)}if(this.readOnly){this.setReadOnly(true)}if(this.tabIndex!==undefined){this.el.dom.setAttribute("tabIndex",this.tabIndex)}this.el.addClass([this.fieldClass,this.cls])},getItemCt:function(){return this.itemCt},initValue:function(){if(this.value!==undefined){this.setValue(this.value)}else{if(!Ext.isEmpty(this.el.dom.value)&&this.el.dom.value!=this.emptyText){this.setValue(this.el.dom.value)}}this.originalValue=this.getValue()},isDirty:function(){if(this.disabled||!this.rendered){return false}return String(this.getValue())!==String(this.originalValue)},setReadOnly:function(a){if(this.rendered){this.el.dom.readOnly=a}this.readOnly=a},afterRender:function(){Ext.form.Field.superclass.afterRender.call(this);this.initEvents();this.initValue()},fireKey:function(a){if(a.isSpecialKey()){this.fireEvent("specialkey",this,a)}},reset:function(){this.setValue(this.originalValue);this.clearInvalid()},initEvents:function(){this.mon(this.el,Ext.EventManager.getKeyEvent(),this.fireKey,this);this.mon(this.el,"focus",this.onFocus,this);this.mon(this.el,"blur",this.onBlur,this,this.inEditor?{buffer:10}:null)},preFocus:Ext.emptyFn,onFocus:function(){this.preFocus();if(this.focusClass){this.el.addClass(this.focusClass)}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this)}},beforeBlur:Ext.emptyFn,onBlur:function(){this.beforeBlur();if(this.focusClass){this.el.removeClass(this.focusClass)}this.hasFocus=false;if(this.validationEvent!==false&&(this.validateOnBlur||this.validationEvent=="blur")){this.validate()}var a=this.getValue();if(String(a)!==String(this.startValue)){this.fireEvent("change",this,a,this.startValue)}this.fireEvent("blur",this);this.postBlur()},postBlur:Ext.emptyFn,isValid:function(a){if(this.disabled){return true}var c=this.preventMark;this.preventMark=a===true;var b=this.validateValue(this.processValue(this.getRawValue()),a);this.preventMark=c;return b},validate:function(){if(this.disabled||this.validateValue(this.processValue(this.getRawValue()))){this.clearInvalid();return true}return false},processValue:function(a){return a},validateValue:function(b){var a=this.getErrors(b)[0];if(a==undefined){return true}else{this.markInvalid(a);return false}},getErrors:function(){return[]},getActiveError:function(){return this.activeError||""},markInvalid:function(c){if(this.rendered&&!this.preventMark){c=c||this.invalidText;var a=this.getMessageHandler();if(a){a.mark(this,c)}else{if(this.msgTarget){this.el.addClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML=c;b.style.display=this.msgDisplay}}}}this.setActiveError(c)},clearInvalid:function(){if(this.rendered&&!this.preventMark){this.el.removeClass(this.invalidClass);var a=this.getMessageHandler();if(a){a.clear(this)}else{if(this.msgTarget){this.el.removeClass(this.invalidClass);var b=Ext.getDom(this.msgTarget);if(b){b.innerHTML="";b.style.display="none"}}}}this.unsetActiveError()},setActiveError:function(b,a){this.activeError=b;if(a!==true){this.fireEvent("invalid",this,b)}},unsetActiveError:function(a){delete this.activeError;if(a!==true){this.fireEvent("valid",this)}},getMessageHandler:function(){return Ext.form.MessageTargets[this.msgTarget]},getErrorCt:function(){return this.el.findParent(".x-form-element",5,true)||this.el.findParent(".x-form-field-wrap",5,true)},alignErrorEl:function(){this.errorEl.setWidth(this.getErrorCt().getWidth(true)-20)},alignErrorIcon:function(){this.errorIcon.alignTo(this.el,"tl-tr",[2,0])},getRawValue:function(){var a=this.rendered?this.el.getValue():Ext.value(this.value,"");if(a===this.emptyText){a=""}return a},getValue:function(){if(!this.rendered){return this.value}var a=this.el.getValue();if(a===this.emptyText||a===undefined){a=""}return a},setRawValue:function(a){return this.rendered?(this.el.dom.value=(Ext.isEmpty(a)?"":a)):""},setValue:function(a){this.value=a;if(this.rendered){this.el.dom.value=(Ext.isEmpty(a)?"":a);this.validate()}return this},append:function(a){this.setValue([this.getValue(),a].join(""))}});Ext.form.MessageTargets={qtip:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.qtip=b;a.el.dom.qclass="x-form-invalid-tip";if(Ext.QuickTips){Ext.QuickTips.enable()}},clear:function(a){a.el.removeClass(a.invalidClass);a.el.dom.qtip=""}},title:{mark:function(a,b){a.el.addClass(a.invalidClass);a.el.dom.title=b},clear:function(a){a.el.dom.title=""}},under:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorEl){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorEl=a.createChild({cls:"x-form-invalid-msg"});b.on("resize",b.alignErrorEl,b);b.on("destroy",function(){Ext.destroy(this.errorEl)},b)}b.alignErrorEl();b.errorEl.update(c);Ext.form.Field.msgFx[b.msgFx].show(b.errorEl,b)},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorEl){Ext.form.Field.msgFx[a.msgFx].hide(a.errorEl,a)}else{a.el.dom.title=""}}},side:{mark:function(b,c){b.el.addClass(b.invalidClass);if(!b.errorIcon){var a=b.getErrorCt();if(!a){b.el.dom.title=c;return}b.errorIcon=a.createChild({cls:"x-form-invalid-icon"});if(b.ownerCt){b.ownerCt.on("afterlayout",b.alignErrorIcon,b);b.ownerCt.on("expand",b.alignErrorIcon,b)}b.on("resize",b.alignErrorIcon,b);b.on("destroy",function(){Ext.destroy(this.errorIcon)},b)}b.alignErrorIcon();b.errorIcon.dom.qtip=c;b.errorIcon.dom.qclass="x-form-invalid-tip";b.errorIcon.show()},clear:function(a){a.el.removeClass(a.invalidClass);if(a.errorIcon){a.errorIcon.dom.qtip="";a.errorIcon.hide()}else{a.el.dom.title=""}}}};Ext.form.Field.msgFx={normal:{show:function(a,b){a.setDisplayed("block")},hide:function(a,b){a.setDisplayed(false).update("")}},slide:{show:function(a,b){a.slideIn("t",{stopFx:true})},hide:function(a,b){a.slideOut("t",{stopFx:true,useDisplay:true})}},slideRight:{show:function(a,b){a.fixDisplay();a.alignTo(b.el,"tl-tr");a.slideIn("l",{stopFx:true})},hide:function(a,b){a.slideOut("l",{stopFx:true,useDisplay:true})}}};Ext.reg("field",Ext.form.Field);Ext.form.TextField=Ext.extend(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",initComponent:function(){Ext.form.TextField.superclass.initComponent.call(this);this.addEvents("autosize","keydown","keyup","keypress")},initEvents:function(){Ext.form.TextField.superclass.initEvents.call(this);if(this.validationEvent=="keyup"){this.validationTask=new Ext.util.DelayedTask(this.validate,this);this.mon(this.el,"keyup",this.filterValidation,this)}else{if(this.validationEvent!==false&&this.validationEvent!="blur"){this.mon(this.el,this.validationEvent,this.validate,this,{buffer:this.validationDelay})}}if(this.selectOnFocus||this.emptyText){this.mon(this.el,"mousedown",this.onMouseDown,this);if(this.emptyText){this.applyEmptyText()}}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Ext.form.VTypes[this.vtype+"Mask"]))){this.mon(this.el,"keypress",this.filterKeys,this)}if(this.grow){this.mon(this.el,"keyup",this.onKeyUpBuffered,this,{buffer:50});this.mon(this.el,"click",this.autoSize,this)}if(this.enableKeyEvents){this.mon(this.el,{scope:this,keyup:this.onKeyUp,keydown:this.onKeyDown,keypress:this.onKeyPress})}},onMouseDown:function(a){if(!this.hasFocus){this.mon(this.el,"mouseup",Ext.emptyFn,this,{single:true,preventDefault:true})}},processValue:function(a){if(this.stripCharsRe){var b=a.replace(this.stripCharsRe,"");if(b!==a){this.setRawValue(b);return b}}return a},filterValidation:function(a){if(!a.isNavKeyPress()){this.validationTask.delay(this.validationDelay)}},onDisable:function(){Ext.form.TextField.superclass.onDisable.call(this);if(Ext.isIE){this.el.dom.unselectable="on"}},onEnable:function(){Ext.form.TextField.superclass.onEnable.call(this);if(Ext.isIE){this.el.dom.unselectable=""}},onKeyUpBuffered:function(a){if(this.doAutoSize(a)){this.autoSize()}},doAutoSize:function(a){return !a.isNavKeyPress()},onKeyUp:function(a){this.fireEvent("keyup",this,a)},onKeyDown:function(a){this.fireEvent("keydown",this,a)},onKeyPress:function(a){this.fireEvent("keypress",this,a)},reset:function(){Ext.form.TextField.superclass.reset.call(this);this.applyEmptyText()},applyEmptyText:function(){if(this.rendered&&this.emptyText&&this.getRawValue().length<1&&!this.hasFocus){this.setRawValue(this.emptyText);this.el.addClass(this.emptyClass)}},preFocus:function(){var a=this.el,b;if(this.emptyText){if(a.dom.value==this.emptyText){this.setRawValue("");b=true}a.removeClass(this.emptyClass)}if(this.selectOnFocus||b){a.dom.select()}},postBlur:function(){this.applyEmptyText()},filterKeys:function(b){if(b.ctrlKey){return}var a=b.getKey();if(Ext.isGecko&&(b.isNavKeyPress()||a==b.BACKSPACE||(a==b.DELETE&&b.button==-1))){return}var c=String.fromCharCode(b.getCharCode());if(!Ext.isGecko&&b.isSpecialKey()&&!c){return}if(!this.maskRe.test(c)){b.stopEvent()}},setValue:function(a){if(this.emptyText&&this.el&&!Ext.isEmpty(a)){this.el.removeClass(this.emptyClass)}Ext.form.TextField.superclass.setValue.apply(this,arguments);this.applyEmptyText();this.autoSize();return this},getErrors:function(a){var d=Ext.form.TextField.superclass.getErrors.apply(this,arguments);a=Ext.isDefined(a)?a:this.processValue(this.getRawValue());if(Ext.isFunction(this.validator)){var c=this.validator(a);if(c!==true){d.push(c)}}if(a.length<1||a===this.emptyText){if(this.allowBlank){return d}else{d.push(this.blankText)}}if(!this.allowBlank&&(a.length<1||a===this.emptyText)){d.push(this.blankText)}if(a.length<this.minLength){d.push(String.format(this.minLengthText,this.minLength))}if(a.length>this.maxLength){d.push(String.format(this.maxLengthText,this.maxLength))}if(this.vtype){var b=Ext.form.VTypes;if(!b[this.vtype](a,this)){d.push(this.vtypeText||b[this.vtype+"Text"])}}if(this.regex&&!this.regex.test(a)){d.push(this.regexText)}return d},selectText:function(h,a){var c=this.getRawValue();var e=false;if(c.length>0){h=h===undefined?0:h;a=a===undefined?c.length:a;var g=this.el.dom;if(g.setSelectionRange){g.setSelectionRange(h,a)}else{if(g.createTextRange){var b=g.createTextRange();b.moveStart("character",h);b.moveEnd("character",a-c.length);b.select()}}e=Ext.isGecko||Ext.isOpera}else{e=true}if(e){this.focus()}},autoSize:function(){if(!this.grow||!this.rendered){return}if(!this.metrics){this.metrics=Ext.util.TextMetrics.createInstance(this.el)}var c=this.el;var b=c.dom.value;var e=document.createElement("div");e.appendChild(document.createTextNode(b));b=e.innerHTML;Ext.removeNode(e);e=null;b+="&#160;";var a=Math.min(this.growMax,Math.max(this.metrics.getWidth(b)+10,this.growMin));this.el.setWidth(a);this.fireEvent("autosize",this,a)},onDestroy:function(){if(this.validationTask){this.validationTask.cancel();this.validationTask=null}Ext.form.TextField.superclass.onDestroy.call(this)}});Ext.reg("textfield",Ext.form.TextField);Ext.form.TriggerField=Ext.extend(Ext.form.TextField,{defaultAutoCreate:{tag:"input",type:"text",size:"16",autocomplete:"off"},hideTrigger:false,editable:true,readOnly:false,wrapFocusClass:"x-trigger-wrap-focus",autoSize:Ext.emptyFn,monitorTab:true,deferHeight:true,mimicing:false,actionMode:"wrap",defaultTriggerWidth:17,onResize:function(a,c){Ext.form.TriggerField.superclass.onResize.call(this,a,c);var b=this.getTriggerWidth();if(Ext.isNumber(a)){this.el.setWidth(a-b)}this.wrap.setWidth(this.el.getWidth()+b)},getTriggerWidth:function(){var a=this.trigger.getWidth();if(!this.hideTrigger&&!this.readOnly&&a===0){a=this.defaultTriggerWidth}return a},alignErrorIcon:function(){if(this.wrap){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}},onRender:function(b,a){this.doc=Ext.isIE?Ext.getBody():Ext.getDoc();Ext.form.TriggerField.superclass.onRender.call(this,b,a);this.wrap=this.el.wrap({cls:"x-form-field-wrap x-form-field-trigger-wrap"});this.trigger=this.wrap.createChild(this.triggerConfig||{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.triggerClass});this.initTrigger();if(!this.width){this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())}this.resizeEl=this.positionEl=this.wrap},getWidth:function(){return(this.el.getWidth()+this.trigger.getWidth())},updateEditState:function(){if(this.rendered){if(this.readOnly){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this);this.trigger.setDisplayed(false)}else{if(!this.editable){this.el.dom.readOnly=true;this.el.addClass("x-trigger-noedit");this.mon(this.el,"click",this.onTriggerClick,this)}else{this.el.dom.readOnly=false;this.el.removeClass("x-trigger-noedit");this.mun(this.el,"click",this.onTriggerClick,this)}this.trigger.setDisplayed(!this.hideTrigger)}this.onResize(this.width||this.wrap.getWidth())}},setHideTrigger:function(a){if(a!=this.hideTrigger){this.hideTrigger=a;this.updateEditState()}},setEditable:function(a){if(a!=this.editable){this.editable=a;this.updateEditState()}},setReadOnly:function(a){if(a!=this.readOnly){this.readOnly=a;this.updateEditState()}},afterRender:function(){Ext.form.TriggerField.superclass.afterRender.call(this);this.updateEditState()},initTrigger:function(){this.mon(this.trigger,"click",this.onTriggerClick,this,{preventDefault:true});this.trigger.addClassOnOver("x-form-trigger-over");this.trigger.addClassOnClick("x-form-trigger-click")},onDestroy:function(){Ext.destroy(this.trigger,this.wrap);if(this.mimicing){this.doc.un("mousedown",this.mimicBlur,this)}delete this.doc;Ext.form.TriggerField.superclass.onDestroy.call(this)},onFocus:function(){Ext.form.TriggerField.superclass.onFocus.call(this);if(!this.mimicing){this.wrap.addClass(this.wrapFocusClass);this.mimicing=true;this.doc.on("mousedown",this.mimicBlur,this,{delay:10});if(this.monitorTab){this.on("specialkey",this.checkTab,this)}}},checkTab:function(a,b){if(b.getKey()==b.TAB){this.triggerBlur()}},onBlur:Ext.emptyFn,mimicBlur:function(a){if(!this.isDestroyed&&!this.wrap.contains(a.target)&&this.validateBlur(a)){this.triggerBlur()}},triggerBlur:function(){this.mimicing=false;this.doc.un("mousedown",this.mimicBlur,this);if(this.monitorTab&&this.el){this.un("specialkey",this.checkTab,this)}Ext.form.TriggerField.superclass.onBlur.call(this);if(this.wrap){this.wrap.removeClass(this.wrapFocusClass)}},beforeBlur:Ext.emptyFn,validateBlur:function(a){return true},onTriggerClick:Ext.emptyFn});Ext.form.TwinTriggerField=Ext.extend(Ext.form.TriggerField,{initComponent:function(){Ext.form.TwinTriggerField.superclass.initComponent.call(this);this.triggerConfig={tag:"span",cls:"x-form-twin-triggers",cn:[{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.trigger1Class},{tag:"img",src:Ext.BLANK_IMAGE_URL,alt:"",cls:"x-form-trigger "+this.trigger2Class}]}},getTrigger:function(a){return this.triggers[a]},afterRender:function(){Ext.form.TwinTriggerField.superclass.afterRender.call(this);var c=this.triggers,b=0,a=c.length;for(;b<a;++b){if(this["hideTrigger"+(b+1)]){c[b].hide()}}},initTrigger:function(){var a=this.trigger.select(".x-form-trigger",true),b=this;a.each(function(d,g,c){var e="Trigger"+(c+1);d.hide=function(){var h=b.wrap.getWidth();this.dom.style.display="none";b.el.setWidth(h-b.trigger.getWidth());b["hidden"+e]=true};d.show=function(){var h=b.wrap.getWidth();this.dom.style.display="";b.el.setWidth(h-b.trigger.getWidth());b["hidden"+e]=false};this.mon(d,"click",this["on"+e+"Click"],this,{preventDefault:true});d.addClassOnOver("x-form-trigger-over");d.addClassOnClick("x-form-trigger-click")},this);this.triggers=a.elements},getTriggerWidth:function(){var a=0;Ext.each(this.triggers,function(d,c){var e="Trigger"+(c+1),b=d.getWidth();if(b===0&&!this["hidden"+e]){a+=this.defaultTriggerWidth}else{a+=b}},this);return a},onDestroy:function(){Ext.destroy(this.triggers);Ext.form.TwinTriggerField.superclass.onDestroy.call(this)},onTrigger1Click:Ext.emptyFn,onTrigger2Click:Ext.emptyFn});Ext.reg("trigger",Ext.form.TriggerField);Ext.reg("twintrigger",Ext.form.TwinTriggerField);Ext.form.TextArea=Ext.extend(Ext.form.TextField,{growMin:60,growMax:1000,growAppend:"&#160;\n&#160;",enterIsSpecial:false,preventScrollbars:false,onRender:function(b,a){if(!this.el){this.defaultAutoCreate={tag:"textarea",style:"width:100px;height:60px;",autocomplete:"off"}}Ext.form.TextArea.superclass.onRender.call(this,b,a);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)}},onDestroy:function(){Ext.removeNode(this.textSizeEl);Ext.form.TextArea.superclass.onDestroy.call(this)},fireKey:function(a){if(a.isSpecialKey()&&(this.enterIsSpecial||(a.getKey()!=a.ENTER||a.hasModifier()))){this.fireEvent("specialkey",this,a)}},doAutoSize:function(a){return !a.isNavKeyPress()||a.getKey()==a.ENTER},filterValidation:function(a){if(!a.isNavKeyPress()||(!this.enterIsSpecial&&a.keyCode==a.ENTER)){this.validationTask.delay(this.validationDelay)}},autoSize:function(){if(!this.grow||!this.textSizeEl){return}var c=this.el,a=Ext.util.Format.htmlEncode(c.dom.value),d=this.textSizeEl,b;Ext.fly(d).setWidth(this.el.getWidth());if(a.length<1){a="&#160;&#160;"}else{a+=this.growAppend;if(Ext.isIE){a=a.replace(/\n/g,"&#160;<br />")}}d.innerHTML=a;b=Math.min(this.growMax,Math.max(d.offsetHeight,this.growMin));if(b!=this.lastHeight){this.lastHeight=b;this.el.setHeight(b);this.fireEvent("autosize",this,b)}}});Ext.reg("textarea",Ext.form.TextArea);Ext.form.NumberField=Ext.extend(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",baseChars:"0123456789",autoStripChars:false,initEvents:function(){var a=this.baseChars+"";if(this.allowDecimals){a+=this.decimalSeparator}if(this.allowNegative){a+="-"}a=Ext.escapeRe(a);this.maskRe=new RegExp("["+a+"]");if(this.autoStripChars){this.stripCharsRe=new RegExp("[^"+a+"]","gi")}Ext.form.NumberField.superclass.initEvents.call(this)},getErrors:function(b){var c=Ext.form.NumberField.superclass.getErrors.apply(this,arguments);b=Ext.isDefined(b)?b:this.processValue(this.getRawValue());if(b.length<1){return c}b=String(b).replace(this.decimalSeparator,".");if(isNaN(b)){c.push(String.format(this.nanText,b))}var a=this.parseValue(b);if(a<this.minValue){c.push(String.format(this.minText,this.minValue))}if(a>this.maxValue){c.push(String.format(this.maxText,this.maxValue))}return c},getValue:function(){return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)))},setValue:function(a){a=Ext.isNumber(a)?a:parseFloat(String(a).replace(this.decimalSeparator,"."));a=this.fixPrecision(a);a=isNaN(a)?"":String(a).replace(".",this.decimalSeparator);return Ext.form.NumberField.superclass.setValue.call(this,a)},setMinValue:function(a){this.minValue=Ext.num(a,Number.NEGATIVE_INFINITY)},setMaxValue:function(a){this.maxValue=Ext.num(a,Number.MAX_VALUE)},parseValue:function(a){a=parseFloat(String(a).replace(this.decimalSeparator,"."));return isNaN(a)?"":a},fixPrecision:function(b){var a=isNaN(b);if(!this.allowDecimals||this.decimalPrecision==-1||a||!b){return a?"":b}return parseFloat(parseFloat(b).toFixed(this.decimalPrecision))},beforeBlur:function(){var a=this.parseValue(this.getRawValue());if(!Ext.isEmpty(a)){this.setValue(a)}}});Ext.reg("numberfield",Ext.form.NumberField);Ext.form.DateField=Ext.extend(Ext.form.TriggerField,{format:"m/d/Y",altFormats:"m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",disabledDaysText:"Disabled",disabledDatesText:"Disabled",minText:"The date in this field must be equal to or after {0}",maxText:"The date in this field must be equal to or before {0}",invalidText:"{0} is not a valid date - it must be in the format {1}",triggerClass:"x-form-date-trigger",showToday:true,startDay:0,defaultAutoCreate:{tag:"input",type:"text",size:"10",autocomplete:"off"},initTime:"12",initTimeFormat:"H",safeParse:function(b,c){if(Date.formatContainsHourInfo(c)){return Date.parseDate(b,c)}else{var a=Date.parseDate(b+" "+this.initTime,c+" "+this.initTimeFormat);if(a){return a.clearTime()}}},initComponent:function(){Ext.form.DateField.superclass.initComponent.call(this);this.addEvents("select");if(Ext.isString(this.minValue)){this.minValue=this.parseDate(this.minValue)}if(Ext.isString(this.maxValue)){this.maxValue=this.parseDate(this.maxValue)}this.disabledDatesRE=null;this.initDisabledDays()},initEvents:function(){Ext.form.DateField.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{down:function(a){this.onTriggerClick()},scope:this,forceKeyDown:true})},initDisabledDays:function(){if(this.disabledDates){var b=this.disabledDates,a=b.length-1,c="(?:";Ext.each(b,function(g,e){c+=Ext.isDate(g)?"^"+Ext.escapeRe(g.dateFormat(this.format))+"$":b[e];if(e!=a){c+="|"}},this);this.disabledDatesRE=new RegExp(c+")")}},setDisabledDates:function(a){this.disabledDates=a;this.initDisabledDays();if(this.menu){this.menu.picker.setDisabledDates(this.disabledDatesRE)}},setDisabledDays:function(a){this.disabledDays=a;if(this.menu){this.menu.picker.setDisabledDays(a)}},setMinValue:function(a){this.minValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMinDate(this.minValue)}},setMaxValue:function(a){this.maxValue=(Ext.isString(a)?this.parseDate(a):a);if(this.menu){this.menu.picker.setMaxDate(this.maxValue)}},getErrors:function(e){var h=Ext.form.DateField.superclass.getErrors.apply(this,arguments);e=this.formatDate(e||this.processValue(this.getRawValue()));if(e.length<1){return h}var c=e;e=this.parseDate(e);if(!e){h.push(String.format(this.invalidText,c,this.format));return h}var g=e.getTime();if(this.minValue&&g<this.minValue.clearTime().getTime()){h.push(String.format(this.minText,this.formatDate(this.minValue)))}if(this.maxValue&&g>this.maxValue.clearTime().getTime()){h.push(String.format(this.maxText,this.formatDate(this.maxValue)))}if(this.disabledDays){var a=e.getDay();for(var b=0;b<this.disabledDays.length;b++){if(a===this.disabledDays[b]){h.push(this.disabledDaysText);break}}}var d=this.formatDate(e);if(this.disabledDatesRE&&this.disabledDatesRE.test(d)){h.push(String.format(this.disabledDatesText,d))}return h},validateBlur:function(){return !this.menu||!this.menu.isVisible()},getValue:function(){return this.parseDate(Ext.form.DateField.superclass.getValue.call(this))||""},setValue:function(a){return Ext.form.DateField.superclass.setValue.call(this,this.formatDate(this.parseDate(a)))},parseDate:function(g){if(!g||Ext.isDate(g)){return g}var b=this.safeParse(g,this.format),c=this.altFormats,e=this.altFormatsArray;if(!b&&c){e=e||c.split("|");for(var d=0,a=e.length;d<a&&!b;d++){b=this.safeParse(g,e[d])}}return b},onDestroy:function(){Ext.destroy(this.menu,this.keyNav);Ext.form.DateField.superclass.onDestroy.call(this)},formatDate:function(a){return Ext.isDate(a)?a.dateFormat(this.format):a},onTriggerClick:function(){if(this.disabled){return}if(this.menu==null){this.menu=new Ext.menu.DateMenu({hideOnClick:false,focusOnSelect:false})}this.onFocus();Ext.apply(this.menu.picker,{minDate:this.minValue,maxDate:this.maxValue,disabledDatesRE:this.disabledDatesRE,disabledDatesText:this.disabledDatesText,disabledDays:this.disabledDays,disabledDaysText:this.disabledDaysText,format:this.format,showToday:this.showToday,startDay:this.startDay,minText:String.format(this.minText,this.formatDate(this.minValue)),maxText:String.format(this.maxText,this.formatDate(this.maxValue))});this.menu.picker.setValue(this.getValue()||new Date());this.menu.show(this.el,"tl-bl?");this.menuEvents("on")},menuEvents:function(a){this.menu[a]("select",this.onSelect,this);this.menu[a]("hide",this.onMenuHide,this);this.menu[a]("show",this.onFocus,this)},onSelect:function(a,b){this.setValue(b);this.fireEvent("select",this,b);this.menu.hide()},onMenuHide:function(){this.focus(false,60);this.menuEvents("un")},beforeBlur:function(){var a=this.parseDate(this.getRawValue());if(a){this.setValue(a)}}});Ext.reg("datefield",Ext.form.DateField);Ext.form.DisplayField=Ext.extend(Ext.form.Field,{validationEvent:false,validateOnBlur:false,defaultAutoCreate:{tag:"div"},fieldClass:"x-form-display-field",htmlEncode:false,initEvents:Ext.emptyFn,isValid:function(){return true},validate:function(){return true},getRawValue:function(){var a=this.rendered?this.el.dom.innerHTML:Ext.value(this.value,"");if(a===this.emptyText){a=""}if(this.htmlEncode){a=Ext.util.Format.htmlDecode(a)}return a},getValue:function(){return this.getRawValue()},getName:function(){return this.name},setRawValue:function(a){if(this.htmlEncode){a=Ext.util.Format.htmlEncode(a)}return this.rendered?(this.el.dom.innerHTML=(Ext.isEmpty(a)?"":a)):(this.value=a)},setValue:function(a){this.setRawValue(a);return this}});Ext.reg("displayfield",Ext.form.DisplayField);Ext.form.ComboBox=Ext.extend(Ext.form.TriggerField,{defaultAutoCreate:{tag:"input",type:"text",size:"24",autocomplete:"off"},listClass:"",selectedClass:"x-combo-selected",listEmptyText:"",triggerClass:"x-form-arrow-trigger",shadow:"sides",listAlign:"tl-bl?",maxHeight:300,minHeight:90,triggerAction:"query",minChars:4,autoSelect:true,typeAhead:false,queryDelay:500,pageSize:0,selectOnFocus:false,queryParam:"query",loadingText:"Loading...",resizable:false,handleHeight:8,allQuery:"",mode:"remote",minListWidth:70,forceSelection:false,typeAheadDelay:250,lazyInit:true,clearFilterOnReset:true,submitValue:undefined,initComponent:function(){Ext.form.ComboBox.superclass.initComponent.call(this);this.addEvents("expand","collapse","beforeselect","select","beforequery");if(this.transform){var c=Ext.getDom(this.transform);if(!this.hiddenName){this.hiddenName=c.name}if(!this.store){this.mode="local";var j=[],e=c.options;for(var b=0,a=e.length;b<a;b++){var h=e[b],g=(h.hasAttribute?h.hasAttribute("value"):h.getAttributeNode("value").specified)?h.value:h.text;if(h.selected&&Ext.isEmpty(this.value,true)){this.value=g}j.push([g,h.text])}this.store=new Ext.data.ArrayStore({idIndex:0,fields:["value","text"],data:j,autoDestroy:true});this.valueField="value";this.displayField="text"}c.name=Ext.id();if(!this.lazyRender){this.target=true;this.el=Ext.DomHelper.insertBefore(c,this.autoCreate||this.defaultAutoCreate);this.render(this.el.parentNode,c)}Ext.removeNode(c)}else{if(this.store){this.store=Ext.StoreMgr.lookup(this.store);if(this.store.autoCreated){this.displayField=this.valueField="field1";if(!this.store.expandData){this.displayField="field2"}this.mode="local"}}}this.selectedIndex=-1;if(this.mode=="local"){if(!Ext.isDefined(this.initialConfig.queryDelay)){this.queryDelay=10}if(!Ext.isDefined(this.initialConfig.minChars)){this.minChars=0}}},onRender:function(b,a){if(this.hiddenName&&!Ext.isDefined(this.submitValue)){this.submitValue=false}Ext.form.ComboBox.superclass.onRender.call(this,b,a);if(this.hiddenName){this.hiddenField=this.el.insertSibling({tag:"input",type:"hidden",name:this.hiddenName,id:(this.hiddenId||Ext.id())},"before",true)}if(Ext.isGecko){this.el.dom.setAttribute("autocomplete","off")}if(!this.lazyInit){this.initList()}else{this.on("focus",this.initList,this,{single:true})}},initValue:function(){Ext.form.ComboBox.superclass.initValue.call(this);if(this.hiddenField){this.hiddenField.value=Ext.value(Ext.isDefined(this.hiddenValue)?this.hiddenValue:this.value,"")}},getParentZIndex:function(){var a;if(this.ownerCt){this.findParentBy(function(b){a=parseInt(b.getPositionEl().getStyle("z-index"),10);return !!a})}return a},getZIndex:function(b){b=b||Ext.getDom(this.getListParent()||Ext.getBody());var a=parseInt(Ext.fly(b).getStyle("z-index"),10);if(!a){a=this.getParentZIndex()}return(a||12000)+5},initList:function(){if(!this.list){var a="x-combo-list",c=Ext.getDom(this.getListParent()||Ext.getBody());this.list=new Ext.Layer({parentEl:c,shadow:this.shadow,cls:[a,this.listClass].join(" "),constrain:false,zindex:this.getZIndex(c)});var b=this.listWidth||Math.max(this.wrap.getWidth(),this.minListWidth);this.list.setSize(b,0);this.list.swallowEvent("mousewheel");this.assetHeight=0;if(this.syncFont!==false){this.list.setStyle("font-size",this.el.getStyle("font-size"))}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.mon(this.innerList,"mouseover",this.onViewOver,this);this.mon(this.innerList,"mousemove",this.onViewMove,this);this.innerList.setWidth(b-this.list.getFrameWidth("lr"));if(this.pageSize){this.footer=this.list.createChild({cls:a+"-ft"});this.pageTb=new Ext.PagingToolbar({store:this.store,pageSize:this.pageSize,renderTo:this.footer});this.assetHeight+=this.footer.getHeight()}if(!this.tpl){this.tpl='<tpl for="."><div class="'+a+'-item">{'+this.displayField+"}</div></tpl>"}this.view=new Ext.DataView({applyTo:this.innerList,tpl:this.tpl,singleSelect:true,selectedClass:this.selectedClass,itemSelector:this.itemSelector||"."+a+"-item",emptyText:this.listEmptyText,deferEmptyText:false});this.mon(this.view,{containerclick:this.onViewClick,click:this.onViewClick,scope:this});this.bindStore(this.store,true);if(this.resizable){this.resizer=new Ext.Resizable(this.list,{pinned:true,handles:"se"});this.mon(this.resizer,"resize",function(g,d,e){this.maxHeight=e-this.handleHeight-this.list.getFrameWidth("tb")-this.assetHeight;this.listWidth=d;this.innerList.setWidth(d-this.list.getFrameWidth("lr"));this.restrictHeight()},this);this[this.pageSize?"footer":"innerList"].setStyle("margin-bottom",this.handleHeight+"px")}}},getListParent:function(){return document.body},getStore:function(){return this.store},bindStore:function(a,b){if(this.store&&!b){if(this.store!==a&&this.store.autoDestroy){this.store.destroy()}else{this.store.un("beforeload",this.onBeforeLoad,this);this.store.un("load",this.onLoad,this);this.store.un("exception",this.collapse,this)}if(!a){this.store=null;if(this.view){this.view.bindStore(null)}if(this.pageTb){this.pageTb.bindStore(null)}}}if(a){if(!b){this.lastQuery=null;if(this.pageTb){this.pageTb.bindStore(a)}}this.store=Ext.StoreMgr.lookup(a);this.store.on({scope:this,beforeload:this.onBeforeLoad,load:this.onLoad,exception:this.collapse});if(this.view){this.view.bindStore(a)}}},reset:function(){if(this.clearFilterOnReset&&this.mode=="local"){this.store.clearFilter()}Ext.form.ComboBox.superclass.reset.call(this)},initEvents:function(){Ext.form.ComboBox.superclass.initEvents.call(this);this.keyNav=new Ext.KeyNav(this.el,{up:function(a){this.inKeyMode=true;this.selectPrev()},down:function(a){if(!this.isExpanded()){this.onTriggerClick()}else{this.inKeyMode=true;this.selectNext()}},enter:function(a){this.onViewClick()},esc:function(a){this.collapse()},tab:function(a){if(this.forceSelection===true){this.collapse()}else{this.onViewClick(false)}return true},scope:this,doRelay:function(c,b,a){if(a=="down"||this.scope.isExpanded()){var d=Ext.KeyNav.prototype.doRelay.apply(this,arguments);if((((Ext.isIE9&&Ext.isStrict)||Ext.isIE10p)||!Ext.isIE)&&Ext.EventManager.useKeydown){this.scope.fireKey(c)}return d}return true},forceKeyDown:true,defaultEventAction:"stopEvent"});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.enableKeyEvents){this.mon(this.el,"keyup",this.onKeyUp,this)}},onDestroy:function(){if(this.dqTask){this.dqTask.cancel();this.dqTask=null}this.bindStore(null);Ext.destroy(this.resizer,this.view,this.pageTb,this.list);Ext.destroyMembers(this,"hiddenField");Ext.form.ComboBox.superclass.onDestroy.call(this)},fireKey:function(a){if(!this.isExpanded()){Ext.form.ComboBox.superclass.fireKey.call(this,a)}},onResize:function(a,b){Ext.form.ComboBox.superclass.onResize.apply(this,arguments);if(!isNaN(a)&&this.isVisible()&&this.list){this.doResize(a)}else{this.bufferSize=a}},doResize:function(a){if(!Ext.isDefined(this.listWidth)){var b=Math.max(a,this.minListWidth);this.list.setWidth(b);this.innerList.setWidth(b-this.list.getFrameWidth("lr"))}},onEnable:function(){Ext.form.ComboBox.superclass.onEnable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=false}},onDisable:function(){Ext.form.ComboBox.superclass.onDisable.apply(this,arguments);if(this.hiddenField){this.hiddenField.disabled=true}},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.listEmptyText){this.expand();this.restrictHeight();if(this.lastQuery==this.allQuery){if(this.editable){this.el.dom.select()}if(this.autoSelect!==false&&!this.selectByValue(this.value,true)){this.select(0,true)}}else{if(this.autoSelect!==false){this.selectNext()}if(this.typeAhead&&this.lastKey!=Ext.EventObject.BACKSPACE&&this.lastKey!=Ext.EventObject.DELETE){this.taTask.delay(this.typeAheadDelay)}}}else{this.collapse()}},onTypeAhead:function(){if(this.store.getCount()>0){var b=this.store.getAt(0);var c=b.data[this.displayField];var a=c.length;var d=this.getRawValue().length;if(d!=a){this.setRawValue(c);this.selectText(d,c.length)}}},assertValue:function(){var b=this.getRawValue(),a;if(this.valueField&&Ext.isDefined(this.value)){a=this.findRecord(this.valueField,this.value)}if(!a||a.get(this.displayField)!=b){a=this.findRecord(this.displayField,b)}if(!a&&this.forceSelection){if(b.length>0&&b!=this.emptyText){this.el.dom.value=Ext.value(this.lastSelectionText,"");this.applyEmptyText()}else{this.clearValue()}}else{if(a&&this.valueField){if(this.value==b){return}b=a.get(this.valueField||this.displayField)}this.setValue(b)}},onSelect:function(a,b){if(this.fireEvent("beforeselect",this,a,b)!==false){this.setValue(a.data[this.valueField||this.displayField]);this.collapse();this.fireEvent("select",this,a,b)}},getName:function(){var a=this.hiddenField;return a&&a.name?a.name:this.hiddenName||Ext.form.ComboBox.superclass.getName.call(this)},getValue:function(){if(this.valueField){return Ext.isDefined(this.value)?this.value:""}else{return Ext.form.ComboBox.superclass.getValue.call(this)}},clearValue:function(){if(this.hiddenField){this.hiddenField.value=""}this.setRawValue("");this.lastSelectionText="";this.applyEmptyText();this.value=""},setValue:function(a){var c=a;if(this.valueField){var b=this.findRecord(this.valueField,a);if(b){c=b.data[this.displayField]}else{if(Ext.isDefined(this.valueNotFoundText)){c=this.valueNotFoundText}}}this.lastSelectionText=c;if(this.hiddenField){this.hiddenField.value=Ext.value(a,"")}Ext.form.ComboBox.superclass.setValue.call(this,c);this.value=a;return this},findRecord:function(c,b){var a;if(this.store.getCount()>0){this.store.each(function(d){if(d.data[c]==b){a=d;return false}})}return a},onViewMove:function(b,a){this.inKeyMode=false},onViewOver:function(d,b){if(this.inKeyMode){return}var c=this.view.findItemFromChild(b);if(c){var a=this.view.indexOf(c);this.select(a,false)}},onViewClick:function(b){var a=this.view.getSelectedIndexes()[0],c=this.store,d=c.getAt(a);if(d){this.onSelect(d,a)}else{this.collapse()}if(b!==false){this.el.focus()}},restrictHeight:function(){this.innerList.dom.style.height="";var b=this.innerList.dom,e=this.list.getFrameWidth("tb")+(this.resizable?this.handleHeight:0)+this.assetHeight,c=Math.max(b.clientHeight,b.offsetHeight,b.scrollHeight),a=this.getPosition()[1]-Ext.getBody().getScroll().top,g=Ext.lib.Dom.getViewHeight()-a-this.getSize().height,d=Math.max(a,g,this.minHeight||0)-this.list.shadowOffset-e-5;c=Math.min(c,d,this.maxHeight);this.innerList.setHeight(c);this.list.beginUpdate();this.list.setHeight(c+e);this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));this.list.endUpdate()},isExpanded:function(){return this.list&&this.list.isVisible()},selectByValue:function(a,c){if(!Ext.isEmpty(a,true)){var b=this.findRecord(this.valueField||this.displayField,a);if(b){this.select(this.store.indexOf(b),c);return true}}return false},select:function(a,c){this.selectedIndex=a;this.view.select(a);if(c!==false){var b=this.view.getNode(a);if(b){this.innerList.scrollChildIntoView(b,false)}}},selectNext:function(){var a=this.store.getCount();if(a>0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex<a-1){this.select(this.selectedIndex+1)}}}},selectPrev:function(){var a=this.store.getCount();if(a>0){if(this.selectedIndex==-1){this.select(0)}else{if(this.selectedIndex!==0){this.select(this.selectedIndex-1)}}}},onKeyUp:function(b){var a=b.getKey();if(this.editable!==false&&this.readOnly!==true&&(a==b.BACKSPACE||!b.isSpecialKey())){this.lastKey=a;this.dqTask.delay(this.queryDelay)}Ext.form.ComboBox.superclass.onKeyUp.call(this,b)},validateBlur:function(){return !this.list||!this.list.isVisible()},initQuery:function(){this.doQuery(this.getRawValue())},beforeBlur:function(){this.assertValue()},postBlur:function(){Ext.form.ComboBox.superclass.postBlur.call(this);this.collapse();this.inKeyMode=false},doQuery:function(c,b){c=Ext.isEmpty(c)?"":c;var a={query:c,forceAll:b,combo:this,cancel:false};if(this.fireEvent("beforequery",a)===false||a.cancel){return false}c=a.query;b=a.forceAll;if(b===true||(c.length>=this.minChars)){if(this.lastQuery!==c){this.lastQuery=c;if(this.mode=="local"){this.selectedIndex=-1;if(b){this.store.clearFilter()}else{this.store.filter(this.displayField,c)}this.onLoad()}else{this.store.baseParams[this.queryParam]=c;this.store.load({params:this.getParams(c)});this.expand()}}else{this.selectedIndex=-1;this.onLoad()}}},getParams:function(a){var b={},c=this.store.paramNames;if(this.pageSize){b[c.start]=0;b[c.limit]=this.pageSize}return b},collapse:function(){if(!this.isExpanded()){return}this.list.hide();Ext.getDoc().un("mousewheel",this.collapseIf,this);Ext.getDoc().un("mousedown",this.collapseIf,this);this.fireEvent("collapse",this)},collapseIf:function(a){if(!this.isDestroyed&&!a.within(this.wrap)&&!a.within(this.list)){this.collapse()}},expand:function(){if(this.isExpanded()||!this.hasFocus){return}if(this.title||this.pageSize){this.assetHeight=0;if(this.title){this.assetHeight+=this.header.getHeight()}if(this.pageSize){this.assetHeight+=this.footer.getHeight()}}if(this.bufferSize){this.doResize(this.bufferSize);delete this.bufferSize}this.list.alignTo.apply(this.list,[this.el].concat(this.listAlign));this.list.setZIndex(this.getZIndex());this.list.show();if(Ext.isGecko2){this.innerList.setOverflow("auto")}this.mon(Ext.getDoc(),{scope:this,mousewheel:this.collapseIf,mousedown:this.collapseIf});this.fireEvent("expand",this)},onTriggerClick:function(){if(this.readOnly||this.disabled){return}if(this.isExpanded()){this.collapse();this.el.focus()}else{this.onFocus({});if(this.triggerAction=="all"){this.doQuery(this.allQuery,true)}else{this.doQuery(this.getRawValue())}this.el.focus()}}});Ext.reg("combo",Ext.form.ComboBox);Ext.form.Checkbox=Ext.extend(Ext.form.Field,{focusClass:undefined,fieldClass:"x-form-field",checked:false,boxLabel:"&#160;",defaultAutoCreate:{tag:"input",type:"checkbox",autocomplete:"off"},actionMode:"wrap",initComponent:function(){Ext.form.Checkbox.superclass.initComponent.call(this);this.addEvents("check")},onResize:function(){Ext.form.Checkbox.superclass.onResize.apply(this,arguments);if(!this.boxLabel&&!this.fieldLabel){this.el.alignTo(this.wrap,"c-c")}},initEvents:function(){Ext.form.Checkbox.superclass.initEvents.call(this);this.mon(this.el,{scope:this,click:this.onClick,change:this.onClick})},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,onRender:function(b,a){Ext.form.Checkbox.superclass.onRender.call(this,b,a);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)}else{this.checked=this.el.dom.checked}if(Ext.isIEQuirks){this.wrap.repaint()}this.resizeEl=this.positionEl=this.wrap},onDestroy:function(){Ext.destroy(this.wrap);Ext.form.Checkbox.superclass.onDestroy.call(this)},initValue:function(){this.originalValue=this.getValue()},getValue:function(){if(this.rendered){return this.el.dom.checked}return this.checked},onClick:function(){if(this.el.dom.checked!=this.checked){this.setValue(this.el.dom.checked)}},setValue:function(a){var c=this.checked,b=this.inputValue;if(a===false){this.checked=false}else{this.checked=(a===true||a==="true"||a=="1"||(b?a==b:String(a).toLowerCase()=="on"))}if(this.rendered){this.el.dom.checked=this.checked;this.el.dom.defaultChecked=this.checked}if(c!=this.checked){this.fireEvent("check",this,this.checked);if(this.handler){this.handler.call(this.scope||this,this,this.checked)}}return this}});Ext.reg("checkbox",Ext.form.Checkbox);Ext.form.CheckboxGroup=Ext.extend(Ext.form.Field,{columns:"auto",vertical:false,allowBlank:true,blankText:"You must select at least one item in this group",defaultType:"checkbox",groupCls:"x-form-check-group",initComponent:function(){this.addEvents("change");this.on("change",this.validate,this);Ext.form.CheckboxGroup.superclass.initComponent.call(this)},onRender:function(j,g){if(!this.el){var p={autoEl:{id:this.id},cls:this.groupCls,layout:"column",renderTo:j,bufferResize:false};var a={xtype:"container",defaultType:this.defaultType,layout:"form",defaults:{hideLabel:true,anchor:"100%"}};if(this.items[0].items){Ext.apply(p,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,m=this.items.length;e<m;e++){Ext.applyIf(this.items[e],a)}}else{var d,n=[];if(typeof this.columns=="string"){this.columns=this.items.length}if(!Ext.isArray(this.columns)){var k=[];for(var e=0;e<this.columns;e++){k.push((100/this.columns)*0.01)}this.columns=k}d=this.columns.length;for(var e=0;e<d;e++){var b=Ext.apply({items:[]},a);b[this.columns[e]<=1?"columnWidth":"width"]=this.columns[e];if(this.defaults){b.defaults=Ext.apply(b.defaults||{},this.defaults)}n.push(b)}if(this.vertical){var r=Math.ceil(this.items.length/d),o=0;for(var e=0,m=this.items.length;e<m;e++){if(e>0&&e%r==0){o++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}n[o].items.push(this.items[e])}}else{for(var e=0,m=this.items.length;e<m;e++){var q=e%d;if(this.items[e].fieldLabel){this.items[e].hideLabel=false}n[q].items.push(this.items[e])}}Ext.apply(p,{layoutConfig:{columns:d},items:n})}this.panel=new Ext.Container(p);this.panel.ownerCt=this;this.el=this.panel.getEl();if(this.forId&&this.itemCls){var c=this.el.up(this.itemCls).child("label",true);if(c){c.setAttribute("htmlFor",this.forId)}}var h=this.panel.findBy(function(i){return i.isFormField},this);this.items=new Ext.util.MixedCollection();this.items.addAll(h)}Ext.form.CheckboxGroup.superclass.onRender.call(this,j,g)},initValue:function(){if(this.value){this.setValue.apply(this,this.buffered?this.value:[this.value]);delete this.buffered;delete this.value}},afterRender:function(){Ext.form.CheckboxGroup.superclass.afterRender.call(this);this.eachItem(function(a){a.on("check",this.fireChecked,this);a.inGroup=true})},doLayout:function(){if(this.rendered){this.panel.forceLayout=this.ownerCt.forceLayout;this.panel.doLayout()}},fireChecked:function(){var a=[];this.eachItem(function(b){if(b.checked){a.push(b)}});this.fireEvent("change",this,a)},getErrors:function(){var b=Ext.form.CheckboxGroup.superclass.getErrors.apply(this,arguments);if(!this.allowBlank){var a=true;this.eachItem(function(c){if(c.checked){return(a=false)}});if(a){b.push(this.blankText)}}return b},isDirty:function(){if(this.disabled||!this.rendered){return false}var a=false;this.eachItem(function(b){if(b.isDirty()){a=true;return false}});return a},setReadOnly:function(a){if(this.rendered){this.eachItem(function(b){b.setReadOnly(a)})}this.readOnly=a},onDisable:function(){this.eachItem(function(a){a.disable()})},onEnable:function(){this.eachItem(function(a){a.enable()})},onResize:function(a,b){this.panel.setSize(a,b);this.panel.doLayout()},reset:function(){if(this.originalValue){this.eachItem(function(a){if(a.setValue){a.setValue(false);a.originalValue=a.getValue()}});this.resetOriginal=true;this.setValue(this.originalValue);delete this.resetOriginal}else{this.eachItem(function(a){if(a.reset){a.reset()}})}(function(){this.clearInvalid()}).defer(50,this)},setValue:function(){if(this.rendered){this.onSetValue.apply(this,arguments)}else{this.buffered=true;this.value=arguments}return this},onSetValue:function(d,c){if(arguments.length==1){if(Ext.isArray(d)){Ext.each(d,function(h,e){if(Ext.isObject(h)&&h.setValue){h.setValue(true);if(this.resetOriginal===true){h.originalValue=h.getValue()}}else{var g=this.items.itemAt(e);if(g){g.setValue(h)}}},this)}else{if(Ext.isObject(d)){for(var a in d){var b=this.getBox(a);if(b){b.setValue(d[a])}}}else{this.setValueForItem(d)}}}else{var b=this.getBox(d);if(b){b.setValue(c)}}},beforeDestroy:function(){Ext.destroy(this.panel);if(!this.rendered){Ext.destroy(this.items)}Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this)},setValueForItem:function(a){a=String(a).split(",");this.eachItem(function(b){if(a.indexOf(b.inputValue)>-1){b.setValue(true)}})},getBox:function(b){var a=null;this.eachItem(function(c){if(b==c||c.dataIndex==b||c.id==b||c.getName()==b){a=c;return false}});return a},getValue:function(){var a=[];this.eachItem(function(b){if(b.checked){a.push(b)}});return a},eachItem:function(b,a){if(this.items&&this.items.each){this.items.each(b,a||this)}},getRawValue:Ext.emptyFn,setRawValue:Ext.emptyFn});Ext.reg("checkboxgroup",Ext.form.CheckboxGroup);Ext.form.CompositeField=Ext.extend(Ext.form.Field,{defaultMargins:"0 5 0 0",skipLastItemMargin:true,isComposite:true,combineErrors:true,labelConnector:", ",initComponent:function(){var g=[],b=this.items,e;for(var d=0,c=b.length;d<c;d++){e=b[d];if(!Ext.isEmpty(e.ref)){e.ref="../"+e.ref}g.push(e.fieldLabel);Ext.applyIf(e,this.defaults);if(!(d==c-1&&this.skipLastItemMargin)){Ext.applyIf(e,{margins:this.defaultMargins})}}this.fieldLabel=this.fieldLabel||this.buildLabel(g);this.fieldErrors=new Ext.util.MixedCollection(true,function(h){return h.field});this.fieldErrors.on({scope:this,add:this.updateInvalidMark,remove:this.updateInvalidMark,replace:this.updateInvalidMark});Ext.form.CompositeField.superclass.initComponent.apply(this,arguments);this.innerCt=new Ext.Container({layout:"hbox",items:this.items,cls:"x-form-composite",defaultMargins:"0 3 0 0",ownerCt:this});delete this.innerCt.ownerCt;var a=this.innerCt.findBy(function(h){return h.isFormField},this);this.items=new Ext.util.MixedCollection();this.items.addAll(a)},onRender:function(c,a){if(!this.el){var d=this.innerCt;d.render(c);this.innerCt.ownerCt=this;this.el=d.getEl();if(this.combineErrors){this.eachItem(function(e){Ext.apply(e,{markInvalid:this.onFieldMarkInvalid.createDelegate(this,[e],0),clearInvalid:this.onFieldClearInvalid.createDelegate(this,[e],0)})})}var b=this.el.parent().parent().child("label",true);if(b){b.setAttribute("for",this.items.items[0].id)}}Ext.form.CompositeField.superclass.onRender.apply(this,arguments)},onFieldMarkInvalid:function(d,c){var b=d.getName(),a={field:b,errorName:d.fieldLabel||b,error:c};this.fieldErrors.replace(b,a);if(!d.preventMark){d.el.addClass(d.invalidClass)}},onFieldClearInvalid:function(a){this.fieldErrors.removeKey(a.getName());a.el.removeClass(a.invalidClass)},updateInvalidMark:function(){var a=Ext.isIE6&&Ext.isStrict;if(this.fieldErrors.length==0){this.clearInvalid();if(a){this.clearInvalid.defer(50,this)}}else{var b=this.buildCombinedErrorMessage(this.fieldErrors.items);this.sortErrors();this.markInvalid(b);if(a){this.markInvalid(b)}}},validateValue:function(c,a){var b=true;this.eachItem(function(d){if(!d.isValid(a)){b=false}});return b},buildCombinedErrorMessage:function(e){var d=[],b;for(var c=0,a=e.length;c<a;c++){b=e[c];d.push(String.format("{0}: {1}",b.errorName,b.error))}return d.join("<br />")},sortErrors:function(){var a=this.items;this.fieldErrors.sort("ASC",function(g,d){var c=function(b){return function(i){return i.getName()==b}};var h=a.findIndexBy(c(g.field)),e=a.findIndexBy(c(d.field));return h<e?-1:1})},reset:function(){this.eachItem(function(a){a.reset()});(function(){this.clearInvalid()}).defer(50,this)},clearInvalidChildren:function(){this.eachItem(function(a){a.clearInvalid()})},buildLabel:function(a){return Ext.clean(a).join(this.labelConnector)},isDirty:function(){if(this.disabled||!this.rendered){return false}var a=false;this.eachItem(function(b){if(b.isDirty()){a=true;return false}});return a},eachItem:function(b,a){if(this.items&&this.items.each){this.items.each(b,a||this)}},onResize:function(e,c,a,d){var b=this.innerCt;if(this.rendered&&b.rendered){b.setSize(e,c)}Ext.form.CompositeField.superclass.onResize.apply(this,arguments)},doLayout:function(c,b){if(this.rendered){var a=this.innerCt;a.forceLayout=this.ownerCt.forceLayout;a.doLayout(c,b)}},beforeDestroy:function(){Ext.destroy(this.innerCt);Ext.form.CompositeField.superclass.beforeDestroy.call(this)},setReadOnly:function(a){if(a==undefined){a=true}a=!!a;if(this.rendered){this.eachItem(function(b){b.setReadOnly(a)})}this.readOnly=a},onShow:function(){Ext.form.CompositeField.superclass.onShow.call(this);this.doLayout()},onDisable:function(){this.eachItem(function(a){a.disable()})},onEnable:function(){this.eachItem(function(a){a.enable()})}});Ext.reg("compositefield",Ext.form.CompositeField);Ext.form.Radio=Ext.extend(Ext.form.Checkbox,{inputType:"radio",markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,getGroupValue:function(){var a=this.el.up("form")||Ext.getBody();var b=a.child('input[name="'+this.el.dom.name+'"]:checked',true);return b?b.value:null},setValue:function(b){var a,d,c;if(typeof b=="boolean"){Ext.form.Radio.superclass.setValue.call(this,b)}else{if(this.rendered){a=this.getCheckEl();c=a.child('input[name="'+this.el.dom.name+'"][value="'+b+'"]',true);if(c){Ext.getCmp(c.id).setValue(true)}}}if(this.rendered&&this.checked){a=a||this.getCheckEl();d=this.getCheckEl().select('input[name="'+this.el.dom.name+'"]');d.each(function(e){if(e.dom.id!=this.id){Ext.getCmp(e.dom.id).setValue(false)}},this)}return this},getCheckEl:function(){if(this.inGroup){return this.el.up(".x-form-radio-group")}return this.el.up("form")||Ext.getBody()}});Ext.reg("radio",Ext.form.Radio);Ext.form.RadioGroup=Ext.extend(Ext.form.CheckboxGroup,{allowBlank:true,blankText:"You must select one item in this group",defaultType:"radio",groupCls:"x-form-radio-group",getValue:function(){var a=null;this.eachItem(function(b){if(b.checked){a=b;return false}});return a},onSetValue:function(c,b){if(arguments.length>1){var a=this.getBox(c);if(a){a.setValue(b);if(a.checked){this.eachItem(function(d){if(d!==a){d.setValue(false)}})}}}else{this.setValueForItem(c)}},setValueForItem:function(a){a=String(a).split(",")[0];this.eachItem(function(b){b.setValue(a==b.inputValue)})},fireChecked:function(){if(!this.checkTask){this.checkTask=new Ext.util.DelayedTask(this.bufferChecked,this)}this.checkTask.delay(10)},bufferChecked:function(){var a=null;this.eachItem(function(b){if(b.checked){a=b;return false}});this.fireEvent("change",this,a)},onDestroy:function(){if(this.checkTask){this.checkTask.cancel();this.checkTask=null}Ext.form.RadioGroup.superclass.onDestroy.call(this)}});Ext.reg("radiogroup",Ext.form.RadioGroup);Ext.form.Hidden=Ext.extend(Ext.form.Field,{inputType:"hidden",shouldLayout:false,onRender:function(){Ext.form.Hidden.superclass.onRender.apply(this,arguments)},initEvents:function(){this.originalValue=this.getValue()},setSize:Ext.emptyFn,setWidth:Ext.emptyFn,setHeight:Ext.emptyFn,setPosition:Ext.emptyFn,setPagePosition:Ext.emptyFn,markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn});Ext.reg("hidden",Ext.form.Hidden);Ext.form.BasicForm=Ext.extend(Ext.util.Observable,{constructor:function(b,a){Ext.apply(this,a);if(Ext.isString(this.paramOrder)){this.paramOrder=this.paramOrder.split(/[\s,|]/)}this.items=new Ext.util.MixedCollection(false,function(c){return c.getItemId()});this.addEvents("beforeaction","actionfailed","actioncomplete");if(b){this.initEl(b)}Ext.form.BasicForm.superclass.constructor.call(this)},timeout:30,paramOrder:undefined,paramsAsHash:false,waitTitle:"Please Wait...",activeAction:null,trackResetOnLoad:false,initEl:function(a){this.el=Ext.get(a);this.id=this.el.id||Ext.id();if(!this.standardSubmit){this.el.on("submit",this.onSubmit,this)}this.el.addClass("x-form")},getEl:function(){return this.el},onSubmit:function(a){a.stopEvent()},destroy:function(a){if(a!==true){this.items.each(function(b){Ext.destroy(b)});Ext.destroy(this.el)}this.items.clear();this.purgeListeners()},isValid:function(){var a=true;this.items.each(function(b){if(!b.validate()){a=false}});return a},isDirty:function(){var a=false;this.items.each(function(b){if(b.isDirty()){a=true;return false}});return a},doAction:function(b,a){if(Ext.isString(b)){b=new Ext.form.Action.ACTION_TYPES[b](this,a)}if(this.fireEvent("beforeaction",this,b)!==false){this.beforeAction(b);b.run.defer(100,b)}return this},submit:function(b){b=b||{};if(this.standardSubmit){var a=b.clientValidation===false||this.isValid();if(a){var c=this.el.dom;if(this.url&&Ext.isEmpty(c.action)){c.action=this.url}c.submit()}return a}var d=String.format("{0}submit",this.api?"direct":"");this.doAction(d,b);return this},load:function(a){var b=String.format("{0}load",this.api?"direct":"");this.doAction(b,a);return this},updateRecord:function(b){b.beginEdit();var a=b.fields,d,c;a.each(function(e){d=this.findField(e.name);if(d){c=d.getValue();if(Ext.type(c)!==false&&c.getGroupValue){c=c.getGroupValue()}else{if(d.eachItem){c=[];d.eachItem(function(g){c.push(g.getValue())})}}b.set(e.name,c)}},this);b.endEdit();return this},loadRecord:function(a){this.setValues(a.data);return this},beforeAction:function(a){this.items.each(function(c){if(c.isFormField&&c.syncValue){c.syncValue()}});var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.mask(b.waitMsg,"x-mask-loading")}else{if(this.waitMsgTarget){this.waitMsgTarget=Ext.get(this.waitMsgTarget);this.waitMsgTarget.mask(b.waitMsg,"x-mask-loading")}else{Ext.MessageBox.wait(b.waitMsg,b.waitTitle||this.waitTitle)}}}},afterAction:function(a,c){this.activeAction=null;var b=a.options;if(b.waitMsg){if(this.waitMsgTarget===true){this.el.unmask()}else{if(this.waitMsgTarget){this.waitMsgTarget.unmask()}else{Ext.MessageBox.updateProgress(1);Ext.MessageBox.hide()}}}if(c){if(b.reset){this.reset()}Ext.callback(b.success,b.scope,[this,a]);this.fireEvent("actioncomplete",this,a)}else{Ext.callback(b.failure,b.scope,[this,a]);this.fireEvent("actionfailed",this,a)}},findField:function(c){var b=this.items.get(c);if(!Ext.isObject(b)){var a=function(d){if(d.isFormField){if(d.dataIndex==c||d.id==c||d.getName()==c){b=d;return false}else{if(d.isComposite){return d.items.each(a)}else{if(d instanceof Ext.form.CheckboxGroup&&d.rendered){return d.eachItem(a)}}}}};this.items.each(a)}return b||null},markInvalid:function(h){if(Ext.isArray(h)){for(var c=0,a=h.length;c<a;c++){var b=h[c];var d=this.findField(b.id);if(d){d.markInvalid(b.msg)}}}else{var e,g;for(g in h){if(!Ext.isFunction(h[g])&&(e=this.findField(g))){e.markInvalid(h[g])}}}return this},setValues:function(c){if(Ext.isArray(c)){for(var d=0,a=c.length;d<a;d++){var b=c[d];var e=this.findField(b.id);if(e){e.setValue(b.value);if(this.trackResetOnLoad){e.originalValue=e.getValue()}}}}else{var g,h;for(h in c){if(!Ext.isFunction(c[h])&&(g=this.findField(h))){g.setValue(c[h]);if(this.trackResetOnLoad){g.originalValue=g.getValue()}}}}return this},getValues:function(b){var a=Ext.lib.Ajax.serializeForm(this.el.dom);if(b===true){return a}return Ext.urlDecode(a)},getFieldValues:function(a){var d={},e,b,c;this.items.each(function(g){if(!g.disabled&&(a!==true||g.isDirty())){e=g.getName();b=d[e];c=g.getValue();if(Ext.isDefined(b)){if(Ext.isArray(b)){d[e].push(c)}else{d[e]=[b,c]}}else{d[e]=c}}});return d},clearInvalid:function(){this.items.each(function(a){a.clearInvalid()});return this},reset:function(){this.items.each(function(a){a.reset()});return this},add:function(){this.items.addAll(Array.prototype.slice.call(arguments,0));return this},remove:function(a){this.items.remove(a);return this},cleanDestroyed:function(){this.items.filterBy(function(a){return !!a.isDestroyed}).each(this.remove,this)},render:function(){this.items.each(function(a){if(a.isFormField&&!a.rendered&&document.getElementById(a.id)){a.applyToMarkup(a.id)}});return this},applyToFields:function(a){this.items.each(function(b){Ext.apply(b,a)});return this},applyIfToFields:function(a){this.items.each(function(b){Ext.applyIf(b,a)});return this},callFieldMethod:function(b,a){a=a||[];this.items.each(function(c){if(Ext.isFunction(c[b])){c[b].apply(c,a)}});return this}});Ext.BasicForm=Ext.form.BasicForm;Ext.FormPanel=Ext.extend(Ext.Panel,{minButtonWidth:75,labelAlign:"left",monitorValid:false,monitorPoll:200,layout:"form",initComponent:function(){this.form=this.createForm();Ext.FormPanel.superclass.initComponent.call(this);this.bodyCfg={tag:"form",cls:this.baseCls+"-body",method:this.method||"POST",id:this.formId||Ext.id()};if(this.fileUpload){this.bodyCfg.enctype="multipart/form-data"}this.initItems();this.addEvents("clientvalidation");this.relayEvents(this.form,["beforeaction","actionfailed","actioncomplete"])},createForm:function(){var a=Ext.applyIf({listeners:{}},this.initialConfig);return new Ext.form.BasicForm(null,a)},initFields:function(){var c=this.form;var a=this;var b=function(d){if(a.isField(d)){c.add(d)}else{if(d.findBy&&d!=a){a.applySettings(d);if(d.items&&d.items.each){d.items.each(b,this)}}}};this.items.each(b,this)},applySettings:function(b){var a=b.ownerCt;Ext.applyIf(b,{labelAlign:a.labelAlign,labelWidth:a.labelWidth,itemCls:a.itemCls})},getLayoutTarget:function(){return this.form.el},getForm:function(){return this.form},onRender:function(b,a){this.initFields();Ext.FormPanel.superclass.onRender.call(this,b,a);this.form.initEl(this.body)},beforeDestroy:function(){this.stopMonitoring();this.form.destroy(true);Ext.FormPanel.superclass.beforeDestroy.call(this)},isField:function(a){return !!a.setValue&&!!a.getValue&&!!a.markInvalid&&!!a.clearInvalid},initEvents:function(){Ext.FormPanel.superclass.initEvents.call(this);this.on({scope:this,add:this.onAddEvent,remove:this.onRemoveEvent});if(this.monitorValid){this.startMonitoring()}},onAdd:function(a){Ext.FormPanel.superclass.onAdd.call(this,a);this.processAdd(a)},onAddEvent:function(a,b){if(a!==this){this.processAdd(b)}},processAdd:function(a){if(this.isField(a)){this.form.add(a)}else{if(a.findBy){this.applySettings(a);this.form.add.apply(this.form,a.findBy(this.isField))}}},onRemove:function(a){Ext.FormPanel.superclass.onRemove.call(this,a);this.processRemove(a)},onRemoveEvent:function(a,b){if(a!==this){this.processRemove(b)}},processRemove:function(a){if(!this.destroying){if(this.isField(a)){this.form.remove(a)}else{if(a.findBy){Ext.each(a.findBy(this.isField),this.form.remove,this.form);this.form.cleanDestroyed()}}}},startMonitoring:function(){if(!this.validTask){this.validTask=new Ext.util.TaskRunner();this.validTask.start({run:this.bindHandler,interval:this.monitorPoll||200,scope:this})}},stopMonitoring:function(){if(this.validTask){this.validTask.stopAll();this.validTask=null}},load:function(){this.form.load.apply(this.form,arguments)},onDisable:function(){Ext.FormPanel.superclass.onDisable.call(this);if(this.form){this.form.items.each(function(){this.disable()})}},onEnable:function(){Ext.FormPanel.superclass.onEnable.call(this);if(this.form){this.form.items.each(function(){this.enable()})}},bindHandler:function(){var e=true;this.form.items.each(function(g){if(!g.isValid(true)){e=false;return false}});if(this.fbar){var b=this.fbar.items.items;for(var d=0,a=b.length;d<a;d++){var c=b[d];if(c.formBind===true&&c.disabled===e){c.setDisabled(!e)}}}this.fireEvent("clientvalidation",this,e)}});Ext.reg("form",Ext.FormPanel);Ext.form.FormPanel=Ext.FormPanel;Ext.form.FieldSet=Ext.extend(Ext.Panel,{baseCls:"x-fieldset",layout:"form",animCollapse:false,onRender:function(b,a){if(!this.el){this.el=document.createElement("fieldset");this.el.id=this.id;if(this.title||this.header||this.checkboxToggle){this.el.appendChild(document.createElement("legend")).className=this.baseCls+"-header"}}Ext.form.FieldSet.superclass.onRender.call(this,b,a);if(this.checkboxToggle){var c=typeof this.checkboxToggle=="object"?this.checkboxToggle:{tag:"input",type:"checkbox",name:this.checkboxName||this.id+"-checkbox"};this.checkbox=this.header.insertFirst(c);this.checkbox.dom.checked=!this.collapsed;this.mon(this.checkbox,"click",this.onCheckClick,this)}},onCollapse:function(a,b){if(this.checkbox){this.checkbox.dom.checked=false}Ext.form.FieldSet.superclass.onCollapse.call(this,a,b)},onExpand:function(a,b){if(this.checkbox){this.checkbox.dom.checked=true}Ext.form.FieldSet.superclass.onExpand.call(this,a,b)},onCheckClick:function(){this[this.checkbox.dom.checked?"expand":"collapse"]()}});Ext.reg("fieldset",Ext.form.FieldSet);Ext.form.HtmlEditor=Ext.extend(Ext.form.Field,{enableFormat:true,enableFontSize:true,enableColors:true,enableAlignments:true,enableLists:true,enableSourceEdit:true,enableLinks:true,enableFont:true,createLinkText:"Please enter the URL for the link:",defaultLinkValue:"http://",fontFamilies:["Arial","Courier New","Tahoma","Times New Roman","Verdana"],defaultFont:"tahoma",defaultValue:(Ext.isOpera||Ext.isIE6)?"&#160;":"&#8203;",actionMode:"wrap",validationEvent:false,deferHeight:true,initialized:false,activated:false,sourceEditMode:false,onFocus:Ext.emptyFn,iframePad:3,hideMode:"offsets",defaultAutoCreate:{tag:"textarea",style:"width:500px;height:300px;",autocomplete:"off"},initComponent:function(){this.addEvents("initialize","activate","beforesync","beforepush","sync","push","editmodechange");Ext.form.HtmlEditor.superclass.initComponent.call(this)},createFontOptions:function(){var d=[],b=this.fontFamilies,c,g;for(var e=0,a=b.length;e<a;e++){c=b[e];g=c.toLowerCase();d.push('<option value="',g,'" style="font-family:',c,';"',(this.defaultFont==g?' selected="true">':">"),c,"</option>")}return d.join("")},createToolbar:function(e){var c=[];var a=Ext.QuickTips&&Ext.QuickTips.isEnabled();function d(j,h,i){return{itemId:j,cls:"x-btn-icon",iconCls:"x-edit-"+j,enableToggle:h!==false,scope:e,handler:i||e.relayBtnCmd,clickEvent:"mousedown",tooltip:a?e.buttonTips[j]||undefined:undefined,overflowText:e.buttonTips[j].title||undefined,tabIndex:-1}}if(this.enableFont&&!Ext.isSafari2){var g=new Ext.Toolbar.Item({autoEl:{tag:"select",cls:"x-font-select",html:this.createFontOptions()}});c.push(g,"-")}if(this.enableFormat){c.push(d("bold"),d("italic"),d("underline"))}if(this.enableFontSize){c.push("-",d("increasefontsize",false,this.adjustFont),d("decreasefontsize",false,this.adjustFont))}if(this.enableColors){c.push("-",{itemId:"forecolor",cls:"x-btn-icon",iconCls:"x-edit-forecolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.forecolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({allowReselect:true,focus:Ext.emptyFn,value:"000000",plain:true,listeners:{scope:this,select:function(i,h){this.execCmd("forecolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}},clickEvent:"mousedown"})},{itemId:"backcolor",cls:"x-btn-icon",iconCls:"x-edit-backcolor",clickEvent:"mousedown",tooltip:a?e.buttonTips.backcolor||undefined:undefined,tabIndex:-1,menu:new Ext.menu.ColorMenu({focus:Ext.emptyFn,value:"FFFFFF",plain:true,allowReselect:true,listeners:{scope:this,select:function(i,h){if(Ext.isGecko){this.execCmd("useCSS",false);this.execCmd("hilitecolor",h);this.execCmd("useCSS",true);this.deferFocus()}else{this.execCmd(Ext.isOpera?"hilitecolor":"backcolor",Ext.isWebKit||Ext.isIE?"#"+h:h);this.deferFocus()}}},clickEvent:"mousedown"})})}if(this.enableAlignments){c.push("-",d("justifyleft"),d("justifycenter"),d("justifyright"))}if(!Ext.isSafari2){if(this.enableLinks){c.push("-",d("createlink",false,this.createLink))}if(this.enableLists){c.push("-",d("insertorderedlist"),d("insertunorderedlist"))}if(this.enableSourceEdit){c.push("-",d("sourceedit",true,function(h){this.toggleSourceEdit(!this.sourceEditMode)}))}}var b=new Ext.Toolbar({renderTo:this.wrap.dom.firstChild,items:c});if(g){this.fontSelect=g.el;this.mon(this.fontSelect,"change",function(){var h=this.fontSelect.dom.value;this.relayCmd("fontname",h);this.deferFocus()},this)}this.mon(b.el,"click",function(h){h.preventDefault()});this.tb=b;this.tb.doLayout()},onDisable:function(){this.wrap.mask();Ext.form.HtmlEditor.superclass.onDisable.call(this)},onEnable:function(){this.wrap.unmask();Ext.form.HtmlEditor.superclass.onEnable.call(this)},setReadOnly:function(b){Ext.form.HtmlEditor.superclass.setReadOnly.call(this,b);if(this.initialized){if(Ext.isIE){this.getEditorBody().contentEditable=!b}else{this.setDesignMode(!b)}var a=this.getEditorBody();if(a){a.style.cursor=this.readOnly?"default":"text"}this.disableItems(b)}},getDocMarkup:function(){var a=Ext.fly(this.iframe).getHeight()-this.iframePad*2;return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>',this.iframePad,a)},getEditorBody:function(){var a=this.getDoc();return a.body||a.documentElement},getDoc:function(){return Ext.isIE?this.getWin().document:(this.iframe.contentDocument||this.getWin().document)},getWin:function(){return Ext.isIE?this.iframe.contentWindow:window.frames[this.iframe.name]},onRender:function(b,a){Ext.form.HtmlEditor.superclass.onRender.call(this,b,a);this.el.dom.style.border="0 none";this.el.dom.setAttribute("tabIndex",-1);this.el.addClass("x-hidden");if(Ext.isIE){this.el.applyStyles("margin-top:-1px;margin-bottom:-1px;")}this.wrap=this.el.wrap({cls:"x-html-editor-wrap",cn:{cls:"x-html-editor-tb"}});this.createToolbar(this);this.disableItems(true);this.tb.doLayout();this.createIFrame();if(!this.width){var c=this.el.getSize();this.setSize(c.width,this.height||c.height)}this.resizeEl=this.positionEl=this.wrap},createIFrame:function(){var a=document.createElement("iframe");a.name=Ext.id();a.frameBorder="0";a.style.overflow="auto";a.src=Ext.SSL_SECURE_URL;this.wrap.dom.appendChild(a);this.iframe=a;this.monitorTask=Ext.TaskMgr.start({run:this.checkDesignMode,scope:this,interval:100})},initFrame:function(){Ext.TaskMgr.stop(this.monitorTask);var a=this.getDoc();this.win=this.getWin();a.open();a.write(this.getDocMarkup());a.close();this.readyTask={run:function(){var b=this.getDoc();if(b.body||b.readyState=="complete"){Ext.TaskMgr.stop(this.readyTask);this.setDesignMode(true);this.initEditor.defer(10,this)}},interval:10,duration:10000,scope:this};Ext.TaskMgr.start(this.readyTask)},checkDesignMode:function(){if(this.wrap&&this.wrap.dom.offsetWidth){var a=this.getDoc();if(!a){return}if(!a.editorInitialized||this.getDesignMode()!="on"){this.initFrame()}}},setDesignMode:function(b){var a=this.getDoc();if(a){if(this.readOnly){b=false}a.designMode=(/on|true/i).test(String(b).toLowerCase())?"on":"off"}},getDesignMode:function(){var a=this.getDoc();if(!a){return""}return String(a.designMode).toLowerCase()},disableItems:function(a){if(this.fontSelect){this.fontSelect.dom.disabled=a}this.tb.items.each(function(b){if(b.getItemId()!="sourceedit"){b.setDisabled(a)}})},onResize:function(b,c){Ext.form.HtmlEditor.superclass.onResize.apply(this,arguments);if(this.el&&this.iframe){if(Ext.isNumber(b)){var e=b-this.wrap.getFrameWidth("lr");this.el.setWidth(e);this.tb.setWidth(e);this.iframe.style.width=Math.max(e,0)+"px"}if(Ext.isNumber(c)){var a=c-this.wrap.getFrameWidth("tb")-this.tb.el.getHeight();this.el.setHeight(a);this.iframe.style.height=Math.max(a,0)+"px";var d=this.getEditorBody();if(d){d.style.height=Math.max((a-(this.iframePad*2)),0)+"px"}}}},toggleSourceEdit:function(b){var d,a;if(b===undefined){b=!this.sourceEditMode}this.sourceEditMode=b===true;var c=this.tb.getComponent("sourceedit");if(c.pressed!==this.sourceEditMode){c.toggle(this.sourceEditMode);if(!c.xtbHidden){return}}if(this.sourceEditMode){this.previousSize=this.getSize();d=Ext.get(this.iframe).getHeight();this.disableItems(true);this.syncValue();this.iframe.className="x-hidden";this.el.removeClass("x-hidden");this.el.dom.removeAttribute("tabIndex");this.el.focus();this.el.dom.style.height=d+"px"}else{a=parseInt(this.el.dom.style.height,10);if(this.initialized){this.disableItems(this.readOnly)}this.pushValue();this.iframe.className="";this.el.addClass("x-hidden");this.el.dom.setAttribute("tabIndex",-1);this.deferFocus();this.setSize(this.previousSize);delete this.previousSize;this.iframe.style.height=a+"px"}this.fireEvent("editmodechange",this,this.sourceEditMode)},createLink:function(){var a=prompt(this.createLinkText,this.defaultLinkValue);if(a&&a!="http://"){this.relayCmd("createlink",a)}},initEvents:function(){this.originalValue=this.getValue()},markInvalid:Ext.emptyFn,clearInvalid:Ext.emptyFn,setValue:function(a){Ext.form.HtmlEditor.superclass.setValue.call(this,a);this.pushValue();return this},cleanHtml:function(a){a=String(a);if(Ext.isWebKit){a=a.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,"")}if(a.charCodeAt(0)==this.defaultValue.replace(/\D/g,"")){a=a.substring(1)}return a},syncValue:function(){if(this.initialized){var d=this.getEditorBody();var c=d.innerHTML;if(Ext.isWebKit){var b=d.getAttribute("style");var a=b.match(/text-align:(.*?);/i);if(a&&a[1]){c='<div style="'+a[0]+'">'+c+"</div>"}}c=this.cleanHtml(c);if(this.fireEvent("beforesync",this,c)!==false){this.el.dom.value=c;this.fireEvent("sync",this,c)}}},getValue:function(){this[this.sourceEditMode?"pushValue":"syncValue"]();return Ext.form.HtmlEditor.superclass.getValue.call(this)},pushValue:function(){if(this.initialized){var a=this.el.dom.value;if(!this.activated&&a.length<1){a=this.defaultValue}if(this.fireEvent("beforepush",this,a)!==false){this.getEditorBody().innerHTML=a;if(Ext.isGecko){this.setDesignMode(false);this.setDesignMode(true)}this.fireEvent("push",this,a)}}},deferFocus:function(){this.focus.defer(10,this)},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus()}else{this.el.focus()}},initEditor:function(){try{var c=this.getEditorBody(),a=this.el.getStyles("font-size","font-family","background-image","background-repeat","background-color","color"),g,b;a["background-attachment"]="fixed";c.bgProperties="fixed";Ext.DomHelper.applyStyles(c,a);g=this.getDoc();if(g){try{Ext.EventManager.removeAll(g)}catch(d){}}b=this.onEditorEvent.createDelegate(this);Ext.EventManager.on(g,{mousedown:b,dblclick:b,click:b,keyup:b,buffer:100});if(Ext.isGecko){Ext.EventManager.on(g,"keypress",this.applyCommand,this)}if(Ext.isIE||Ext.isWebKit||Ext.isOpera){Ext.EventManager.on(g,"keydown",this.fixKeys,this)}g.editorInitialized=true;this.initialized=true;this.pushValue();this.setReadOnly(this.readOnly);this.fireEvent("initialize",this)}catch(d){}},beforeDestroy:function(){if(this.monitorTask){Ext.TaskMgr.stop(this.monitorTask)}if(this.readyTask){Ext.TaskMgr.stop(this.readyTask)}if(this.rendered){Ext.destroy(this.tb);var b=this.getDoc();Ext.EventManager.removeFromSpecialCache(b);if(b){try{Ext.EventManager.removeAll(b);for(var c in b){delete b[c]}}catch(a){}}if(this.wrap){this.wrap.dom.innerHTML="";this.wrap.remove()}}Ext.form.HtmlEditor.superclass.beforeDestroy.call(this)},onFirstFocus:function(){this.activated=true;this.disableItems(this.readOnly);if(Ext.isGecko){this.win.focus();var a=this.win.getSelection();if(!a.focusNode||a.focusNode.nodeType!=3){var b=a.getRangeAt(0);b.selectNodeContents(this.getEditorBody());b.collapse(true);this.deferFocus()}try{this.execCmd("useCSS",true);this.execCmd("styleWithCSS",false)}catch(c){}}this.fireEvent("activate",this)},adjustFont:function(b){var d=b.getItemId()=="increasefontsize"?1:-1,c=this.getDoc(),a=parseInt(c.queryCommandValue("FontSize")||2,10);if((Ext.isSafari&&!Ext.isSafari2)||Ext.isChrome||Ext.isAir){if(a<=10){a=1+d}else{if(a<=13){a=2+d}else{if(a<=16){a=3+d}else{if(a<=18){a=4+d}else{if(a<=24){a=5+d}else{a=6+d}}}}}a=a.constrain(1,6)}else{if(Ext.isSafari){d*=2}a=Math.max(1,a+d)+(Ext.isSafari?"px":0)}this.execCmd("FontSize",a)},onEditorEvent:function(a){this.updateToolbar()},updateToolbar:function(){if(this.readOnly){return}if(!this.activated){this.onFirstFocus();return}var b=this.tb.items.map,c=this.getDoc();if(this.enableFont&&!Ext.isSafari2){var a=(c.queryCommandValue("FontName")||this.defaultFont).toLowerCase();if(a!=this.fontSelect.dom.value){this.fontSelect.dom.value=a}}if(this.enableFormat){b.bold.toggle(c.queryCommandState("bold"));b.italic.toggle(c.queryCommandState("italic"));b.underline.toggle(c.queryCommandState("underline"))}if(this.enableAlignments){b.justifyleft.toggle(c.queryCommandState("justifyleft"));b.justifycenter.toggle(c.queryCommandState("justifycenter"));b.justifyright.toggle(c.queryCommandState("justifyright"))}if(!Ext.isSafari2&&this.enableLists){b.insertorderedlist.toggle(c.queryCommandState("insertorderedlist"));b.insertunorderedlist.toggle(c.queryCommandState("insertunorderedlist"))}Ext.menu.MenuMgr.hideAll();this.syncValue()},relayBtnCmd:function(a){this.relayCmd(a.getItemId())},relayCmd:function(b,a){(function(){this.focus();this.execCmd(b,a);this.updateToolbar()}).defer(10,this)},execCmd:function(b,a){var c=this.getDoc();c.execCommand(b,false,a===undefined?null:a);this.syncValue()},applyCommand:function(b){if(b.ctrlKey){var d=b.getCharCode(),a;if(d>0){d=String.fromCharCode(d);switch(d){case"b":a="bold";break;case"i":a="italic";break;case"u":a="underline";break}if(a){this.win.focus();this.execCmd(a);this.deferFocus();b.preventDefault()}}}},insertAtCursor:function(c){if(!this.activated){return}if(Ext.isIE){this.win.focus();var b=this.getDoc(),a=b.selection.createRange();if(a){a.pasteHTML(c);this.syncValue();this.deferFocus()}}else{this.win.focus();this.execCmd("InsertHTML",c);this.deferFocus()}},fixKeys:function(){if(Ext.isIE){return function(g){var a=g.getKey(),d=this.getDoc(),b;if(a==g.TAB){g.stopEvent();b=d.selection.createRange();if(b){b.collapse(true);b.pasteHTML("&nbsp;&nbsp;&nbsp;&nbsp;");this.deferFocus()}}else{if(a==g.ENTER){b=d.selection.createRange();if(b){var c=b.parentElement();if(!c||c.tagName.toLowerCase()!="li"){g.stopEvent();b.pasteHTML("<br />");b.collapse(false);b.select()}}}}}}else{if(Ext.isOpera){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.win.focus();this.execCmd("InsertHTML","&nbsp;&nbsp;&nbsp;&nbsp;");this.deferFocus()}}}else{if(Ext.isWebKit){return function(b){var a=b.getKey();if(a==b.TAB){b.stopEvent();this.execCmd("InsertText","\t");this.deferFocus()}else{if(a==b.ENTER){b.stopEvent();this.execCmd("InsertHtml","<br /><br />");this.deferFocus()}}}}}}}(),getToolbar:function(){return this.tb},buttonTips:{bold:{title:"Bold (Ctrl+B)",text:"Make the selected text bold.",cls:"x-html-editor-tip"},italic:{title:"Italic (Ctrl+I)",text:"Make the selected text italic.",cls:"x-html-editor-tip"},underline:{title:"Underline (Ctrl+U)",text:"Underline the selected text.",cls:"x-html-editor-tip"},increasefontsize:{title:"Grow Text",text:"Increase the font size.",cls:"x-html-editor-tip"},decreasefontsize:{title:"Shrink Text",text:"Decrease the font size.",cls:"x-html-editor-tip"},backcolor:{title:"Text Highlight Color",text:"Change the background color of the selected text.",cls:"x-html-editor-tip"},forecolor:{title:"Font Color",text:"Change the color of the selected text.",cls:"x-html-editor-tip"},justifyleft:{title:"Align Text Left",text:"Align text to the left.",cls:"x-html-editor-tip"},justifycenter:{title:"Center Text",text:"Center text in the editor.",cls:"x-html-editor-tip"},justifyright:{title:"Align Text Right",text:"Align text to the right.",cls:"x-html-editor-tip"},insertunorderedlist:{title:"Bullet List",text:"Start a bulleted list.",cls:"x-html-editor-tip"},insertorderedlist:{title:"Numbered List",text:"Start a numbered list.",cls:"x-html-editor-tip"},createlink:{title:"Hyperlink",text:"Make the selected text a hyperlink.",cls:"x-html-editor-tip"},sourceedit:{title:"Source Edit",text:"Switch to source editing mode.",cls:"x-html-editor-tip"}}});Ext.reg("htmleditor",Ext.form.HtmlEditor);Ext.form.TimeField=Ext.extend(Ext.form.ComboBox,{minValue:undefined,maxValue:undefined,minText:"The time in this field must be equal to or after {0}",maxText:"The time in this field must be equal to or before {0}",invalidText:"{0} is not a valid time",format:"g:i A",altFormats:"g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",increment:15,mode:"local",triggerAction:"all",typeAhead:false,initDate:"1/1/2008",initDateFormat:"j/n/Y",initComponent:function(){if(Ext.isDefined(this.minValue)){this.setMinValue(this.minValue,true)}if(Ext.isDefined(this.maxValue)){this.setMaxValue(this.maxValue,true)}if(!this.store){this.generateStore(true)}Ext.form.TimeField.superclass.initComponent.call(this)},setMinValue:function(b,a){this.setLimit(b,true,a);return this},setMaxValue:function(b,a){this.setLimit(b,false,a);return this},generateStore:function(b){var c=this.minValue||new Date(this.initDate).clearTime(),a=this.maxValue||new Date(this.initDate).clearTime().add("mi",(24*60)-1),d=[];while(c<=a){d.push(c.dateFormat(this.format));c=c.add("mi",this.increment)}this.bindStore(d,b)},setLimit:function(b,g,a){var e;if(Ext.isString(b)){e=this.parseDate(b)}else{if(Ext.isDate(b)){e=b}}if(e){var c=new Date(this.initDate).clearTime();c.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds());this[g?"minValue":"maxValue"]=c;if(!a){this.generateStore()}}},getValue:function(){var a=Ext.form.TimeField.superclass.getValue.call(this);return this.formatDate(this.parseDate(a))||""},setValue:function(a){return Ext.form.TimeField.superclass.setValue.call(this,this.formatDate(this.parseDate(a)))},validateValue:Ext.form.DateField.prototype.validateValue,formatDate:Ext.form.DateField.prototype.formatDate,parseDate:function(h){if(!h||Ext.isDate(h)){return h}var j=this.initDate+" ",g=this.initDateFormat+" ",b=Date.parseDate(j+h,g+this.format),c=this.altFormats;if(!b&&c){if(!this.altFormatsArray){this.altFormatsArray=c.split("|")}for(var e=0,d=this.altFormatsArray,a=d.length;e<a&&!b;e++){b=Date.parseDate(j+h,g+d[e])}}return b}});Ext.reg("timefield",Ext.form.TimeField);Ext.form.SliderField=Ext.extend(Ext.form.Field,{useTips:true,tipText:null,actionMode:"wrap",initComponent:function(){var b=Ext.copyTo({id:this.id+"-slider"},this.initialConfig,["vertical","minValue","maxValue","decimalPrecision","keyIncrement","increment","clickToChange","animate"]);if(this.useTips){var a=this.tipText?{getText:this.tipText}:{};b.plugins=[new Ext.slider.Tip(a)]}this.slider=new Ext.Slider(b);Ext.form.SliderField.superclass.initComponent.call(this)},onRender:function(b,a){this.autoCreate={id:this.id,name:this.name,type:"hidden",tag:"input"};Ext.form.SliderField.superclass.onRender.call(this,b,a);this.wrap=this.el.wrap({cls:"x-form-field-wrap"});this.resizeEl=this.positionEl=this.wrap;this.slider.render(this.wrap)},onResize:function(b,c,d,a){Ext.form.SliderField.superclass.onResize.call(this,b,c,d,a);this.slider.setSize(b,c)},initEvents:function(){Ext.form.SliderField.superclass.initEvents.call(this);this.slider.on("change",this.onChange,this)},onChange:function(b,a){this.setValue(a,undefined,true)},onEnable:function(){Ext.form.SliderField.superclass.onEnable.call(this);this.slider.enable()},onDisable:function(){Ext.form.SliderField.superclass.onDisable.call(this);this.slider.disable()},beforeDestroy:function(){Ext.destroy(this.slider);Ext.form.SliderField.superclass.beforeDestroy.call(this)},alignErrorIcon:function(){this.errorIcon.alignTo(this.slider.el,"tl-tr",[2,0])},setMinValue:function(a){this.slider.setMinValue(a);return this},setMaxValue:function(a){this.slider.setMaxValue(a);return this},setValue:function(c,b,a){if(!a){this.slider.setValue(c,b)}return Ext.form.SliderField.superclass.setValue.call(this,this.slider.getValue())},getValue:function(){return this.slider.getValue()}});Ext.reg("sliderfield",Ext.form.SliderField);Ext.form.Label=Ext.extend(Ext.BoxComponent,{onRender:function(b,a){if(!this.el){this.el=document.createElement("label");this.el.id=this.getId();this.el.innerHTML=this.text?Ext.util.Format.htmlEncode(this.text):(this.html||"");if(this.forId){this.el.setAttribute("for",this.forId)}}Ext.form.Label.superclass.onRender.call(this,b,a)},setText:function(a,b){var c=b===false;this[!c?"text":"html"]=a;delete this[c?"text":"html"];if(this.rendered){this.el.dom.innerHTML=b!==false?Ext.util.Format.htmlEncode(a):a}return this}});Ext.reg("label",Ext.form.Label);Ext.form.Action=function(b,a){this.form=b;this.options=a||{}};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",run:function(a){},success:function(a){},handleResponse:function(a){},failure:function(a){this.response=a;this.failureType=Ext.form.Action.CONNECT_FAILURE;this.form.afterAction(this,false)},processResponse:function(a){this.response=a;if(!a.responseText&&!a.responseXML){return true}this.result=this.handleResponse(a);return this.result},decodeResponse:function(a){try{return Ext.decode(a.responseText)}catch(b){return false}},getUrl:function(c){var a=this.options.url||this.form.url||this.form.el.dom.action;if(c){var b=this.getParams();if(b){a=Ext.urlAppend(a,b)}}return a},getMethod:function(){return(this.options.method||this.form.method||this.form.el.dom.method||"POST").toUpperCase()},getParams:function(){var a=this.form.baseParams;var b=this.options.params;if(b){if(typeof b=="object"){b=Ext.urlEncode(Ext.applyIf(b,a))}else{if(typeof b=="string"&&a){b+="&"+Ext.urlEncode(a)}}}else{if(a){b=Ext.urlEncode(a)}}return b},createCallback:function(a){var a=a||{};return{success:this.success,failure:this.failure,scope:this,timeout:(a.timeout*1000)||(this.form.timeout*1000),upload:this.form.fileUpload?this.success:undefined}}};Ext.form.Action.Submit=function(b,a){Ext.form.Action.Submit.superclass.constructor.call(this,b,a)};Ext.extend(Ext.form.Action.Submit,Ext.form.Action,{type:"submit",run:function(){var e=this.options,g=this.getMethod(),d=g=="GET";if(e.clientValidation===false||this.form.isValid()){if(e.submitEmptyText===false){var a=this.form.items,c=[],b=function(h){if(h.el.getValue()==h.emptyText){c.push(h);h.el.dom.value=""}if(h.isComposite&&h.rendered){h.items.each(b)}};a.each(b)}Ext.Ajax.request(Ext.apply(this.createCallback(e),{form:this.form.el.dom,url:this.getUrl(d),method:g,headers:e.headers,params:!d?this.getParams():null,isUpload:this.form.fileUpload}));if(e.submitEmptyText===false){Ext.each(c,function(h){if(h.applyEmptyText){h.applyEmptyText()}})}}else{if(e.clientValidation!==false){this.failureType=Ext.form.Action.CLIENT_INVALID;this.form.afterAction(this,false)}}},success:function(b){var a=this.processResponse(b);if(a===true||a.success){this.form.afterAction(this,true);return}if(a.errors){this.form.markInvalid(a.errors)}this.failureType=Ext.form.Action.SERVER_INVALID;this.form.afterAction(this,false)},handleResponse:function(c){if(this.form.errorReader){var b=this.form.errorReader.read(c);var g=[];if(b.records){for(var d=0,a=b.records.length;d<a;d++){var e=b.records[d];g[d]=e.data}}if(g.length<1){g=null}return{success:b.success,errors:g}}return this.decodeResponse(c)}});Ext.form.Action.Load=function(b,a){Ext.form.Action.Load.superclass.constructor.call(this,b,a);this.reader=this.form.reader};Ext.extend(Ext.form.Action.Load,Ext.form.Action,{type:"load",run:function(){Ext.Ajax.request(Ext.apply(this.createCallback(this.options),{method:this.getMethod(),url:this.getUrl(false),headers:this.options.headers,params:this.getParams()}))},success:function(b){var a=this.processResponse(b);if(a===true||!a.success||!a.data){this.failureType=Ext.form.Action.LOAD_FAILURE;this.form.afterAction(this,false);return}this.form.clearInvalid();this.form.setValues(a.data);this.form.afterAction(this,true)},handleResponse:function(b){if(this.form.reader){var a=this.form.reader.read(b);var c=a.records&&a.records[0]?a.records[0].data:null;return{success:a.success,data:c}}return this.decodeResponse(b)}});Ext.form.Action.DirectLoad=Ext.extend(Ext.form.Action.Load,{constructor:function(b,a){Ext.form.Action.DirectLoad.superclass.constructor.call(this,b,a)},type:"directload",run:function(){var a=this.getParams();a.push(this.success,this);this.form.api.load.apply(window,a)},getParams:function(){var c=[],h={};var e=this.form.baseParams;var g=this.options.params;Ext.apply(h,g,e);var b=this.form.paramOrder;if(b){for(var d=0,a=b.length;d<a;d++){c.push(h[b[d]])}}else{if(this.form.paramsAsHash){c.push(h)}}return c},processResponse:function(a){this.result=a;return a},success:function(a,b){if(b.type==Ext.Direct.exceptions.SERVER){a={}}Ext.form.Action.DirectLoad.superclass.success.call(this,a)}});Ext.form.Action.DirectSubmit=Ext.extend(Ext.form.Action.Submit,{constructor:function(b,a){Ext.form.Action.DirectSubmit.superclass.constructor.call(this,b,a)},type:"directsubmit",run:function(){var a=this.options;if(a.clientValidation===false||this.form.isValid()){this.success.params=this.getParams();this.form.api.submit(this.form.el.dom,this.success,this)}else{if(a.clientValidation!==false){this.failureType=Ext.form.Action.CLIENT_INVALID;this.form.afterAction(this,false)}}},getParams:function(){var c={};var a=this.form.baseParams;var b=this.options.params;Ext.apply(c,b,a);return c},processResponse:function(a){this.result=a;return a},success:function(a,b){if(b.type==Ext.Direct.exceptions.SERVER){a={}}Ext.form.Action.DirectSubmit.superclass.success.call(this,a)}});Ext.form.Action.ACTION_TYPES={load:Ext.form.Action.Load,submit:Ext.form.Action.Submit,directload:Ext.form.Action.DirectLoad,directsubmit:Ext.form.Action.DirectSubmit};Ext.form.VTypes=function(){var c=/^[a-zA-Z_]+$/,d=/^[a-zA-Z0-9_]+$/,b=/^(\w+)([\-+.\'][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,a=/(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;return{email:function(e){return b.test(e)},emailText:'This field should be an e-mail address in the format "user@example.com"',emailMask:/[a-z0-9_\.\-\+\'@]/i,url:function(e){return a.test(e)},urlText:'This field should be a URL in the format "http://www.example.com"',alpha:function(e){return c.test(e)},alphaText:"This field should only contain letters and _",alphaMask:/[a-z_]/i,alphanum:function(e){return d.test(e)},alphanumText:"This field should only contain letters, numbers and _",alphanumMask:/[a-z0-9_]/i}}();Ext.grid.GridPanel=Ext.extend(Ext.Panel,{autoExpandColumn:false,autoExpandMax:1000,autoExpandMin:50,columnLines:false,ddText:"{0} selected row{1}",deferRowRender:true,enableColumnHide:true,enableColumnMove:true,enableDragDrop:false,enableHdMenu:true,loadMask:false,minColumnWidth:25,stripeRows:false,trackMouseOver:true,stateEvents:["columnmove","columnresize","sortchange","groupchange"],view:null,bubbleEvents:[],rendered:false,viewReady:false,initComponent:function(){Ext.grid.GridPanel.superclass.initComponent.call(this);if(this.columnLines){this.cls=(this.cls||"")+" x-grid-with-col-lines"}this.autoScroll=false;this.autoWidth=false;if(Ext.isArray(this.columns)){this.colModel=new Ext.grid.ColumnModel(this.columns);delete this.columns}if(this.ds){this.store=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}this.store=Ext.StoreMgr.lookup(this.store);this.addEvents("click","dblclick","contextmenu","mousedown","mouseup","mouseover","mouseout","keypress","keydown","cellmousedown","rowmousedown","headermousedown","groupmousedown","rowbodymousedown","containermousedown","cellclick","celldblclick","rowclick","rowdblclick","headerclick","headerdblclick","groupclick","groupdblclick","containerclick","containerdblclick","rowbodyclick","rowbodydblclick","rowcontextmenu","cellcontextmenu","headercontextmenu","groupcontextmenu","containercontextmenu","rowbodycontextmenu","bodyscroll","columnresize","columnmove","sortchange","groupchange","reconfigure","viewready")},onRender:function(d,a){Ext.grid.GridPanel.superclass.onRender.apply(this,arguments);var e=this.getGridEl();this.el.addClass("x-grid-panel");this.mon(e,{scope:this,mousedown:this.onMouseDown,click:this.onClick,dblclick:this.onDblClick,contextmenu:this.onContextMenu});this.relayEvents(e,["mousedown","mouseup","mouseover","mouseout","keypress","keydown"]);var b=this.getView();b.init(this);b.render();this.getSelectionModel().init(this)},initEvents:function(){Ext.grid.GridPanel.superclass.initEvents.call(this);if(this.loadMask){this.loadMask=new Ext.LoadMask(this.bwrap,Ext.apply({store:this.store},this.loadMask))}},initStateEvents:function(){Ext.grid.GridPanel.superclass.initStateEvents.call(this);this.mon(this.colModel,"hiddenchange",this.saveState,this,{delay:100})},applyState:function(a){var k=this.colModel,g=a.columns,j=this.store,m,h,l;if(g){for(var d=0,e=g.length;d<e;d++){m=g[d];h=k.getColumnById(m.id);if(h){l=k.getIndexById(m.id);k.setState(l,{hidden:m.hidden,width:m.width,sortable:h.sortable,editable:h.editable});if(l!=d){k.moveColumn(l,d)}}}}if(j){m=a.sort;if(m){j[j.remoteSort?"setDefaultSort":"sort"](m.field,m.direction)}m=a.group;if(j.groupBy){if(m){j.groupBy(m)}else{j.clearGrouping()}}}var b=Ext.apply({},a);delete b.columns;delete b.sort;Ext.grid.GridPanel.superclass.applyState.call(this,b)},getState:function(){var g={columns:[]},b=this.store,e,a;for(var d=0,h;(h=this.colModel.config[d]);d++){g.columns[d]={id:h.id,width:h.width};if(h.hidden){g.columns[d].hidden=true}}if(b){e=b.getSortState();if(e){g.sort=e}if(b.getGroupState){a=b.getGroupState();if(a){g.group=a}}}return g},afterRender:function(){Ext.grid.GridPanel.superclass.afterRender.call(this);var a=this.view;this.on("bodyresize",a.layout,a);a.layout(true);if(this.deferRowRender){if(!this.deferRowRenderTask){this.deferRowRenderTask=new Ext.util.DelayedTask(a.afterRender,this.view)}this.deferRowRenderTask.delay(10)}else{a.afterRender()}this.viewReady=true},reconfigure:function(a,b){var c=this.rendered;if(c){if(this.loadMask){this.loadMask.destroy();this.loadMask=new Ext.LoadMask(this.bwrap,Ext.apply({},{store:a},this.initialConfig.loadMask))}}if(this.view){this.view.initData(a,b)}this.store=a;this.colModel=b;if(c){this.view.refresh(true)}this.fireEvent("reconfigure",this,a,b)},onDestroy:function(){if(this.deferRowRenderTask&&this.deferRowRenderTask.cancel){this.deferRowRenderTask.cancel()}if(this.rendered){Ext.destroy(this.view,this.loadMask)}else{if(this.store&&this.store.autoDestroy){this.store.destroy()}}Ext.destroy(this.colModel,this.selModel);this.store=this.selModel=this.colModel=this.view=this.loadMask=null;Ext.grid.GridPanel.superclass.onDestroy.call(this)},processEvent:function(a,b){this.view.processEvent(a,b)},onClick:function(a){this.processEvent("click",a)},onMouseDown:function(a){this.processEvent("mousedown",a)},onContextMenu:function(b,a){this.processEvent("contextmenu",b)},onDblClick:function(a){this.processEvent("dblclick",a)},walkCells:function(k,c,b,e,j){var i=this.colModel,g=i.getColumnCount(),a=this.store,h=a.getCount(),d=true;if(b<0){if(c<0){k--;d=false}while(k>=0){if(!d){c=g-1}d=false;while(c>=0){if(e.call(j||this,k,c,i)===true){return[k,c]}c--}k--}}else{if(c>=g){k++;d=false}while(k<h){if(!d){c=0}d=false;while(c<g){if(e.call(j||this,k,c,i)===true){return[k,c]}c++}k++}}return null},getGridEl:function(){return this.body},stopEditing:Ext.emptyFn,getSelectionModel:function(){if(!this.selModel){this.selModel=new Ext.grid.RowSelectionModel(this.disableSelection?{selectRow:Ext.emptyFn}:null)}return this.selModel},getStore:function(){return this.store},getColumnModel:function(){return this.colModel},getView:function(){if(!this.view){this.view=new Ext.grid.GridView(this.viewConfig)}return this.view},getDragDropText:function(){var a=this.selModel.getCount?this.selModel.getCount():1;return String.format(this.ddText,a,a==1?"":"s")}});Ext.reg("grid",Ext.grid.GridPanel);Ext.grid.PivotGrid=Ext.extend(Ext.grid.GridPanel,{aggregator:"sum",renderer:undefined,initComponent:function(){Ext.grid.PivotGrid.superclass.initComponent.apply(this,arguments);this.initAxes();this.enableColumnResize=false;this.viewConfig=Ext.apply(this.viewConfig||{},{forceFit:true});this.colModel=new Ext.grid.ColumnModel({})},getAggregator:function(){if(typeof this.aggregator=="string"){return Ext.grid.PivotAggregatorMgr.types[this.aggregator]}else{return this.aggregator}},setAggregator:function(a){this.aggregator=a},setMeasure:function(a){this.measure=a},setLeftAxis:function(b,a){this.leftAxis=b;if(a){this.view.refresh()}},setTopAxis:function(b,a){this.topAxis=b;if(a){this.view.refresh()}},initAxes:function(){var a=Ext.grid.PivotAxis;if(!(this.leftAxis instanceof a)){this.setLeftAxis(new a({orientation:"vertical",dimensions:this.leftAxis||[],store:this.store}))}if(!(this.topAxis instanceof a)){this.setTopAxis(new a({orientation:"horizontal",dimensions:this.topAxis||[],store:this.store}))}},extractData:function(){var c=this.store.data.items,s=c.length,q=[],h,g,e,d;if(s==0){return[]}var l=this.leftAxis.getTuples(),o=l.length,m=this.topAxis.getTuples(),a=m.length,b=this.getAggregator();for(g=0;g<s;g++){h=c[g];for(e=0;e<o;e++){q[e]=q[e]||[];if(l[e].matcher(h)===true){for(d=0;d<a;d++){q[e][d]=q[e][d]||[];if(m[d].matcher(h)){q[e][d].push(h)}}}}}var n=q.length,p,r;for(g=0;g<n;g++){r=q[g];p=r.length;for(e=0;e<p;e++){q[g][e]=b(q[g][e],this.measure)}}return q},getView:function(){if(!this.view){this.view=new Ext.grid.PivotGridView(this.viewConfig)}return this.view}});Ext.reg("pivotgrid",Ext.grid.PivotGrid);Ext.grid.PivotAggregatorMgr=new Ext.AbstractManager();Ext.grid.PivotAggregatorMgr.registerType("sum",function(a,c){var e=a.length,d=0,b;for(b=0;b<e;b++){d+=a[b].get(c)}return d});Ext.grid.PivotAggregatorMgr.registerType("avg",function(a,c){var e=a.length,d=0,b;for(b=0;b<e;b++){d+=a[b].get(c)}return(d/e)||"n/a"});Ext.grid.PivotAggregatorMgr.registerType("min",function(a,c){var e=[],d=a.length,b;for(b=0;b<d;b++){e.push(a[b].get(c))}return Math.min.apply(this,e)||"n/a"});Ext.grid.PivotAggregatorMgr.registerType("max",function(a,c){var e=[],d=a.length,b;for(b=0;b<d;b++){e.push(a[b].get(c))}return Math.max.apply(this,e)||"n/a"});Ext.grid.PivotAggregatorMgr.registerType("count",function(a,b){return a.length});Ext.grid.GridView=Ext.extend(Ext.util.Observable,{deferEmptyText:true,scrollOffset:undefined,autoFill:false,forceFit:false,sortClasses:["sort-asc","sort-desc"],sortAscText:"Sort Ascending",sortDescText:"Sort Descending",hideSortIcons:false,columnsText:"Columns",selectedRowClass:"x-grid3-row-selected",borderWidth:2,tdClass:"x-grid3-cell",hdCls:"x-grid3-hd",markDirty:true,cellSelectorDepth:4,rowSelectorDepth:10,rowBodySelectorDepth:10,cellSelector:"td.x-grid3-cell",rowSelector:"div.x-grid3-row",rowBodySelector:"div.x-grid3-row-body",firstRowCls:"x-grid3-row-first",lastRowCls:"x-grid3-row-last",rowClsRe:/(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,headerMenuOpenCls:"x-grid3-hd-menu-open",rowOverCls:"x-grid3-row-over",constructor:function(a){Ext.apply(this,a);this.addEvents("beforerowremoved","beforerowsinserted","beforerefresh","rowremoved","rowsinserted","rowupdated","refresh");Ext.grid.GridView.superclass.constructor.call(this)},masterTpl:new Ext.Template('<div class="x-grid3" hidefocus="true">','<div class="x-grid3-viewport">','<div class="x-grid3-header">','<div class="x-grid3-header-inner">','<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',"</div>",'<div class="x-clear"></div>',"</div>",'<div class="x-grid3-scroller">','<div class="x-grid3-body" style="{bstyle}">{body}</div>','<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',"</div>","</div>",'<div class="x-grid3-resize-marker">&#160;</div>','<div class="x-grid3-resize-proxy">&#160;</div>',"</div>"),headerTpl:new Ext.Template('<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',"<thead>",'<tr class="x-grid3-hd-row">{cells}</tr>',"</thead>","</table>"),bodyTpl:new Ext.Template("{rows}"),cellTpl:new Ext.Template('<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>','<div class="x-grid3-cell-inner x-grid3-col-{id} x-unselectable" unselectable="on" {attr}>{value}</div>',"</td>"),initTemplates:function(){var c=this.templates||{},d,b,g=new Ext.Template('<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">','<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',this.grid.enableHdMenu?'<a class="x-grid3-hd-btn" href="#"></a>':"","{value}",'<img alt="" class="x-grid3-sort-icon" src="',Ext.BLANK_IMAGE_URL,'" />',"</div>","</td>"),a=['<tr class="x-grid3-row-body-tr" style="{bodyStyle}">','<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">','<div class="x-grid3-row-body">{body}</div>',"</td>","</tr>"].join(""),e=['<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',"<tbody>","<tr>{cells}</tr>",this.enableRowBody?a:"","</tbody>","</table>"].join("");Ext.applyIf(c,{hcell:g,cell:this.cellTpl,body:this.bodyTpl,header:this.headerTpl,master:this.masterTpl,row:new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">'+e+"</div>"),rowInner:new Ext.Template(e)});for(b in c){d=c[b];if(d&&Ext.isFunction(d.compile)&&!d.compiled){d.disableFormats=true;d.compile()}}this.templates=c;this.colRe=new RegExp("x-grid3-td-([^\\s]+)","")},fly:function(a){if(!this._flyweight){this._flyweight=new Ext.Element.Flyweight(document.body)}this._flyweight.dom=a;return this._flyweight},getEditorParent:function(){return this.scroller.dom},initElements:function(){var b=Ext.Element,d=Ext.get(this.grid.getGridEl().dom.firstChild),e=new b(d.child("div.x-grid3-viewport")),c=new b(e.child("div.x-grid3-header")),a=new b(e.child("div.x-grid3-scroller"));if(this.grid.hideHeaders){c.setDisplayed(false)}if(this.forceFit){a.setStyle("overflow-x","hidden")}Ext.apply(this,{el:d,mainWrap:e,scroller:a,mainHd:c,innerHd:c.child("div.x-grid3-header-inner").dom,mainBody:new b(b.fly(a).child("div.x-grid3-body")),focusEl:new b(b.fly(a).child("a")),resizeMarker:new b(d.child("div.x-grid3-resize-marker")),resizeProxy:new b(d.child("div.x-grid3-resize-proxy"))});this.focusEl.swallowEvent("click",true)},getRows:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},findCell:function(a){if(!a){return false}return this.fly(a).findParent(this.cellSelector,this.cellSelectorDepth)},findCellIndex:function(d,c){var b=this.findCell(d),a;if(b){a=this.fly(b).hasClass(c);if(!c||a){return this.getCellIndex(b)}}return false},getCellIndex:function(b){if(b){var a=b.className.match(this.colRe);if(a&&a[1]){return this.cm.getIndexById(a[1])}}return false},findHeaderCell:function(b){var a=this.findCell(b);return a&&this.fly(a).hasClass(this.hdCls)?a:null},findHeaderIndex:function(a){return this.findCellIndex(a,this.hdCls)},findRow:function(a){if(!a){return false}return this.fly(a).findParent(this.rowSelector,this.rowSelectorDepth)},findRowIndex:function(a){var b=this.findRow(a);return b?b.rowIndex:false},findRowBody:function(a){if(!a){return false}return this.fly(a).findParent(this.rowBodySelector,this.rowBodySelectorDepth)},getRow:function(a){return this.getRows()[a]},getCell:function(b,a){return Ext.fly(this.getRow(b)).query(this.cellSelector)[a]},getHeaderCell:function(a){return this.mainHd.dom.getElementsByTagName("td")[a]},addRowClass:function(b,a){var c=this.getRow(b);if(c){this.fly(c).addClass(a)}},removeRowClass:function(c,a){var b=this.getRow(c);if(b){this.fly(b).removeClass(a)}},removeRow:function(a){Ext.removeNode(this.getRow(a));this.syncFocusEl(a)},removeRows:function(c,a){var b=this.mainBody.dom,d;for(d=c;d<=a;d++){Ext.removeNode(b.childNodes[c])}this.syncFocusEl(c)},getScrollState:function(){var a=this.scroller.dom;return{left:a.scrollLeft,top:a.scrollTop}},restoreScroll:function(a){var b=this.scroller.dom;b.scrollLeft=a.left;b.scrollTop=a.top},scrollToTop:function(){var a=this.scroller.dom;a.scrollTop=0;a.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.scroller.dom;this.grid.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerHd,b=this.scroller.dom.scrollLeft;a.scrollLeft=b;a.scrollLeft=b},updateSortIcon:function(d,c){var a=this.sortClasses,b=a[c=="DESC"?1:0],e=this.mainHd.select("td").removeClass(a);e.item(d).addClass(b)},updateAllColumnWidths:function(){var e=this.getTotalWidth(),k=this.cm.getColumnCount(),m=this.getRows(),g=m.length,b=[],l,a,h,d,c;for(d=0;d<k;d++){b[d]=this.getColumnWidth(d);this.getHeaderCell(d).style.width=b[d]}this.updateHeaderWidth();for(d=0;d<g;d++){l=m[d];l.style.width=e;a=l.firstChild;if(a){a.style.width=e;h=a.rows[0];for(c=0;c<k;c++){h.childNodes[c].style.width=b[c]}}}this.onAllColumnWidthsUpdated(b,e)},updateColumnWidth:function(d,b){var c=this.getColumnWidth(d),j=this.getTotalWidth(),h=this.getHeaderCell(d),a=this.getRows(),e=a.length,l,g,k;this.updateHeaderWidth();h.style.width=c;for(g=0;g<e;g++){l=a[g];k=l.firstChild;l.style.width=j;if(k){k.style.width=j;k.rows[0].childNodes[d].style.width=c}}this.onColumnWidthUpdated(d,c,j)},updateColumnHidden:function(b,j){var h=this.getTotalWidth(),k=j?"none":"",g=this.getHeaderCell(b),a=this.getRows(),d=a.length,l,c,e;this.updateHeaderWidth();g.style.display=k;for(e=0;e<d;e++){l=a[e];l.style.width=h;c=l.firstChild;if(c){c.style.width=h;c.rows[0].childNodes[b].style.display=k}}this.onColumnHiddenUpdated(b,j,h);delete this.lastViewWidth;this.layout()},doRender:function(d,v,m,a,r,t){var h=this.templates,c=h.cell,y=h.row,o=r-1,b="width:"+this.getTotalWidth()+";",k=[],l=[],n={tstyle:b},q={},w=v.length,x,g,e,u,s,p;for(s=0;s<w;s++){e=v[s];l=[];p=s+a;for(u=0;u<r;u++){g=d[u];q.id=g.id;q.css=u===0?"x-grid3-cell-first ":(u==o?"x-grid3-cell-last ":"");q.attr=q.cellAttr="";q.style=g.style;q.value=g.renderer.call(g.scope,e.data[g.name],q,e,p,u,m);if(Ext.isEmpty(q.value)){q.value="&#160;"}if(this.markDirty&&e.dirty&&typeof e.modified[g.name]!="undefined"){q.css+=" x-grid3-dirty-cell"}l[l.length]=c.apply(q)}x=[];if(t&&((p+1)%2===0)){x[0]="x-grid3-row-alt"}if(e.dirty){x[1]=" x-grid3-dirty-row"}n.cols=r;if(this.getRowClass){x[2]=this.getRowClass(e,p,n,m)}n.alt=x.join(" ");n.cells=l.join("");k[k.length]=y.apply(n)}return k.join("")},processRows:function(a,g){if(!this.ds||this.ds.getCount()<1){return}var d=this.getRows(),c=d.length,e,b;g=g||!this.grid.stripeRows;a=a||0;for(b=0;b<c;b++){e=d[b];if(e){e.rowIndex=b;if(!g){e.className=e.className.replace(this.rowClsRe," ");if((b+1)%2===0){e.className+=" x-grid3-row-alt"}}}}if(a===0){Ext.fly(d[0]).addClass(this.firstRowCls)}Ext.fly(d[c-1]).addClass(this.lastRowCls)},afterRender:function(){if(!this.ds||!this.cm){return}this.mainBody.dom.innerHTML=this.renderBody()||"&#160;";this.processRows(0,true);if(this.deferEmptyText!==true){this.applyEmptyText()}this.grid.fireEvent("viewready",this.grid)},afterRenderUI:function(){var a=this.grid;this.initElements();Ext.fly(this.innerHd).on("click",this.handleHdDown,this);this.mainHd.on({scope:this,mouseover:this.handleHdOver,mouseout:this.handleHdOut,mousemove:this.handleHdMove});this.scroller.on("scroll",this.syncScroll,this);if(a.enableColumnResize!==false){this.splitZone=new Ext.grid.GridView.SplitDragZone(a,this.mainHd.dom)}if(a.enableColumnMove){this.columnDrag=new Ext.grid.GridView.ColumnDragZone(a,this.innerHd);this.columnDrop=new Ext.grid.HeaderDropZone(a,this.mainHd.dom)}if(a.enableHdMenu!==false){this.hmenu=new Ext.menu.Menu({id:a.id+"-hctx"});this.hmenu.add({itemId:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},{itemId:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"});if(a.enableColumnHide!==false){this.colMenu=new Ext.menu.Menu({id:a.id+"-hcols-menu"});this.colMenu.on({scope:this,beforeshow:this.beforeColMenuShow,itemclick:this.handleHdMenuClick});this.hmenu.add({itemId:"sortSep",xtype:"menuseparator"},{itemId:"columns",hideOnClick:false,text:this.columnsText,menu:this.colMenu,iconCls:"x-cols-icon"})}this.hmenu.on("itemclick",this.handleHdMenuClick,this)}if(a.trackMouseOver){this.mainBody.on({scope:this,mouseover:this.onRowOver,mouseout:this.onRowOut})}if(a.enableDragDrop||a.enableDrag){this.dragZone=new Ext.grid.GridDragZone(a,{ddGroup:a.ddGroup||"GridDD"})}this.updateHeaderSortState()},renderUI:function(){var a=this.templates;return a.master.apply({body:a.body.apply({rows:"&#160;"}),header:this.renderHeaders(),ostyle:"width:"+this.getOffsetWidth()+";",bstyle:"width:"+this.getTotalWidth()+";"})},processEvent:function(b,h){var i=h.getTarget(),a=this.grid,d=this.findHeaderIndex(i),k,j,c,g;a.fireEvent(b,h);if(d!==false){a.fireEvent("header"+b,a,d,h)}else{k=this.findRowIndex(i);if(k!==false){j=this.findCellIndex(i);if(j!==false){c=a.colModel.getColumnAt(j);if(a.fireEvent("cell"+b,a,k,j,h)!==false){if(!c||(c.processEvent&&(c.processEvent(b,h,a,k,j)!==false))){a.fireEvent("row"+b,a,k,h)}}}else{if(a.fireEvent("row"+b,a,k,h)!==false){(g=this.findRowBody(i))&&a.fireEvent("rowbody"+b,a,k,h)}}}else{a.fireEvent("container"+b,a,h)}}},layout:function(j){if(!this.mainBody){return}var a=this.grid,d=a.getGridEl(),c=d.getSize(true),i=c.width,b=c.height,h=this.scroller,g,e,k;if(i<20||b<20){return}if(a.autoHeight){g=h.dom.style;g.overflow="visible";if(Ext.isWebKit){g.position="static"}}else{this.el.setSize(i,b);e=this.mainHd.getHeight();k=b-e;h.setSize(i,k);if(this.innerHd){this.innerHd.style.width=(i)+"px"}}if(this.forceFit||(j===true&&this.autoFill)){if(this.lastViewWidth!=i){this.fitColumns(false,false);this.lastViewWidth=i}}else{this.autoExpand();this.syncHeaderScroll()}this.onLayout(i,k)},onLayout:function(a,b){},onColumnWidthUpdated:function(c,a,b){},onAllColumnWidthsUpdated:function(a,b){},onColumnHiddenUpdated:function(b,c,a){},updateColumnText:function(a,b){},afterMove:function(a){},init:function(a){this.grid=a;this.initTemplates();this.initData(a.store,a.colModel);this.initUI(a)},getColumnId:function(a){return this.cm.getColumnId(a)},getOffsetWidth:function(){return(this.cm.getTotalWidth()+this.getScrollOffset())+"px"},getScrollOffset:function(){return Ext.num(this.scrollOffset,Ext.getScrollBarWidth())},renderHeaders:function(){var e=this.cm,g=this.templates,a=g.hcell,d={},h=e.getColumnCount(),j=h-1,k=[],c,b;for(c=0;c<h;c++){if(c==0){b="x-grid3-cell-first "}else{b=c==j?"x-grid3-cell-last ":""}d={id:e.getColumnId(c),value:e.getColumnHeader(c)||"",style:this.getColumnStyle(c,true),css:b,tooltip:this.getColumnTooltip(c)};if(e.config[c].align=="right"){d.istyle="padding-right: 16px;"}else{delete d.istyle}k[c]=a.apply(d)}return g.header.apply({cells:k.join(""),tstyle:String.format("width: {0};",this.getTotalWidth())})},getColumnTooltip:function(a){var b=this.cm.getColumnTooltip(a);if(b){if(Ext.QuickTips.isEnabled()){return'ext:qtip="'+b+'"'}else{return'title="'+b+'"'}}return""},beforeUpdate:function(){this.grid.stopEditing(true)},updateHeaders:function(){this.innerHd.firstChild.innerHTML=this.renderHeaders();this.updateHeaderWidth(false)},updateHeaderWidth:function(c){var b=this.innerHd.firstChild,a=this.getTotalWidth();b.style.width=this.getOffsetWidth();b.firstChild.style.width=a;if(c!==false){this.mainBody.dom.style.width=a}},focusRow:function(a){this.focusCell(a,0,false)},focusCell:function(d,b,c){this.syncFocusEl(this.ensureVisible(d,b,c));var a=this.focusEl;if(Ext.isGecko){a.focus()}else{a.focus.defer(1,a)}},resolveCell:function(h,d,g){if(!Ext.isNumber(h)){h=h.rowIndex}if(!this.ds){return null}if(h<0||h>=this.ds.getCount()){return null}d=(d!==undefined?d:0);var c=this.getRow(h),b=this.cm,e=b.getColumnCount(),a;if(!(g===false&&d===0)){while(d<e&&b.isHidden(d)){d++}a=this.getCell(h,d)}return{row:c,cell:a}},getResolvedXY:function(b){if(!b){return null}var a=b.cell,c=b.row;if(a){return Ext.fly(a).getXY()}else{return[this.el.getX(),Ext.fly(c).getY()]}},syncFocusEl:function(d,a,c){var b=d;if(!Ext.isArray(b)){d=Math.min(d,Math.max(0,this.getRows().length-1));if(isNaN(d)){return}b=this.getResolvedXY(this.resolveCell(d,a,c))}this.focusEl.setXY(b||this.scroller.getXY())},ensureVisible:function(t,g,e){var r=this.resolveCell(t,g,e);if(!r||!r.row){return null}var k=r.row,h=r.cell,n=this.scroller.dom,d=k,s=0,o=this.el.dom;while(d&&d!=o){s+=d.offsetTop;d=d.offsetParent}s-=this.mainHd.dom.offsetHeight;o=parseInt(n.scrollTop,10);var q=s+k.offsetHeight,a=n.clientHeight,m=o+a;if(s<o){n.scrollTop=s}else{if(q>m){n.scrollTop=q-a}}if(e!==false){var l=parseInt(h.offsetLeft,10),j=l+h.offsetWidth,i=parseInt(n.scrollLeft,10),b=i+n.clientWidth;if(l<i){n.scrollLeft=l}else{if(j>b){n.scrollLeft=j-n.clientWidth}}}return this.getResolvedXY(r)},insertRows:function(a,i,e,h){var d=a.getCount()-1;if(!h&&i===0&&e>=d){this.fireEvent("beforerowsinserted",this,i,e);this.refresh();this.fireEvent("rowsinserted",this,i,e)}else{if(!h){this.fireEvent("beforerowsinserted",this,i,e)}var b=this.renderRows(i,e),g=this.getRow(i);if(g){if(i===0){Ext.fly(this.getRow(0)).removeClass(this.firstRowCls)}Ext.DomHelper.insertHtml("beforeBegin",g,b)}else{var c=this.getRow(d-1);if(c){Ext.fly(c).removeClass(this.lastRowCls)}Ext.DomHelper.insertHtml("beforeEnd",this.mainBody.dom,b)}if(!h){this.processRows(i);this.fireEvent("rowsinserted",this,i,e)}else{if(i===0||i>=d){Ext.fly(this.getRow(i)).addClass(i===0?this.firstRowCls:this.lastRowCls)}}}this.syncFocusEl(i)},deleteRows:function(a,c,b){if(a.getRowCount()<1){this.refresh()}else{this.fireEvent("beforerowsdeleted",this,c,b);this.removeRows(c,b);this.processRows(c);this.fireEvent("rowsdeleted",this,c,b)}},getColumnStyle:function(b,d){var a=this.cm,g=a.config,c=d?"":g[b].css||"",e=g[b].align;c+=String.format("width: {0};",this.getColumnWidth(b));if(a.isHidden(b)){c+="display: none; "}if(e){c+=String.format("text-align: {0};",e)}return c},getColumnWidth:function(b){var c=this.cm.getColumnWidth(b),a=this.borderWidth;if(Ext.isNumber(c)){if(Ext.isBorderBox){return c+"px"}else{return Math.max(c-a,0)+"px"}}else{return c}},getTotalWidth:function(){return this.cm.getTotalWidth()+"px"},fitColumns:function(g,j,h){var a=this.grid,l=this.cm,s=l.getTotalWidth(false),q=this.getGridInnerWidth(),r=q-s,c=[],o=0,n=0,u,d,p;if(q<20||r===0){return false}var e=l.getColumnCount(true),m=l.getColumnCount(false),b=e-(Ext.isNumber(h)?1:0);if(b===0){b=1;h=undefined}for(p=0;p<m;p++){if(!l.isFixed(p)&&p!==h){u=l.getColumnWidth(p);c.push(p,u);if(!l.isHidden(p)){o=p;n+=u}}}d=(q-l.getTotalWidth())/n;while(c.length){u=c.pop();p=c.pop();l.setColumnWidth(p,Math.max(a.minColumnWidth,Math.floor(u+u*d)),true)}s=l.getTotalWidth(false);if(s>q){var t=(b==e)?o:h,k=Math.max(1,l.getColumnWidth(t)-(s-q));l.setColumnWidth(t,k,true)}if(g!==true){this.updateAllColumnWidths()}return true},autoExpand:function(k){var a=this.grid,i=this.cm,e=this.getGridInnerWidth(),c=i.getTotalWidth(false),g=a.autoExpandColumn;if(!this.userResized&&g){if(e!=c){var j=i.getIndexById(g),b=i.getColumnWidth(j),h=e-c+b,d=Math.min(Math.max(h,a.autoExpandMin),a.autoExpandMax);if(b!=d){i.setColumnWidth(j,d,true);if(k!==true){this.updateColumnWidth(j,d)}}}}},getGridInnerWidth:function(){return this.grid.getGridEl().getWidth(true)-this.getScrollOffset()},getColumnData:function(){var e=[],c=this.cm,g=c.getColumnCount(),a=this.ds.fields,d,b;for(d=0;d<g;d++){b=c.getDataIndex(d);e[d]={name:Ext.isDefined(b)?b:(a.get(d)?a.get(d).name:undefined),renderer:c.getRenderer(d),scope:c.getRendererScope(d),id:c.getColumnId(d),style:this.getColumnStyle(d)}}return e},renderRows:function(i,c){var a=this.grid,g=a.store,j=a.stripeRows,e=a.colModel,h=e.getColumnCount(),d=g.getCount(),b;if(d<1){return""}i=i||0;c=Ext.isDefined(c)?c:d-1;b=g.getRange(i,c);return this.doRender(this.getColumnData(),b,g,i,h,j)},renderBody:function(){var a=this.renderRows()||"&#160;";return this.templates.body.apply({rows:a})},refreshRow:function(g){var l=this.ds,m=this.cm.getColumnCount(),c=this.getColumnData(),n=m-1,p=["x-grid3-row"],e={tstyle:String.format("width: {0};",this.getTotalWidth())},a=[],k=this.templates.cell,j,q,b,o,h,d;if(Ext.isNumber(g)){j=g;g=l.getAt(j)}else{j=l.indexOf(g)}if(!g||j<0){return}for(d=0;d<m;d++){b=c[d];if(d==0){h="x-grid3-cell-first"}else{h=(d==n)?"x-grid3-cell-last ":""}o={id:b.id,style:b.style,css:h,attr:"",cellAttr:""};o.value=b.renderer.call(b.scope,g.data[b.name],o,g,j,d,l);if(Ext.isEmpty(o.value)){o.value="&#160;"}if(this.markDirty&&g.dirty&&typeof g.modified[b.name]!="undefined"){o.css+=" x-grid3-dirty-cell"}a[d]=k.apply(o)}q=this.getRow(j);q.className="";if(this.grid.stripeRows&&((j+1)%2===0)){p.push("x-grid3-row-alt")}if(this.getRowClass){e.cols=m;p.push(this.getRowClass(g,j,e,l))}this.fly(q).addClass(p).setStyle(e.tstyle);e.cells=a.join("");q.innerHTML=this.templates.rowInner.apply(e);this.fireEvent("rowupdated",this,j,g)},refresh:function(b){this.fireEvent("beforerefresh",this);this.grid.stopEditing(true);var a=this.renderBody();this.mainBody.update(a).setWidth(this.getTotalWidth());if(b===true){this.updateHeaders();this.updateHeaderSortState()}this.processRows(0,true);this.layout();this.applyEmptyText();this.fireEvent("refresh",this)},applyEmptyText:function(){if(this.emptyText&&!this.hasRows()){this.mainBody.update('<div class="x-grid-empty">'+this.emptyText+"</div>")}},updateHeaderSortState:function(){var b=this.ds.getSortState();if(!b){return}if(!this.sortState||(this.sortState.field!=b.field||this.sortState.direction!=b.direction)){this.grid.fireEvent("sortchange",this.grid,b)}this.sortState=b;var c=this.cm.findColumnIndex(b.field);if(c!=-1){var a=b.direction;this.updateSortIcon(c,a)}},clearHeaderSortState:function(){if(!this.sortState){return}this.grid.fireEvent("sortchange",this.grid,null);this.mainHd.select("td").removeClass(this.sortClasses);delete this.sortState},destroy:function(){var j=this,a=j.grid,d=a.getGridEl(),i=j.dragZone,g=j.splitZone,h=j.columnDrag,e=j.columnDrop,k=j.scrollToTopTask,c,b;if(k&&k.cancel){k.cancel()}Ext.destroyMembers(j,"colMenu","hmenu");j.initData(null,null);j.purgeListeners();Ext.fly(j.innerHd).un("click",j.handleHdDown,j);if(a.enableColumnMove){c=h.dragData;b=h.proxy;Ext.destroy(h.el,b.ghost,b.el,e.el,e.proxyTop,e.proxyBottom,c.ddel,c.header);if(b.anim){Ext.destroy(b.anim)}delete b.ghost;delete c.ddel;delete c.header;h.destroy();delete Ext.dd.DDM.locationCache[h.id];delete h._domRef;delete e.proxyTop;delete e.proxyBottom;e.destroy();delete Ext.dd.DDM.locationCache["gridHeader"+d.id];delete e._domRef;delete Ext.dd.DDM.ids[e.ddGroup]}if(g){g.destroy();delete g._domRef;delete Ext.dd.DDM.ids["gridSplitters"+d.id]}Ext.fly(j.innerHd).removeAllListeners();Ext.removeNode(j.innerHd);delete j.innerHd;Ext.destroy(j.el,j.mainWrap,j.mainHd,j.scroller,j.mainBody,j.focusEl,j.resizeMarker,j.resizeProxy,j.activeHdBtn,j._flyweight,i,g);delete a.container;if(i){i.destroy()}Ext.dd.DDM.currentTarget=null;delete Ext.dd.DDM.locationCache[d.id];Ext.EventManager.removeResizeListener(j.onWindowResize,j)},onDenyColumnHide:function(){},render:function(){if(this.autoFill){var a=this.grid.ownerCt;if(a&&a.getLayout()){a.on("afterlayout",function(){this.fitColumns(true,true);this.updateHeaders();this.updateHeaderSortState()},this,{single:true})}}else{if(this.forceFit){this.fitColumns(true,false)}else{if(this.grid.autoExpandColumn){this.autoExpand(true)}}}this.grid.getGridEl().dom.innerHTML=this.renderUI();this.afterRenderUI()},initData:function(a,e){var b=this;if(b.ds){var d=b.ds;d.un("add",b.onAdd,b);d.un("load",b.onLoad,b);d.un("clear",b.onClear,b);d.un("remove",b.onRemove,b);d.un("update",b.onUpdate,b);d.un("datachanged",b.onDataChange,b);if(d!==a&&d.autoDestroy){d.destroy()}}if(a){a.on({scope:b,load:b.onLoad,add:b.onAdd,remove:b.onRemove,update:b.onUpdate,clear:b.onClear,datachanged:b.onDataChange})}if(b.cm){var c=b.cm;c.un("configchange",b.onColConfigChange,b);c.un("widthchange",b.onColWidthChange,b);c.un("headerchange",b.onHeaderChange,b);c.un("hiddenchange",b.onHiddenChange,b);c.un("columnmoved",b.onColumnMove,b)}if(e){delete b.lastViewWidth;e.on({scope:b,configchange:b.onColConfigChange,widthchange:b.onColWidthChange,headerchange:b.onHeaderChange,hiddenchange:b.onHiddenChange,columnmoved:b.onColumnMove})}b.ds=a;b.cm=e},onDataChange:function(){this.refresh(true);this.updateHeaderSortState();this.syncFocusEl(0)},onClear:function(){this.refresh();this.syncFocusEl(0)},onUpdate:function(b,a){this.refreshRow(a)},onAdd:function(b,a,c){this.insertRows(b,c,c+(a.length-1))},onRemove:function(b,a,c,d){if(d!==true){this.fireEvent("beforerowremoved",this,c,a)}this.removeRow(c);if(d!==true){this.processRows(c);this.applyEmptyText();this.fireEvent("rowremoved",this,c,a)}},onLoad:function(){if(Ext.isGecko){if(!this.scrollToTopTask){this.scrollToTopTask=new Ext.util.DelayedTask(this.scrollToTop,this)}this.scrollToTopTask.delay(1)}else{this.scrollToTop()}},onColWidthChange:function(a,b,c){this.updateColumnWidth(b,c)},onHeaderChange:function(a,b,c){this.updateHeaders()},onHiddenChange:function(a,b,c){this.updateColumnHidden(b,c)},onColumnMove:function(a,c,b){this.indexMap=null;this.refresh(true);this.restoreScroll(this.getScrollState());this.afterMove(b);this.grid.fireEvent("columnmove",c,b)},onColConfigChange:function(){delete this.lastViewWidth;this.indexMap=null;this.refresh(true)},initUI:function(a){a.on("headerclick",this.onHeaderClick,this)},initEvents:Ext.emptyFn,onHeaderClick:function(b,a){if(this.headersDisabled||!this.cm.isSortable(a)){return}b.stopEditing(true);b.store.sort(this.cm.getDataIndex(a))},onRowOver:function(b,a){var c=this.findRowIndex(a);if(c!==false){this.addRowClass(c,this.rowOverCls)}},onRowOut:function(b,a){var c=this.findRowIndex(a);if(c!==false&&!b.within(this.getRow(c),true)){this.removeRowClass(c,this.rowOverCls)}},onRowSelect:function(a){this.addRowClass(a,this.selectedRowClass)},onRowDeselect:function(a){this.removeRowClass(a,this.selectedRowClass)},onCellSelect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).addClass("x-grid3-cell-selected")}},onCellDeselect:function(c,b){var a=this.getCell(c,b);if(a){this.fly(a).removeClass("x-grid3-cell-selected")}},handleWheel:function(a){a.stopPropagation()},onColumnSplitterMoved:function(a,b){this.userResized=true;this.grid.colModel.setColumnWidth(a,b,true);if(this.forceFit){this.fitColumns(true,false,a);this.updateAllColumnWidths()}else{this.updateColumnWidth(a,b);this.syncHeaderScroll()}this.grid.fireEvent("columnresize",a,b)},beforeColMenuShow:function(){var b=this.cm,d=b.getColumnCount(),a=this.colMenu,c;a.removeAll();for(c=0;c<d;c++){if(b.config[c].hideable!==false){a.add(new Ext.menu.CheckItem({text:b.getColumnHeader(c),itemId:"col-"+b.getColumnId(c),checked:!b.isHidden(c),disabled:b.config[c].hideable===false,hideOnClick:false}))}}},handleHdMenuClick:function(c){var a=this.ds,b=this.cm.getDataIndex(this.hdCtxIndex);switch(c.getItemId()){case"asc":a.sort(b,"ASC");break;case"desc":a.sort(b,"DESC");break;default:this.handleHdMenuClickDefault(c)}return true},handleHdMenuClickDefault:function(c){var b=this.cm,d=c.getItemId(),a=b.getIndexById(d.substr(4));if(a!=-1){if(c.checked&&b.getColumnsBy(this.isHideableColumn,this).length<=1){this.onDenyColumnHide();return}b.setHidden(a,c.checked)}},handleHdDown:function(i,j){if(Ext.fly(j).hasClass("x-grid3-hd-btn")){i.stopEvent();var k=this.cm,g=this.findHeaderCell(j),h=this.getCellIndex(g),d=k.isSortable(h),c=this.hmenu,b=c.items,a=this.headerMenuOpenCls,l;this.hdCtxIndex=h;Ext.fly(g).addClass(a);if(this.hideSortIcons){b.get("asc").setVisible(d);b.get("desc").setVisible(d);l=b.get("sortSep");if(l){l.setVisible(d)}}else{b.get("asc").setDisabled(!d);b.get("desc").setDisabled(!d)}c.on("hide",function(){Ext.fly(g).removeClass(a)},this,{single:true});c.show(j,"tl-bl?")}},handleHdMove:function(k){var i=this.findHeaderCell(this.activeHdRef);if(i&&!this.headersDisabled){var l=this.splitHandleWidth||5,j=this.activeHdRegion,p=i.style,m=this.cm,o="",g=k.getPageX();if(this.grid.enableColumnResize!==false){var a=this.activeHdIndex,b=this.getPreviousVisible(a),n=m.isResizable(a),c=b&&m.isResizable(b),d=g-j.left<=l,h=j.right-g<=(!this.activeHdBtn?l:2);if(d&&c){o=Ext.isAir?"move":Ext.isWebKit?"e-resize":"col-resize"}else{if(h&&n){o=Ext.isAir?"move":Ext.isWebKit?"w-resize":"col-resize"}}}p.cursor=o}},getPreviousVisible:function(a){while(a>0){if(!this.cm.isHidden(a-1)){return a}a--}return undefined},handleHdOver:function(c,b){var d=this.findHeaderCell(b);if(d&&!this.headersDisabled){var a=this.fly(d);this.activeHdRef=b;this.activeHdIndex=this.getCellIndex(d);this.activeHdRegion=a.getRegion();if(!this.isMenuDisabled(this.activeHdIndex,a)){a.addClass("x-grid3-hd-over");this.activeHdBtn=a.child(".x-grid3-hd-btn");if(this.activeHdBtn){this.activeHdBtn.dom.style.height=(d.firstChild.offsetHeight-1)+"px"}}}},handleHdOut:function(b,a){var c=this.findHeaderCell(a);if(c&&(!Ext.isIE9m||!b.within(c,true))){this.activeHdRef=null;this.fly(c).removeClass("x-grid3-hd-over");c.style.cursor=""}},isMenuDisabled:function(a,b){return this.cm.isMenuDisabled(a)},hasRows:function(){var a=this.mainBody.dom.firstChild;return a&&a.nodeType==1&&a.className!="x-grid-empty"},isHideableColumn:function(a){return !a.hidden},bind:function(a,b){this.initData(a,b)}});Ext.grid.GridView.SplitDragZone=Ext.extend(Ext.dd.DDProxy,{constructor:function(a,b){this.grid=a;this.view=a.getView();this.marker=this.view.resizeMarker;this.proxy=this.view.resizeProxy;Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this,b,"gridSplitters"+this.grid.getGridEl().id,{dragElId:Ext.id(this.proxy.dom),resizeFrame:false});this.scroll=false;this.hw=this.view.splitHandleWidth||5},b4StartDrag:function(a,e){this.dragHeadersDisabled=this.view.headersDisabled;this.view.headersDisabled=true;var d=this.view.mainWrap.getHeight();this.marker.setHeight(d);this.marker.show();this.marker.alignTo(this.view.getHeaderCell(this.cellIndex),"tl-tl",[-2,0]);this.proxy.setHeight(d);var b=this.cm.getColumnWidth(this.cellIndex),c=Math.max(b-this.grid.minColumnWidth,0);this.resetConstraints();this.setXConstraint(c,1000);this.setYConstraint(0,0);this.minX=a-c;this.maxX=a+1000;this.startPos=a;Ext.dd.DDProxy.prototype.b4StartDrag.call(this,a,e)},allowHeaderDrag:function(a){return true},handleMouseDown:function(a){var h=this.view.findHeaderCell(a.getTarget());if(h&&this.allowHeaderDrag(a)){var k=this.view.fly(h).getXY(),c=k[0],i=a.getXY(),b=i[0],g=h.offsetWidth,d=false;if((b-c)<=this.hw){d=-1}else{if((c+g)-b<=this.hw){d=0}}if(d!==false){this.cm=this.grid.colModel;var j=this.view.getCellIndex(h);if(d==-1){if(j+d<0){return}while(this.cm.isHidden(j+d)){--d;if(j+d<0){return}}}this.cellIndex=j+d;this.split=h.dom;if(this.cm.isResizable(this.cellIndex)&&!this.cm.isFixed(this.cellIndex)){Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this,arguments)}}else{if(this.view.columnDrag){this.view.columnDrag.callHandleMouseDown(a)}}}},endDrag:function(g){this.marker.hide();var a=this.view,c=Math.max(this.minX,g.getPageX()),d=c-this.startPos,b=this.dragHeadersDisabled;a.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+d);setTimeout(function(){a.headersDisabled=b},50)},autoOffset:function(){this.setDelta(0,0)}});Ext.grid.PivotGridView=Ext.extend(Ext.grid.GridView,{colHeaderCellCls:"grid-hd-group-cell",title:"",getColumnHeaders:function(){return this.grid.topAxis.buildHeaders()},getRowHeaders:function(){return this.grid.leftAxis.buildHeaders()},renderRows:function(a,t){var b=this.grid,o=b.extractData(),p=o.length,g=this.templates,s=b.renderer,h=typeof s=="function",w=this.getCellCls,n=typeof w=="function",d=g.cell,x=g.row,k=[],q={},c="width:"+this.getGridInnerWidth()+"px;",l,r,e,v,m;a=a||0;t=Ext.isDefined(t)?t:p-1;for(v=0;v<p;v++){m=o[v];r=m.length;l=[];for(var u=0;u<r;u++){q.id=v+"-"+u;q.css=u===0?"x-grid3-cell-first ":(u==(r-1)?"x-grid3-cell-last ":"");q.attr=q.cellAttr="";q.value=m[u];if(Ext.isEmpty(q.value)){q.value="&#160;"}if(h){q.value=s(q.value)}if(n){q.css+=w(q.value)+" "}l[l.length]=d.apply(q)}k[k.length]=x.apply({tstyle:c,cols:r,cells:l.join(""),alt:""})}return k.join("")},masterTpl:new Ext.Template('<div class="x-grid3 x-pivotgrid" hidefocus="true">','<div class="x-grid3-viewport">','<div class="x-grid3-header">','<div class="x-grid3-header-title"><span>{title}</span></div>','<div class="x-grid3-header-inner">','<div class="x-grid3-header-offset" style="{ostyle}"></div>',"</div>",'<div class="x-clear"></div>',"</div>",'<div class="x-grid3-scroller">','<div class="x-grid3-row-headers"></div>','<div class="x-grid3-body" style="{bstyle}">{body}</div>','<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',"</div>","</div>",'<div class="x-grid3-resize-marker">&#160;</div>','<div class="x-grid3-resize-proxy">&#160;</div>',"</div>"),initTemplates:function(){Ext.grid.PivotGridView.superclass.initTemplates.apply(this,arguments);var a=this.templates||{};if(!a.gcell){a.gcell=new Ext.XTemplate('<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} '+this.colHeaderCellCls+'" style="{style}">','<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id} x-unselectable" unselectable="on" style="{istyle}">',this.grid.enableHdMenu?'<a class="x-grid3-hd-btn" href="#"></a>':"","{value}","</div>","</td>")}this.templates=a;this.hrowRe=new RegExp("ux-grid-hd-group-row-(\\d+)","")},initElements:function(){Ext.grid.PivotGridView.superclass.initElements.apply(this,arguments);this.rowHeadersEl=new Ext.Element(this.scroller.child("div.x-grid3-row-headers"));this.headerTitleEl=new Ext.Element(this.mainHd.child("div.x-grid3-header-title"))},getGridInnerWidth:function(){var a=Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this,arguments);return a-this.getTotalRowHeaderWidth()},getTotalRowHeaderWidth:function(){var d=this.getRowHeaders(),c=d.length,b=0,a;for(a=0;a<c;a++){b+=d[a].width}return b},getTotalColumnHeaderHeight:function(){return this.getColumnHeaders().length*21},getCellIndex:function(b){if(b){var a=b.className.match(this.colRe),c;if(a&&(c=a[1])){return parseInt(c.split("-")[1],10)}}return false},renderUI:function(){var b=this.templates,a=this.getGridInnerWidth();return b.master.apply({body:b.body.apply({rows:"&#160;"}),ostyle:"width:"+a+"px",bstyle:"width:"+a+"px"})},onLayout:function(b,a){Ext.grid.PivotGridView.superclass.onLayout.apply(this,arguments);var b=this.getGridInnerWidth();this.resizeColumnHeaders(b);this.resizeAllRows(b)},refresh:function(b){this.fireEvent("beforerefresh",this);this.grid.stopEditing(true);var a=this.renderBody();this.mainBody.update(a).setWidth(this.getGridInnerWidth());if(b===true){this.updateHeaders();this.updateHeaderSortState()}this.processRows(0,true);this.layout();this.applyEmptyText();this.fireEvent("refresh",this)},renderHeaders:Ext.emptyFn,fitColumns:Ext.emptyFn,resizeColumnHeaders:function(b){var a=this.grid.topAxis;if(a.rendered){a.el.setWidth(b)}},resizeRowHeaders:function(){var a=this.getTotalRowHeaderWidth(),b=String.format("margin-left: {0}px;",a);this.rowHeadersEl.setWidth(a);this.mainBody.applyStyles(b);Ext.fly(this.innerHd).applyStyles(b);this.headerTitleEl.setWidth(a);this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight())},resizeAllRows:function(b){var d=this.getRows(),c=d.length,a;for(a=0;a<c;a++){Ext.fly(d[a]).setWidth(b);Ext.fly(d[a]).child("table").setWidth(b)}},updateHeaders:function(){this.renderGroupRowHeaders();this.renderGroupColumnHeaders()},renderGroupRowHeaders:function(){var a=this.grid.leftAxis;this.resizeRowHeaders();a.rendered=false;a.render(this.rowHeadersEl);this.setTitle(this.title)},setTitle:function(a){this.headerTitleEl.child("span").dom.innerHTML=a},renderGroupColumnHeaders:function(){var a=this.grid.topAxis;a.rendered=false;a.render(this.innerHd.firstChild)},isMenuDisabled:function(a,b){return true}});Ext.grid.PivotAxis=Ext.extend(Ext.Component,{orientation:"horizontal",defaultHeaderWidth:80,paddingWidth:7,setDimensions:function(a){this.dimensions=a},onRender:function(b,a){var c=this.orientation=="horizontal"?this.renderHorizontalRows():this.renderVerticalRows();this.el=Ext.DomHelper.overwrite(b.dom,{tag:"table",cn:c},true)},renderHorizontalRows:function(){var k=this.buildHeaders(),a=k.length,g=[],c,h,e,d,b;for(d=0;d<a;d++){c=[];h=k[d].items;e=h.length;for(b=0;b<e;b++){c.push({tag:"td",html:h[b].header,colspan:h[b].span})}g[d]={tag:"tr",cn:c}}return g},renderVerticalRows:function(){var b=this.buildHeaders(),k=b.length,a=[],m=[],h,c,l,g,e,d;for(e=0;e<k;e++){c=b[e];g=c.width||80;h=c.items.length;for(d=0;d<h;d++){l=c.items[d];a[l.start]=a[l.start]||[];a[l.start].push({tag:"td",html:l.header,rowspan:l.span,width:Ext.isBorderBox?g:g-this.paddingWidth})}}h=a.length;for(e=0;e<h;e++){m[e]={tag:"tr",cn:a[e]}}return m},getTuples:function(){var b=new Ext.data.Store({});b.data=this.store.data.clone();b.fields=this.store.fields;var l=[],a=this.dimensions,c=a.length,j;for(j=0;j<c;j++){l.push({field:a[j].dataIndex,direction:a[j].direction||"ASC"})}b.sort(l);var e=b.data.items,n=[],k=[],o,h,d,g,m;c=e.length;for(j=0;j<c;j++){d=this.getRecordInfo(e[j]);g=d.data;h="";for(m in g){h+=g[m]+"---"}if(n.indexOf(h)==-1){n.push(h);k.push(d)}}b.destroy();return k},getRecordInfo:function(a){var e=this.dimensions,d=e.length,h={},j,c,b;for(b=0;b<d;b++){j=e[b];c=j.dataIndex;h[c]=a.get(c)}var g=function(i){return function(k){for(var l in i){if(k.get(l)!=i[l]){return false}}return true}};return{data:h,matcher:g(h)}},buildHeaders:function(){var l=this.getTuples(),m=l.length,a=this.dimensions,e,r=a.length,c=[],o,s,n,q,p,b,k,h,g,d;for(g=0;g<r;g++){e=a[g];s=[];p=0;b=0;for(d=0;d<m;d++){o=l[d];k=d==(m-1);n=o.data[e.dataIndex];h=q!=undefined&&q!=n;if(g>0&&d>0){h=h||o.data[a[g-1].dataIndex]!=l[d-1].data[a[g-1].dataIndex]}if(h){s.push({header:q,span:p,start:b});b+=p;p=0}if(k){s.push({header:n,span:p+1,start:b});b+=p;p=0}q=n;p++}c.push({items:s,width:e.width||this.defaultHeaderWidth});q=undefined}return c}});Ext.grid.HeaderDragZone=Ext.extend(Ext.dd.DragZone,{maxDragWidth:120,constructor:function(a,c,b){this.grid=a;this.view=a.getView();this.ddGroup="gridHeader"+this.grid.getGridEl().id;Ext.grid.HeaderDragZone.superclass.constructor.call(this,c);if(b){this.setHandleElId(Ext.id(c));this.setOuterHandleElId(Ext.id(b))}this.scroll=false},getDragData:function(c){var a=Ext.lib.Event.getTarget(c),b=this.view.findHeaderCell(a);if(b){return{ddel:b.firstChild,header:b}}return false},onInitDrag:function(a){this.dragHeadersDisabled=this.view.headersDisabled;this.view.headersDisabled=true;var b=this.dragData.ddel.cloneNode(true);b.id=Ext.id();b.style.width=Math.min(this.dragData.header.offsetWidth,this.maxDragWidth)+"px";this.proxy.update(b);return true},afterValidDrop:function(){this.completeDrop()},afterInvalidDrop:function(){this.completeDrop()},completeDrop:function(){var a=this.view,b=this.dragHeadersDisabled;setTimeout(function(){a.headersDisabled=b},50)}});Ext.grid.HeaderDropZone=Ext.extend(Ext.dd.DropZone,{proxyOffsets:[-4,-9],fly:Ext.Element.fly,constructor:function(a,c,b){this.grid=a;this.view=a.getView();this.proxyTop=Ext.DomHelper.append(document.body,{cls:"col-move-top",html:"&#160;"},true);this.proxyBottom=Ext.DomHelper.append(document.body,{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.getGridEl().id;Ext.grid.HeaderDropZone.superclass.constructor.call(this,a.getGridEl().dom)},getTargetFromEvent:function(c){var a=Ext.lib.Event.getTarget(c),b=this.view.findCellIndex(a);if(b!==false){return this.view.getHeaderCell(b)}},nextVisible:function(c){var b=this.view,a=this.grid.colModel;c=c.nextSibling;while(c){if(!a.isHidden(b.getCellIndex(c))){return c}c=c.nextSibling}return null},prevVisible:function(c){var b=this.view,a=this.grid.colModel;c=c.prevSibling;while(c){if(!a.isHidden(b.getCellIndex(c))){return c}c=c.prevSibling}return null},positionIndicator:function(d,k,j){var a=Ext.lib.Event.getPageX(j),g=Ext.lib.Dom.getRegion(k.firstChild),c,i,b=g.top+this.proxyOffsets[1];if((g.right-a)<=(g.right-g.left)/2){c=g.right+this.view.borderWidth;i="after"}else{c=g.left;i="before"}if(this.grid.colModel.isFixed(this.view.getCellIndex(k))){return false}c+=this.proxyOffsets[0];this.proxyTop.setLeftTop(c,b);this.proxyTop.show();if(!this.bottomOffset){this.bottomOffset=this.view.mainHd.getHeight()}this.proxyBottom.setLeftTop(c,b+this.proxyTop.dom.offsetHeight+this.bottomOffset);this.proxyBottom.show();return i},onNodeEnter:function(d,a,c,b){if(b.header!=d){this.positionIndicator(b.header,d,c)}},onNodeOver:function(g,b,d,c){var a=false;if(c.header!=g){a=this.positionIndicator(c.header,g,d)}if(!a){this.proxyTop.hide();this.proxyBottom.hide()}return a?this.dropAllowed:this.dropNotAllowed},onNodeOut:function(d,a,c,b){this.proxyTop.hide();this.proxyBottom.hide()},onNodeDrop:function(b,m,g,c){var d=c.header;if(d!=b){var k=this.grid.colModel,j=Ext.lib.Event.getPageX(g),a=Ext.lib.Dom.getRegion(b.firstChild),o=(a.right-j)<=((a.right-a.left)/2)?"after":"before",i=this.view.getCellIndex(d),l=this.view.getCellIndex(b);if(o=="after"){l++}if(i<l){l--}k.moveColumn(i,l);return true}return false}});Ext.grid.GridView.ColumnDragZone=Ext.extend(Ext.grid.HeaderDragZone,{constructor:function(a,b){Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this,a,b,null);this.proxy.el.addClass("x-grid3-col-dd")},handleMouseDown:function(a){},callHandleMouseDown:function(a){Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this,a)}});Ext.grid.SplitDragZone=Ext.extend(Ext.dd.DDProxy,{fly:Ext.Element.fly,constructor:function(a,c,b){this.grid=a;this.view=a.getView();this.proxy=this.view.resizeProxy;Ext.grid.SplitDragZone.superclass.constructor.call(this,c,"gridSplitters"+this.grid.getGridEl().id,{dragElId:Ext.id(this.proxy.dom),resizeFrame:false});this.setHandleElId(Ext.id(c));this.setOuterHandleElId(Ext.id(b));this.scroll=false},b4StartDrag:function(a,d){this.view.headersDisabled=true;this.proxy.setHeight(this.view.mainWrap.getHeight());var b=this.cm.getColumnWidth(this.cellIndex);var c=Math.max(b-this.grid.minColumnWidth,0);this.resetConstraints();this.setXConstraint(c,1000);this.setYConstraint(0,0);this.minX=a-c;this.maxX=a+1000;this.startPos=a;Ext.dd.DDProxy.prototype.b4StartDrag.call(this,a,d)},handleMouseDown:function(c){var b=Ext.EventObject.setEvent(c);var a=this.fly(b.getTarget());if(a.hasClass("x-grid-split")){this.cellIndex=this.view.getCellIndex(a.dom);this.split=a.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(c){this.view.headersDisabled=false;var a=Math.max(this.minX,Ext.lib.Event.getPageX(c));var b=a-this.startPos;this.view.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+b)},autoOffset:function(){this.setDelta(0,0)}});Ext.grid.GridDragZone=function(b,a){this.view=b.getView();Ext.grid.GridDragZone.superclass.constructor.call(this,this.view.mainBody.dom,a);this.scroll=false;this.grid=b;this.ddel=document.createElement("div");this.ddel.className="x-grid-dd-wrap";this.preventDefault=true};Ext.extend(Ext.grid.GridDragZone,Ext.dd.DragZone,{ddGroup:"GridDD",getDragData:function(g){var c=Ext.lib.Event.getTarget(g),i,h=this.view.findRowIndex(c),b,a,d;if(h!==false){i=this.grid.selModel;if(i.getSelectedCell){b=this.view.findCellIndex(c);a=i.getSelectedCell();if(!a||a[0]!==h||a[1]!==b){i.handleMouseDown(this.grid,h,b,g)}if(this.grid.dragCell){d=i.getSelectedCell();if(!this.grid.hasOwnProperty("ddText")){this.grid.ddText="{0} selected cell{1}"}}else{d=[this.grid.store.getAt(h)]}}else{if(!i.isSelected(h)||g.hasModifier()){i.handleMouseDown(this.grid,h,g)}d=i.getSelections()}return{grid:this.grid,ddel:this.ddel,rowIndex:h,selections:d}}return false},onInitDrag:function(b){var a=this.dragData;this.ddel.innerHTML=this.grid.getDragDropText();this.proxy.update(this.ddel)},afterRepair:function(){this.dragging=false},getRepairXY:function(b,a){return false},onEndDrag:function(a,b){},onValidDrop:function(a,b,c){this.hideProxy()},beforeInvalidDrop:function(a,b){}});Ext.grid.ColumnModel=Ext.extend(Ext.util.Observable,{defaultWidth:100,defaultSortable:false,constructor:function(a){if(a.columns){Ext.apply(this,a);this.setConfig(a.columns,true)}else{this.setConfig(a,true)}this.addEvents("widthchange","headerchange","hiddenchange","columnmoved","configchange");Ext.grid.ColumnModel.superclass.constructor.call(this)},getColumnId:function(a){return this.config[a].id},getColumnAt:function(a){return this.config[a]},setConfig:function(d,b){var e,h,a;if(!b){delete this.totalWidth;for(e=0,a=this.config.length;e<a;e++){h=this.config[e];if(h.setEditor){h.setEditor(null)}}}this.defaults=Ext.apply({width:this.defaultWidth,sortable:this.defaultSortable},this.defaults);this.config=d;this.lookup={};for(e=0,a=d.length;e<a;e++){h=Ext.applyIf(d[e],this.defaults);if(Ext.isEmpty(h.id)){h.id=e}if(!h.isColumn){var g=Ext.grid.Column.types[h.xtype||"gridcolumn"];h=new g(h);d[e]=h}this.lookup[h.id]=h}if(!b){this.fireEvent("configchange",this)}},getColumnById:function(a){return this.lookup[a]},getIndexById:function(c){for(var b=0,a=this.config.length;b<a;b++){if(this.config[b].id==c){return b}}return -1},moveColumn:function(e,b){var a=this.config,d=a[e];a.splice(e,1);a.splice(b,0,d);this.dataMap=null;this.fireEvent("columnmoved",this,e,b)},getColumnCount:function(b){var d=this.config.length,e=0,a;if(b===true){for(a=0;a<d;a++){if(!this.isHidden(a)){e++}}return e}return d},getColumnsBy:function(g,e){var b=this.config,h=b.length,a=[],d,j;for(d=0;d<h;d++){j=b[d];if(g.call(e||this,j,d)===true){a[a.length]=j}}return a},isSortable:function(a){return !!this.config[a].sortable},isMenuDisabled:function(a){return !!this.config[a].menuDisabled},getRenderer:function(a){return this.config[a].renderer||Ext.grid.ColumnModel.defaultRenderer},getRendererScope:function(a){return this.config[a].scope},setRenderer:function(a,b){this.config[a].renderer=b},getColumnWidth:function(a){var b=this.config[a].width;if(typeof b!="number"){b=this.defaultWidth}return b},setColumnWidth:function(b,c,a){this.config[b].width=c;this.totalWidth=null;if(!a){this.fireEvent("widthchange",this,b,c)}},getTotalWidth:function(b){if(!this.totalWidth){this.totalWidth=0;for(var c=0,a=this.config.length;c<a;c++){if(b||!this.isHidden(c)){this.totalWidth+=this.getColumnWidth(c)}}}return this.totalWidth},getColumnHeader:function(a){return this.config[a].header},setColumnHeader:function(a,b){this.config[a].header=b;this.fireEvent("headerchange",this,a,b)},getColumnTooltip:function(a){return this.config[a].tooltip},setColumnTooltip:function(a,b){this.config[a].tooltip=b},getDataIndex:function(a){return this.config[a].dataIndex},setDataIndex:function(a,b){this.config[a].dataIndex=b},findColumnIndex:function(d){var e=this.config;for(var b=0,a=e.length;b<a;b++){if(e[b].dataIndex==d){return b}}return -1},isCellEditable:function(b,e){var d=this.config[b],a=d.editable;return !!(a||(!Ext.isDefined(a)&&d.editor))},getCellEditor:function(a,b){return this.config[a].getCellEditor(b)},setEditable:function(a,b){this.config[a].editable=b},isHidden:function(a){return !!this.config[a].hidden},isFixed:function(a){return !!this.config[a].fixed},isResizable:function(a){return a>=0&&this.config[a].resizable!==false&&this.config[a].fixed!==true},setHidden:function(a,b){var d=this.config[a];if(d.hidden!==b){d.hidden=b;this.totalWidth=null;this.fireEvent("hiddenchange",this,a,b)}},setEditor:function(a,b){this.config[a].setEditor(b)},destroy:function(){var b=this.config.length,a=0;for(;a<b;a++){this.config[a].destroy()}delete this.config;delete this.lookup;this.purgeListeners()},setState:function(a,b){b=Ext.applyIf(b,this.defaults);Ext.apply(this.config[a],b)}});Ext.grid.ColumnModel.defaultRenderer=function(a){if(typeof a=="string"&&a.length<1){return"&#160;"}return a};Ext.grid.AbstractSelectionModel=Ext.extend(Ext.util.Observable,{constructor:function(){this.locked=false;Ext.grid.AbstractSelectionModel.superclass.constructor.call(this)},init:function(a){this.grid=a;if(this.lockOnInit){delete this.lockOnInit;this.locked=false;this.lock()}this.initEvents()},lock:function(){if(!this.locked){this.locked=true;var a=this.grid;if(a){a.getView().on({scope:this,beforerefresh:this.sortUnLock,refresh:this.sortLock})}else{this.lockOnInit=true}}},sortLock:function(){this.locked=true},sortUnLock:function(){this.locked=false},unlock:function(){if(this.locked){this.locked=false;var a=this.grid,b;if(a){b=a.getView();b.un("beforerefresh",this.sortUnLock,this);b.un("refresh",this.sortLock,this)}else{delete this.lockOnInit}}},isLocked:function(){return this.locked},destroy:function(){this.unlock();this.purgeListeners()}});Ext.grid.RowSelectionModel=Ext.extend(Ext.grid.AbstractSelectionModel,{singleSelect:false,constructor:function(a){Ext.apply(this,a);this.selections=new Ext.util.MixedCollection(false,function(b){return b.id});this.last=false;this.lastActive=false;this.addEvents("selectionchange","beforerowselect","rowselect","rowdeselect");Ext.grid.RowSelectionModel.superclass.constructor.call(this)},initEvents:function(){if(!this.grid.enableDragDrop&&!this.grid.enableDrag){this.grid.on("rowmousedown",this.handleMouseDown,this)}this.rowNav=new Ext.KeyNav(this.grid.getGridEl(),{up:this.onKeyPress,down:this.onKeyPress,scope:this});this.grid.getView().on({scope:this,refresh:this.onRefresh,rowupdated:this.onRowUpdated,rowremoved:this.onRemove})},onKeyPress:function(g,b){var a=b=="up",h=a?"selectPrevious":"selectNext",d=a?-1:1,c;if(!g.shiftKey||this.singleSelect){this[h](false)}else{if(this.last!==false&&this.lastActive!==false){c=this.last;this.selectRange(this.last,this.lastActive+d);this.grid.getView().focusRow(this.lastActive);if(c!==false){this.last=c}}else{this.selectFirstRow()}}},onRefresh:function(){var g=this.grid.store,d=this.getSelections(),c=0,a=d.length,b,e;this.silent=true;this.clearSelections(true);for(;c<a;c++){e=d[c];if((b=g.indexOfId(e.id))!=-1){this.selectRow(b,true)}}if(d.length!=this.selections.getCount()){this.fireEvent("selectionchange",this)}this.silent=false},onRemove:function(a,b,c){if(this.selections.remove(c)!==false){this.fireEvent("selectionchange",this)}},onRowUpdated:function(a,b,c){if(this.isSelected(c)){a.onRowSelect(b)}},selectRecords:function(b,e){if(!e){this.clearSelections()}var d=this.grid.store,c=0,a=b.length;for(;c<a;c++){this.selectRow(d.indexOf(b[c]),true)}},getCount:function(){return this.selections.length},selectFirstRow:function(){this.selectRow(0)},selectLastRow:function(a){this.selectRow(this.grid.store.getCount()-1,a)},selectNext:function(a){if(this.hasNext()){this.selectRow(this.last+1,a);this.grid.getView().focusRow(this.last);return true}return false},selectPrevious:function(a){if(this.hasPrevious()){this.selectRow(this.last-1,a);this.grid.getView().focusRow(this.last);return true}return false},hasNext:function(){return this.last!==false&&(this.last+1)<this.grid.store.getCount()},hasPrevious:function(){return !!this.last},getSelections:function(){return[].concat(this.selections.items)},getSelected:function(){return this.selections.itemAt(0)},each:function(e,d){var c=this.getSelections(),b=0,a=c.length;for(;b<a;b++){if(e.call(d||this,c[b],b)===false){return false}}return true},clearSelections:function(a){if(this.isLocked()){return}if(a!==true){var c=this.grid.store,b=this.selections;b.each(function(d){this.deselectRow(c.indexOfId(d.id))},this);b.clear()}else{this.selections.clear()}this.last=false},selectAll:function(){if(this.isLocked()){return}this.selections.clear();for(var b=0,a=this.grid.store.getCount();b<a;b++){this.selectRow(b,true)}},hasSelection:function(){return this.selections.length>0},isSelected:function(a){var b=Ext.isNumber(a)?this.grid.store.getAt(a):a;return(b&&this.selections.key(b.id)?true:false)},isIdSelected:function(a){return(this.selections.key(a)?true:false)},handleMouseDown:function(d,i,h){if(h.button!==0||this.isLocked()){return}var a=this.grid.getView();if(h.shiftKey&&!this.singleSelect&&this.last!==false){var c=this.last;this.selectRange(c,i,h.ctrlKey);this.last=c;a.focusRow(i)}else{var b=this.isSelected(i);if(h.ctrlKey&&b){this.deselectRow(i)}else{if(!b||this.getCount()>1){this.selectRow(i,h.ctrlKey||h.shiftKey);a.focusRow(i)}}}},selectRows:function(c,d){if(!d){this.clearSelections()}for(var b=0,a=c.length;b<a;b++){this.selectRow(c[b],true)}},selectRange:function(b,a,d){var c;if(this.isLocked()){return}if(!d){this.clearSelections()}if(b<=a){for(c=b;c<=a;c++){this.selectRow(c,true)}}else{for(c=b;c>=a;c--){this.selectRow(c,true)}}},deselectRange:function(c,b,a){if(this.isLocked()){return}for(var d=c;d<=b;d++){this.deselectRow(d,a)}},selectRow:function(b,d,a){if(this.isLocked()||(b<0||b>=this.grid.store.getCount())||(d&&this.isSelected(b))){return}var c=this.grid.store.getAt(b);if(c&&this.fireEvent("beforerowselect",this,b,d,c)!==false){if(!d||this.singleSelect){this.clearSelections()}this.selections.add(c);this.last=this.lastActive=b;if(!a){this.grid.getView().onRowSelect(b)}if(!this.silent){this.fireEvent("rowselect",this,b,c);this.fireEvent("selectionchange",this)}}},deselectRow:function(b,a){if(this.isLocked()){return}if(this.last==b){this.last=false}if(this.lastActive==b){this.lastActive=false}var c=this.grid.store.getAt(b);if(c){this.selections.remove(c);if(!a){this.grid.getView().onRowDeselect(b)}this.fireEvent("rowdeselect",this,b,c);this.fireEvent("selectionchange",this)}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)},onEditorKey:function(n,l){var d=l.getKey(),h,i=this.grid,p=i.lastEdit,j=i.activeEditor,b=l.shiftKey,o,p,a,m;if(d==l.TAB){l.stopEvent();j.completeEdit();if(b){h=i.walkCells(j.row,j.col-1,-1,this.acceptsNav,this)}else{h=i.walkCells(j.row,j.col+1,1,this.acceptsNav,this)}}else{if(d==l.ENTER){if(this.moveEditorOnEnter!==false){if(b){h=i.walkCells(p.row-1,p.col,-1,this.acceptsNav,this)}else{h=i.walkCells(p.row+1,p.col,1,this.acceptsNav,this)}}}}if(h){a=h[0];m=h[1];this.onEditorSelect(a,p.row);if(i.isEditor&&i.editing){o=i.activeEditor;if(o&&o.field.triggerBlur){o.field.triggerBlur()}}i.startEditing(a,m)}},onEditorSelect:function(b,a){if(a!=b){this.selectRow(b)}},destroy:function(){Ext.destroy(this.rowNav);this.rowNav=null;Ext.grid.RowSelectionModel.superclass.destroy.call(this)}});Ext.grid.Column=Ext.extend(Ext.util.Observable,{isColumn:true,constructor:function(b){Ext.apply(this,b);if(Ext.isString(this.renderer)){this.renderer=Ext.util.Format[this.renderer]}else{if(Ext.isObject(this.renderer)){this.scope=this.renderer.scope;this.renderer=this.renderer.fn}}if(!this.scope){this.scope=this}var a=this.editor;delete this.editor;this.setEditor(a);this.addEvents("click","contextmenu","dblclick","mousedown");Ext.grid.Column.superclass.constructor.call(this)},processEvent:function(b,d,c,g,a){return this.fireEvent(b,this,c,g,d)},destroy:function(){if(this.setEditor){this.setEditor(null)}this.purgeListeners()},renderer:function(a){return a},getEditor:function(a){return this.editable!==false?this.editor:null},setEditor:function(b){var a=this.editor;if(a){if(a.gridEditor){a.gridEditor.destroy();delete a.gridEditor}else{a.destroy()}}this.editor=null;if(b){if(!b.isXType){b=Ext.create(b,"textfield")}this.editor=b}},getCellEditor:function(b){var a=this.getEditor(b);if(a){if(!a.startEdit){if(!a.gridEditor){a.gridEditor=new Ext.grid.GridEditor(a)}a=a.gridEditor}}return a}});Ext.grid.BooleanColumn=Ext.extend(Ext.grid.Column,{trueText:"true",falseText:"false",undefinedText:"&#160;",constructor:function(a){Ext.grid.BooleanColumn.superclass.constructor.call(this,a);var c=this.trueText,d=this.falseText,b=this.undefinedText;this.renderer=function(e){if(e===undefined){return b}if(!e||e==="false"){return d}return c}}});Ext.grid.NumberColumn=Ext.extend(Ext.grid.Column,{format:"0,000.00",constructor:function(a){Ext.grid.NumberColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.numberRenderer(this.format)}});Ext.grid.DateColumn=Ext.extend(Ext.grid.Column,{format:"m/d/Y",constructor:function(a){Ext.grid.DateColumn.superclass.constructor.call(this,a);this.renderer=Ext.util.Format.dateRenderer(this.format)}});Ext.grid.TemplateColumn=Ext.extend(Ext.grid.Column,{constructor:function(a){Ext.grid.TemplateColumn.superclass.constructor.call(this,a);var b=(!Ext.isPrimitive(this.tpl)&&this.tpl.compile)?this.tpl:new Ext.XTemplate(this.tpl);this.renderer=function(d,e,c){return b.apply(c.data)};this.tpl=b}});Ext.grid.ActionColumn=Ext.extend(Ext.grid.Column,{header:"&#160;",actionIdRe:/x-action-col-(\d+)/,altText:"",constructor:function(b){var g=this,c=b.items||(g.items=[g]),a=c.length,d,e;Ext.grid.ActionColumn.superclass.constructor.call(g,b);g.renderer=function(h,i){h=Ext.isFunction(b.renderer)?b.renderer.apply(this,arguments)||"":"";i.css+=" x-action-col-cell";for(d=0;d<a;d++){e=c[d];h+='<img alt="'+(e.altText||g.altText)+'" src="'+(e.icon||Ext.BLANK_IMAGE_URL)+'" class="x-action-col-icon x-action-col-'+String(d)+" "+(e.iconCls||"")+" "+(Ext.isFunction(e.getClass)?e.getClass.apply(e.scope||this.scope||this,arguments):"")+'"'+((e.tooltip)?' ext:qtip="'+e.tooltip+'"':"")+" />"}return h}},destroy:function(){delete this.items;delete this.renderer;return Ext.grid.ActionColumn.superclass.destroy.apply(this,arguments)},processEvent:function(c,i,d,j,b){var a=i.getTarget().className.match(this.actionIdRe),h,g;if(a&&(h=this.items[parseInt(a[1],10)])){if(c=="click"){(g=h.handler||this.handler)&&g.call(h.scope||this.scope||this,d,j,b,h,i)}else{if((c=="mousedown")&&(h.stopSelection!==false)){return false}}}return Ext.grid.ActionColumn.superclass.processEvent.apply(this,arguments)}});Ext.grid.Column.types={gridcolumn:Ext.grid.Column,booleancolumn:Ext.grid.BooleanColumn,numbercolumn:Ext.grid.NumberColumn,datecolumn:Ext.grid.DateColumn,templatecolumn:Ext.grid.TemplateColumn,actioncolumn:Ext.grid.ActionColumn};Ext.grid.RowNumberer=Ext.extend(Object,{header:"",width:23,sortable:false,constructor:function(a){Ext.apply(this,a);if(this.rowspan){this.renderer=this.renderer.createDelegate(this)}},fixed:true,hideable:false,menuDisabled:true,dataIndex:"",id:"numberer",rowspan:undefined,renderer:function(b,c,a,d){if(this.rowspan){c.cellAttr='rowspan="'+this.rowspan+'"'}return d+1}});Ext.grid.CheckboxSelectionModel=Ext.extend(Ext.grid.RowSelectionModel,{header:'<div class="x-grid3-hd-checker">&#160;</div>',width:20,sortable:false,menuDisabled:true,fixed:true,hideable:false,dataIndex:"",id:"checker",isColumn:true,constructor:function(){Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this,arguments);if(this.checkOnly){this.handleMouseDown=Ext.emptyFn}},initEvents:function(){Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);this.grid.on("render",function(){Ext.fly(this.grid.getView().innerHd).on("mousedown",this.onHdMouseDown,this)},this)},processEvent:function(b,d,c,g,a){if(b=="mousedown"){this.onMouseDown(d,d.getTarget());return false}else{return Ext.grid.Column.prototype.processEvent.apply(this,arguments)}},onMouseDown:function(c,b){if(c.button===0&&b.className=="x-grid3-row-checker"){c.stopEvent();var d=c.getTarget(".x-grid3-row");if(d){var a=d.rowIndex;if(this.isSelected(a)){this.deselectRow(a)}else{this.selectRow(a,true);this.grid.getView().focusRow(a)}}}},onHdMouseDown:function(c,a){if(a.className=="x-grid3-hd-checker"){c.stopEvent();var b=Ext.fly(a.parentNode);var d=b.hasClass("x-grid3-hd-checker-on");if(d){b.removeClass("x-grid3-hd-checker-on");this.clearSelections()}else{b.addClass("x-grid3-hd-checker-on");this.selectAll()}}},renderer:function(b,c,a){return'<div class="x-grid3-row-checker">&#160;</div>'},onEditorSelect:function(b,a){if(a!=b&&!this.checkOnly){this.selectRow(b)}}});Ext.grid.CellSelectionModel=Ext.extend(Ext.grid.AbstractSelectionModel,{constructor:function(a){Ext.apply(this,a);this.selection=null;this.addEvents("beforecellselect","cellselect","selectionchange");Ext.grid.CellSelectionModel.superclass.constructor.call(this)},initEvents:function(){this.grid.on("cellmousedown",this.handleMouseDown,this);this.grid.on(Ext.EventManager.getKeyEvent(),this.handleKeyDown,this);this.grid.getView().on({scope:this,refresh:this.onViewChange,rowupdated:this.onRowUpdated,beforerowremoved:this.clearSelections,beforerowsinserted:this.clearSelections});if(this.grid.isEditor){this.grid.on("beforeedit",this.beforeEdit,this)}},beforeEdit:function(a){this.select(a.row,a.column,false,true,a.record)},onRowUpdated:function(a,b,c){if(this.selection&&this.selection.record==c){a.onCellSelect(b,this.selection.cell[1])}},onViewChange:function(){this.clearSelections(true)},getSelectedCell:function(){return this.selection?this.selection.cell:null},clearSelections:function(b){var a=this.selection;if(a){if(b!==true){this.grid.view.onCellDeselect(a.cell[0],a.cell[1])}this.selection=null;this.fireEvent("selectionchange",this,null)}},hasSelection:function(){return this.selection?true:false},handleMouseDown:function(b,d,a,c){if(c.button!==0||this.isLocked()){return}this.select(d,a)},select:function(g,c,b,e,d){if(this.fireEvent("beforecellselect",this,g,c)!==false){this.clearSelections();d=d||this.grid.store.getAt(g);this.selection={record:d,cell:[g,c]};if(!b){var a=this.grid.getView();a.onCellSelect(g,c);if(e!==true){a.focusCell(g,c)}}this.fireEvent("cellselect",this,g,c);this.fireEvent("selectionchange",this,this.selection)}},isSelectable:function(c,b,a){return !a.isHidden(b)},onEditorKey:function(b,a){if(a.getKey()==a.TAB){this.handleKeyDown(a)}},handleKeyDown:function(j){if(!j.isNavKeyPress()){return}var d=j.getKey(),i=this.grid,p=this.selection,b=this,m=function(g,c,e){return i.walkCells(g,c,e,i.isEditor&&i.editing?b.acceptsNav:b.isSelectable,b)},o,h,a,l,n;switch(d){case j.ESC:case j.PAGE_UP:case j.PAGE_DOWN:break;default:j.stopEvent();break}if(!p){o=m(0,0,1);if(o){this.select(o[0],o[1])}return}o=p.cell;a=o[0];l=o[1];switch(d){case j.TAB:if(j.shiftKey){h=m(a,l-1,-1)}else{h=m(a,l+1,1)}break;case j.DOWN:h=m(a+1,l,1);break;case j.UP:h=m(a-1,l,-1);break;case j.RIGHT:h=m(a,l+1,1);break;case j.LEFT:h=m(a,l-1,-1);break;case j.ENTER:if(i.isEditor&&!i.editing){i.startEditing(a,l);return}break}if(h){a=h[0];l=h[1];this.select(a,l);if(i.isEditor&&i.editing){n=i.activeEditor;if(n&&n.field.triggerBlur){n.field.triggerBlur()}i.startEditing(a,l)}}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)}});Ext.grid.EditorGridPanel=Ext.extend(Ext.grid.GridPanel,{clicksToEdit:2,forceValidation:false,isEditor:true,detectEdit:false,autoEncode:false,trackMouseOver:false,initComponent:function(){Ext.grid.EditorGridPanel.superclass.initComponent.call(this);if(!this.selModel){this.selModel=new Ext.grid.CellSelectionModel()}this.activeEditor=null;this.addEvents("beforeedit","afteredit","validateedit")},initEvents:function(){Ext.grid.EditorGridPanel.superclass.initEvents.call(this);this.getGridEl().on("mousewheel",this.stopEditing.createDelegate(this,[true]),this);this.on("columnresize",this.stopEditing,this,[true]);if(this.clicksToEdit==1){this.on("cellclick",this.onCellDblClick,this)}else{var a=this.getView();if(this.clicksToEdit=="auto"&&a.mainBody){a.mainBody.on("mousedown",this.onAutoEditClick,this)}this.on("celldblclick",this.onCellDblClick,this)}},onResize:function(){Ext.grid.EditorGridPanel.superclass.onResize.apply(this,arguments);var a=this.activeEditor;if(this.editing&&a){a.realign(true)}},onCellDblClick:function(b,c,a){this.startEditing(c,a)},onAutoEditClick:function(c,b){if(c.button!==0){return}var g=this.view.findRowIndex(b),a=this.view.findCellIndex(b);if(g!==false&&a!==false){this.stopEditing();if(this.selModel.getSelectedCell){var d=this.selModel.getSelectedCell();if(d&&d[0]===g&&d[1]===a){this.startEditing(g,a)}}else{if(this.selModel.isSelected(g)){this.startEditing(g,a)}}}},onEditComplete:function(b,d,a){this.editing=false;this.lastActiveEditor=this.activeEditor;this.activeEditor=null;var c=b.record,h=this.colModel.getDataIndex(b.col);d=this.postEditValue(d,a,c,h);if(this.forceValidation===true||String(d)!==String(a)){var g={grid:this,record:c,field:h,originalValue:a,value:d,row:b.row,column:b.col,cancel:false};if(this.fireEvent("validateedit",g)!==false&&!g.cancel&&String(d)!==String(a)){c.set(h,g.value);delete g.cancel;this.fireEvent("afteredit",g)}}this.view.focusCell(b.row,b.col)},startEditing:function(i,c){this.stopEditing();if(this.colModel.isCellEditable(c,i)){this.view.ensureVisible(i,c,true);var d=this.store.getAt(i),h=this.colModel.getDataIndex(c),g={grid:this,record:d,field:h,value:d.data[h],row:i,column:c,cancel:false};if(this.fireEvent("beforeedit",g)!==false&&!g.cancel){this.editing=true;var b=this.colModel.getCellEditor(c,i);if(!b){return}if(!b.rendered){b.parentEl=this.view.getEditorParent(b);b.on({scope:this,render:{fn:function(e){e.field.focus(false,true)},single:true,scope:this},specialkey:function(k,j){this.getSelectionModel().onEditorKey(k,j)},complete:this.onEditComplete,canceledit:this.stopEditing.createDelegate(this,[true])})}Ext.apply(b,{row:i,col:c,record:d});this.lastEdit={row:i,col:c};this.activeEditor=b;if(b.field.isXType("checkbox")){b.allowBlur=false;this.setupCheckbox(b.field)}b.selectSameEditor=(this.activeEditor==this.lastActiveEditor);var a=this.preEditValue(d,h);b.startEdit(this.view.getCell(i,c).firstChild,Ext.isDefined(a)?a:"");(function(){delete b.selectSameEditor}).defer(50)}}},setupCheckbox:function(c){var b=this,a=function(){c.el.on("click",b.onCheckClick,b,{single:true})};if(c.rendered){a()}else{c.on("render",a,null,{single:true})}},onCheckClick:function(){var a=this.activeEditor;a.allowBlur=true;a.field.focus(false,10)},preEditValue:function(a,c){var b=a.data[c];return this.autoEncode&&Ext.isString(b)?Ext.util.Format.htmlDecode(b):b},postEditValue:function(c,a,b,d){return this.autoEncode&&Ext.isString(c)?Ext.util.Format.htmlEncode(c):c},stopEditing:function(b){if(this.editing){var a=this.lastActiveEditor=this.activeEditor;if(a){a[b===true?"cancelEdit":"completeEdit"]();this.view.focusCell(a.row,a.col)}this.activeEditor=null}this.editing=false}});Ext.reg("editorgrid",Ext.grid.EditorGridPanel);Ext.grid.GridEditor=function(b,a){Ext.grid.GridEditor.superclass.constructor.call(this,b,a);b.monitorTab=false};Ext.extend(Ext.grid.GridEditor,Ext.Editor,{alignment:"tl-tl",autoSize:"width",hideEl:false,cls:"x-small-editor x-grid-editor",shim:false,shadow:false});Ext.grid.PropertyRecord=Ext.data.Record.create([{name:"name",type:"string"},"value"]);Ext.grid.PropertyStore=Ext.extend(Ext.util.Observable,{constructor:function(a,b){this.grid=a;this.store=new Ext.data.Store({recordType:Ext.grid.PropertyRecord});this.store.on("update",this.onUpdate,this);if(b){this.setSource(b)}Ext.grid.PropertyStore.superclass.constructor.call(this)},setSource:function(c){this.source=c;this.store.removeAll();var b=[];for(var a in c){if(this.isEditableValue(c[a])){b.push(new Ext.grid.PropertyRecord({name:a,value:c[a]},a))}}this.store.loadRecords({records:b},{},true)},onUpdate:function(e,a,d){if(d==Ext.data.Record.EDIT){var b=a.data.value;var c=a.modified.value;if(this.grid.fireEvent("beforepropertychange",this.source,a.id,b,c)!==false){this.source[a.id]=b;a.commit();this.grid.fireEvent("propertychange",this.source,a.id,b,c)}else{a.reject()}}},getProperty:function(a){return this.store.getAt(a)},isEditableValue:function(a){return Ext.isPrimitive(a)||Ext.isDate(a)},setValue:function(d,c,a){var b=this.getRec(d);if(b){b.set("value",c);this.source[d]=c}else{if(a){this.source[d]=c;b=new Ext.grid.PropertyRecord({name:d,value:c},d);this.store.add(b)}}},remove:function(b){var a=this.getRec(b);if(a){this.store.remove(a);delete this.source[b]}},getRec:function(a){return this.store.getById(a)},getSource:function(){return this.source}});Ext.grid.PropertyColumnModel=Ext.extend(Ext.grid.ColumnModel,{nameText:"Name",valueText:"Value",dateFormat:"m/j/Y",trueText:"true",falseText:"false",constructor:function(c,b){var d=Ext.grid,e=Ext.form;this.grid=c;d.PropertyColumnModel.superclass.constructor.call(this,[{header:this.nameText,width:50,sortable:true,dataIndex:"name",id:"name",menuDisabled:true},{header:this.valueText,width:50,resizable:false,dataIndex:"value",id:"value",menuDisabled:true}]);this.store=b;var a=new e.Field({autoCreate:{tag:"select",children:[{tag:"option",value:"true",html:this.trueText},{tag:"option",value:"false",html:this.falseText}]},getValue:function(){return this.el.dom.value=="true"}});this.editors={date:new d.GridEditor(new e.DateField({selectOnFocus:true})),string:new d.GridEditor(new e.TextField({selectOnFocus:true})),number:new d.GridEditor(new e.NumberField({selectOnFocus:true,style:"text-align:left;"})),"boolean":new d.GridEditor(a,{autoSize:"both"})};this.renderCellDelegate=this.renderCell.createDelegate(this);this.renderPropDelegate=this.renderProp.createDelegate(this)},renderDate:function(a){return a.dateFormat(this.dateFormat)},renderBool:function(a){return this[a?"trueText":"falseText"]},isCellEditable:function(a,b){return a==1},getRenderer:function(a){return a==1?this.renderCellDelegate:this.renderPropDelegate},renderProp:function(a){return this.getPropertyName(a)},renderCell:function(d,b,c){var a=this.grid.customRenderers[c.get("name")];if(a){return a.apply(this,arguments)}var e=d;if(Ext.isDate(d)){e=this.renderDate(d)}else{if(typeof d=="boolean"){e=this.renderBool(d)}}return Ext.util.Format.htmlEncode(e)},getPropertyName:function(b){var a=this.grid.propertyNames;return a&&a[b]?a[b]:b},getCellEditor:function(a,e){var b=this.store.getProperty(e),d=b.data.name,c=b.data.value;if(this.grid.customEditors[d]){return this.grid.customEditors[d]}if(Ext.isDate(c)){return this.editors.date}else{if(typeof c=="number"){return this.editors.number}else{if(typeof c=="boolean"){return this.editors["boolean"]}else{return this.editors.string}}}},destroy:function(){Ext.grid.PropertyColumnModel.superclass.destroy.call(this);this.destroyEditors(this.editors);this.destroyEditors(this.grid.customEditors)},destroyEditors:function(b){for(var a in b){Ext.destroy(b[a])}}});Ext.grid.PropertyGrid=Ext.extend(Ext.grid.EditorGridPanel,{enableColumnMove:false,stripeRows:false,trackMouseOver:false,clicksToEdit:1,enableHdMenu:false,viewConfig:{forceFit:true},initComponent:function(){this.customRenderers=this.customRenderers||{};this.customEditors=this.customEditors||{};this.lastEditRow=null;var b=new Ext.grid.PropertyStore(this);this.propStore=b;var a=new Ext.grid.PropertyColumnModel(this,b);b.store.sort("name","ASC");this.addEvents("beforepropertychange","propertychange");this.cm=a;this.ds=b.store;Ext.grid.PropertyGrid.superclass.initComponent.call(this);this.mon(this.selModel,"beforecellselect",function(e,d,c){if(c===0){this.startEditing.defer(200,this,[d,1]);return false}},this)},onRender:function(){Ext.grid.PropertyGrid.superclass.onRender.apply(this,arguments);this.getGridEl().addClass("x-props-grid")},afterRender:function(){Ext.grid.PropertyGrid.superclass.afterRender.apply(this,arguments);if(this.source){this.setSource(this.source)}},setSource:function(a){this.propStore.setSource(a)},getSource:function(){return this.propStore.getSource()},setProperty:function(c,b,a){this.propStore.setValue(c,b,a)},removeProperty:function(a){this.propStore.remove(a)}});Ext.reg("propertygrid",Ext.grid.PropertyGrid);Ext.grid.GroupingView=Ext.extend(Ext.grid.GridView,{groupByText:"Group By This Field",showGroupsText:"Show in Groups",hideGroupedColumn:false,showGroupName:true,startCollapsed:false,enableGrouping:true,enableGroupingMenu:true,enableNoGroups:true,emptyGroupText:"(None)",ignoreAdd:false,groupTextTpl:"{text}",groupMode:"value",cancelEditOnToggle:true,initTemplates:function(){Ext.grid.GroupingView.superclass.initTemplates.call(this);this.state={};var a=this.grid.getSelectionModel();a.on(a.selectRow?"beforerowselect":"beforecellselect",this.onBeforeRowSelect,this);if(!this.startGroup){this.startGroup=new Ext.XTemplate('<div id="{groupId}" class="x-grid-group {cls}">','<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">',this.groupTextTpl,"</div></div>",'<div id="{groupId}-bd" class="x-grid-group-body">')}this.startGroup.compile();if(!this.endGroup){this.endGroup="</div></div>"}},findGroup:function(a){return Ext.fly(a).up(".x-grid-group",this.mainBody.dom)},getGroups:function(){return this.hasRows()?this.mainBody.dom.childNodes:[]},onAdd:function(d,a,b){if(this.canGroup()&&!this.ignoreAdd){var c=this.getScrollState();this.fireEvent("beforerowsinserted",d,b,b+(a.length-1));this.refresh();this.restoreScroll(c);this.fireEvent("rowsinserted",d,b,b+(a.length-1))}else{if(!this.canGroup()){Ext.grid.GroupingView.superclass.onAdd.apply(this,arguments)}}},onRemove:function(e,a,b,d){Ext.grid.GroupingView.superclass.onRemove.apply(this,arguments);var c=document.getElementById(a._groupId);if(c&&c.childNodes[1].childNodes.length<1){Ext.removeNode(c)}this.applyEmptyText()},refreshRow:function(a){if(this.ds.getCount()==1){this.refresh()}else{this.isUpdating=true;Ext.grid.GroupingView.superclass.refreshRow.apply(this,arguments);this.isUpdating=false}},beforeMenuShow:function(){var c,a=this.hmenu.items,b=this.cm.config[this.hdCtxIndex].groupable===false;if((c=a.get("groupBy"))){c.setDisabled(b)}if((c=a.get("showGroups"))){c.setDisabled(b);c.setChecked(this.canGroup(),true)}},renderUI:function(){var a=Ext.grid.GroupingView.superclass.renderUI.call(this);if(this.enableGroupingMenu&&this.hmenu){this.hmenu.add("-",{itemId:"groupBy",text:this.groupByText,handler:this.onGroupByClick,scope:this,iconCls:"x-group-by-icon"});if(this.enableNoGroups){this.hmenu.add({itemId:"showGroups",text:this.showGroupsText,checked:true,checkHandler:this.onShowGroupsClick,scope:this})}this.hmenu.on("beforeshow",this.beforeMenuShow,this)}return a},processEvent:function(b,i){Ext.grid.GroupingView.superclass.processEvent.call(this,b,i);var h=i.getTarget(".x-grid-group-hd",this.mainBody);if(h){var g=this.getGroupField(),d=this.getPrefix(g),a=h.id.substring(d.length),c=new RegExp("gp-"+Ext.escapeRe(g)+"--hd");a=a.substr(0,a.length-3);if(a||c.test(h.id)){this.grid.fireEvent("group"+b,this.grid,g,a,i)}if(b=="mousedown"&&i.button==0){this.toggleGroup(h.parentNode)}}},onGroupByClick:function(){var a=this.grid;this.enableGrouping=true;a.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));a.fireEvent("groupchange",a,a.store.getGroupState());this.beforeMenuShow();this.refresh()},onShowGroupsClick:function(a,b){this.enableGrouping=b;if(b){this.onGroupByClick()}else{this.grid.store.clearGrouping();this.grid.fireEvent("groupchange",this,null)}},toggleRowIndex:function(c,a){if(!this.canGroup()){return}var b=this.getRow(c);if(b){this.toggleGroup(this.findGroup(b),a)}},toggleGroup:function(c,b){var a=Ext.get(c),d=Ext.util.Format.htmlEncode(a.id);b=Ext.isDefined(b)?b:a.hasClass("x-grid-group-collapsed");if(this.state[d]!==b){if(this.cancelEditOnToggle!==false){this.grid.stopEditing(true)}this.state[d]=b;a[b?"removeClass":"addClass"]("x-grid-group-collapsed")}},toggleAllGroups:function(c){var b=this.getGroups();for(var d=0,a=b.length;d<a;d++){this.toggleGroup(b[d],c)}},expandAllGroups:function(){this.toggleAllGroups(true)},collapseAllGroups:function(){this.toggleAllGroups(false)},getGroup:function(a,e,i,j,b,h){var c=this.cm.config[b],d=i?i.call(c.scope,a,{},e,j,b,h):String(a);if(d===""||d==="&#160;"){d=c.emptyGroupText||this.emptyGroupText}return d},getGroupField:function(){return this.grid.store.getGroupState()},afterRender:function(){if(!this.ds||!this.cm){return}Ext.grid.GroupingView.superclass.afterRender.call(this);if(this.grid.deferRowRender){this.updateGroupWidths()}},afterRenderUI:function(){Ext.grid.GroupingView.superclass.afterRenderUI.call(this);if(this.enableGroupingMenu&&this.hmenu){this.hmenu.add("-",{itemId:"groupBy",text:this.groupByText,handler:this.onGroupByClick,scope:this,iconCls:"x-group-by-icon"});if(this.enableNoGroups){this.hmenu.add({itemId:"showGroups",text:this.showGroupsText,checked:true,checkHandler:this.onShowGroupsClick,scope:this})}this.hmenu.on("beforeshow",this.beforeMenuShow,this)}},renderRows:function(){var a=this.getGroupField();var e=!!a;if(this.hideGroupedColumn){var b=this.cm.findColumnIndex(a),d=Ext.isDefined(this.lastGroupField);if(!e&&d){this.mainBody.update("");this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField),false);delete this.lastGroupField}else{if(e&&!d){this.lastGroupField=a;this.cm.setHidden(b,true)}else{if(e&&d&&a!==this.lastGroupField){this.mainBody.update("");var c=this.cm.findColumnIndex(this.lastGroupField);this.cm.setHidden(c,false);this.lastGroupField=a;this.cm.setHidden(b,true)}}}}return Ext.grid.GroupingView.superclass.renderRows.apply(this,arguments)},doRender:function(c,h,q,a,p,s){if(h.length<1){return""}if(!this.canGroup()||this.isUpdating){return Ext.grid.GroupingView.superclass.doRender.apply(this,arguments)}var z=this.getGroupField(),o=this.cm.findColumnIndex(z),w,j="width:"+this.getTotalWidth()+";",e=this.cm.config[o],b=e.groupRenderer||e.renderer,t=this.showGroupName?(e.groupName||e.header)+": ":"",y=[],l,u,v,n;for(u=0,v=h.length;u<v;u++){var k=a+u,m=h[u],d=m.data[z];w=this.getGroup(d,m,b,k,o,q);if(!l||l.group!=w){n=this.constructId(d,z,o);this.state[n]=!(Ext.isDefined(this.state[n])?!this.state[n]:this.startCollapsed);l={group:w,gvalue:d,text:t+w,groupId:n,startRow:k,rs:[m],cls:this.state[n]?"":"x-grid-group-collapsed",style:j};y.push(l)}else{l.rs.push(m)}m._groupId=n}var x=[];for(u=0,v=y.length;u<v;u++){w=y[u];this.doGroupStart(x,w,c,q,p);x[x.length]=Ext.grid.GroupingView.superclass.doRender.call(this,c,w.rs,q,w.startRow,p,s);this.doGroupEnd(x,w,c,q,p)}return x.join("")},getGroupId:function(a){var b=this.getGroupField();return this.constructId(a,b,this.cm.findColumnIndex(b))},constructId:function(c,e,a){var b=this.cm.config[a],d=b.groupRenderer||b.renderer,g=(this.groupMode=="value")?c:this.getGroup(c,{data:{}},d,0,a,this.ds);return this.getPrefix(e)+Ext.util.Format.htmlEncode(g)},canGroup:function(){return this.enableGrouping&&!!this.getGroupField()},getPrefix:function(a){return this.grid.getGridEl().id+"-gp-"+a+"-"},doGroupStart:function(a,d,b,e,c){a[a.length]=this.startGroup.apply(d)},doGroupEnd:function(a,d,b,e,c){a[a.length]=this.endGroup},getRows:function(){if(!this.canGroup()){return Ext.grid.GroupingView.superclass.getRows.call(this)}var k=[],c=this.getGroups(),h,e=0,a=c.length,d,b;for(;e<a;++e){h=c[e].childNodes[1];if(h){h=h.childNodes;for(d=0,b=h.length;d<b;++d){k[k.length]=h[d]}}}return k},updateGroupWidths:function(){if(!this.canGroup()||!this.hasRows()){return}var c=Math.max(this.cm.getTotalWidth(),this.el.dom.offsetWidth-this.getScrollOffset())+"px";var b=this.getGroups();for(var d=0,a=b.length;d<a;d++){b[d].firstChild.style.width=c}},onColumnWidthUpdated:function(c,a,b){Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this,c,a,b);this.updateGroupWidths()},onAllColumnWidthsUpdated:function(a,b){Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this,a,b);this.updateGroupWidths()},onColumnHiddenUpdated:function(b,c,a){Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this,b,c,a);this.updateGroupWidths()},onLayout:function(){this.updateGroupWidths()},onBeforeRowSelect:function(b,a){this.toggleRowIndex(a,true)}});Ext.grid.GroupingView.GROUP_ID=1000; \ No newline at end of file
diff --git a/deluge/ui/web/js/extjs/ext-base-debug.js b/deluge/ui/web/js/extjs/ext-base-debug.js
new file mode 100644
index 0000000..7b20934
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-base-debug.js
@@ -0,0 +1,3352 @@
+/*
+This file is part of Ext JS 3.4
+
+Copyright (c) 2011-2013 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as
+published by the Free Software Foundation and appearing in the file LICENSE included in the
+packaging of this file.
+
+Please review the following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department
+at http://www.sencha.com/contact.
+
+Build date: 2013-04-03 15:07:25
+*/
+// for old browsers
+window.undefined = window.undefined;
+
+/**
+ * @class Ext
+ * Ext core utilities and functions.
+ * @singleton
+ */
+
+Ext = {
+ /**
+ * The version of the framework
+ * @type String
+ */
+ version : '3.4.1.1',
+ versionDetail : {
+ major : 3,
+ minor : 4,
+ patch : 1.1
+ }
+};
+
+/**
+ * Copies all the properties of config to obj.
+ * @param {Object} obj The receiver of the properties
+ * @param {Object} config The source of the properties
+ * @param {Object} defaults A different object that will also be applied for default values
+ * @return {Object} returns obj
+ * @member Ext apply
+ */
+Ext.apply = function(o, c, defaults){
+ // no "this" reference for friendly out of scope calls
+ if(defaults){
+ Ext.apply(o, defaults);
+ }
+ if(o && c && typeof c == 'object'){
+ for(var p in c){
+ o[p] = c[p];
+ }
+ }
+ return o;
+};
+
+(function(){
+ var idSeed = 0,
+ toString = Object.prototype.toString,
+ ua = navigator.userAgent.toLowerCase(),
+ check = function(r){
+ return r.test(ua);
+ },
+ DOC = document,
+ docMode = DOC.documentMode,
+ isStrict = DOC.compatMode == "CSS1Compat",
+ isOpera = check(/opera/),
+ isChrome = check(/\bchrome\b/),
+ isWebKit = check(/webkit/),
+ isSafari = !isChrome && check(/safari/),
+ isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2
+ isSafari3 = isSafari && check(/version\/3/),
+ isSafari4 = isSafari && check(/version\/4/),
+ isIE = !isOpera && check(/msie/),
+ isIE7 = isIE && ((check(/msie 7/) && docMode != 8 && docMode != 9 && docMode != 10) || docMode == 7),
+ isIE8 = isIE && ((check(/msie 8/) && docMode != 7 && docMode != 9 && docMode != 10) || docMode == 8),
+ isIE9 = isIE && ((check(/msie 9/) && docMode != 7 && docMode != 8 && docMode != 10) || docMode == 9),
+ isIE10 = isIE && ((check(/msie 10/) && docMode != 7 && docMode != 8 && docMode != 9) || docMode == 10),
+ isIE6 = isIE && check(/msie 6/),
+ isIE9m = isIE && (isIE6 || isIE7 || isIE8 || isIE9),
+ isGecko = !isWebKit && check(/gecko/),
+ isGecko2 = isGecko && check(/rv:1\.8/),
+ isGecko3 = isGecko && check(/rv:1\.9/),
+ isBorderBox = isIE9m && !isStrict,
+ isWindows = check(/windows|win32/),
+ isMac = check(/macintosh|mac os x/),
+ isAir = check(/adobeair/),
+ isLinux = check(/linux/),
+ isSecure = /^https/i.test(window.location.protocol),
+ noArgs = [],
+ nonEnumerables = [],
+ emptyFn = Ext.emptyFn,
+ t = Ext.apply({}, {
+ constructor: emptyFn,
+ toString: emptyFn,
+ valueOf: emptyFn
+ }),
+ callOverrideParent = function () {
+ var method = callOverrideParent.caller.caller; // skip callParent (our caller)
+ return method.$owner.prototype[method.$name].apply(this, arguments);
+ };
+
+ if (t.constructor !== emptyFn) {
+ nonEnumerables.push('constructor');
+ }
+ if (t.toString !== emptyFn) {
+ nonEnumerables.push('toString');
+ }
+ if (t.valueOf !== emptyFn) {
+ nonEnumerables.push('valueOf');
+ }
+ if (!nonEnumerables.length) {
+ nonEnumerables = null;
+ }
+
+ // Create the abstract Base class to provide an empty constructor and callParent implementations
+ function Base () {
+ //
+ }
+
+ Ext.apply(Base, {
+ $isClass: true,
+
+ callParent: function (args) {
+ var method;
+
+ // This code is intentionally inlined for the least number of debugger stepping
+ return (method = this.callParent.caller) && (method.$previous ||
+ ((method = method.$owner ? method : method.caller) &&
+ method.$owner.superclass.self[method.$name])).apply(this, args || noArgs);
+ }
+ });
+
+ Base.prototype = {
+ constructor: function() {
+ },
+ callParent: function(args) {
+ // NOTE: this code is deliberately as few expressions (and no function calls)
+ // as possible so that a debugger can skip over this noise with the minimum number
+ // of steps. Basically, just hit Step Into until you are where you really wanted
+ // to be.
+ var method,
+ superMethod = (method = this.callParent.caller) && (method.$previous ||
+ ((method = method.$owner ? method : method.caller) &&
+ method.$owner.superclass[method.$name]));
+
+ return superMethod.apply(this, args || noArgs);
+ }
+ };
+
+ // remove css image flicker
+ if(isIE6){
+ try{
+ DOC.execCommand("BackgroundImageCache", false, true);
+ }catch(e){}
+ }
+
+ Ext.apply(Ext, {
+ /**
+ * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
+ * the IE insecure content warning (<tt>'about:blank'</tt>, except for IE in secure mode, which is <tt>'javascript:""'</tt>).
+ * @type String
+ */
+ SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
+ /**
+ * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
+ * @type Boolean
+ */
+ isStrict : isStrict,
+ /**
+ * True if the page is running over SSL
+ * @type Boolean
+ */
+ isSecure : isSecure,
+ /**
+ * True when the document is fully initialized and ready for action
+ * @type Boolean
+ */
+ isReady : false,
+
+ /**
+ * True if the {@link Ext.Fx} Class is available
+ * @type Boolean
+ * @property enableFx
+ */
+
+ /**
+ * HIGHLY EXPERIMENTAL
+ * True to force css based border-box model override and turning off javascript based adjustments. This is a
+ * runtime configuration and must be set before onReady.
+ * @type Boolean
+ */
+ enableForcedBoxModel : false,
+
+ /**
+ * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
+ * @type Boolean
+ */
+ enableGarbageCollector : true,
+
+ /**
+ * True to automatically purge event listeners during garbageCollection (defaults to false).
+ * @type Boolean
+ */
+ enableListenerCollection : false,
+
+ /**
+ * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed.
+ * Currently not optimized for performance.
+ * @type Boolean
+ */
+ enableNestedListenerRemoval : false,
+
+ /**
+ * Indicates whether to use native browser parsing for JSON methods.
+ * This option is ignored if the browser does not support native JSON methods.
+ * <b>Note: Native JSON methods will not work with objects that have functions.
+ * Also, property names must be quoted, otherwise the data will not parse.</b> (Defaults to false)
+ * @type Boolean
+ */
+ USE_NATIVE_JSON : false,
+
+ /**
+ * Copies all the properties of config to obj if they don't already exist.
+ * @param {Object} obj The receiver of the properties
+ * @param {Object} config The source of the properties
+ * @return {Object} returns obj
+ */
+ applyIf : function(o, c){
+ if(o){
+ for(var p in c){
+ if(!Ext.isDefined(o[p])){
+ o[p] = c[p];
+ }
+ }
+ }
+ return o;
+ },
+
+ /**
+ * Generates unique ids. If the element already has an id, it is unchanged
+ * @param {Mixed} el (optional) The element to generate an id for
+ * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
+ * @return {String} The generated Id.
+ */
+ id : function(el, prefix){
+ el = Ext.getDom(el, true) || {};
+ if (!el.id) {
+ el.id = (prefix || "ext-gen") + (++idSeed);
+ }
+ return el.id;
+ },
+
+ /**
+ * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method
+ * also adds the function "override()" to the subclass that can be used to override members of the class.</p>
+ * For example, to create a subclass of Ext GridPanel:
+ * <pre><code>
+MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
+ constructor: function(config) {
+
+// Create configuration for this Grid.
+ var store = new Ext.data.Store({...});
+ var colModel = new Ext.grid.ColumnModel({...});
+
+// Create a new config object containing our computed properties
+// *plus* whatever was in the config parameter.
+ config = Ext.apply({
+ store: store,
+ colModel: colModel
+ }, config);
+
+ MyGridPanel.superclass.constructor.call(this, config);
+
+// Your postprocessing here
+ },
+
+ yourMethod: function() {
+ // etc.
+ }
+});
+</code></pre>
+ *
+ * <p>This function also supports a 3-argument call in which the subclass's constructor is
+ * passed as an argument. In this form, the parameters are as follows:</p>
+ * <div class="mdetail-params"><ul>
+ * <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li>
+ * <li><code>superclass</code> : Function <div class="sub-desc">The constructor of class being extended</div></li>
+ * <li><code>overrides</code> : Object <div class="sub-desc">A literal with members which are copied into the subclass's
+ * prototype, and are therefore shared among all instances of the new class.</div></li>
+ * </ul></div>
+ *
+ * @param {Function} superclass The constructor of class being extended.
+ * @param {Object} overrides <p>A literal with members which are copied into the subclass's
+ * prototype, and are therefore shared between all instances of the new class.</p>
+ * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used
+ * to define the constructor of the new class, and is returned. If this property is
+ * <i>not</i> specified, a constructor is generated and returned which just calls the
+ * superclass's constructor passing on its parameters.</p>
+ * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p>
+ * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided.
+ */
+ extend : function(){
+ // inline overrides
+ var io = function(o){
+ for(var m in o){
+ this[m] = o[m];
+ }
+ };
+ var oc = Object.prototype.constructor;
+
+ return function(sb, sp, overrides){
+ if(typeof sp == 'object'){
+ overrides = sp;
+ sp = sb;
+ sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
+ }
+ var F = function(){},
+ sbp,
+ spp = sp.prototype;
+
+ F.prototype = spp;
+ sbp = sb.prototype = new F();
+ sbp.constructor=sb;
+ sb.superclass=spp;
+ if(spp.constructor == oc){
+ spp.constructor=sp;
+ }
+ sb.override = function(o){
+ Ext.override(sb, o);
+ };
+ sbp.superclass = sbp.supr = (function(){
+ return spp;
+ });
+ sbp.override = io;
+ Ext.override(sb, overrides);
+ sb.extend = function(o){return Ext.extend(sb, o);};
+ return sb;
+ };
+ }(),
+
+ global: (function () {
+ return this;
+ })(),
+
+ Base: Base,
+
+ namespaceCache: {},
+
+ createNamespace: function (namespaceOrClass, isClass) {
+ var cache = Ext.namespaceCache,
+ namespace = isClass ? namespaceOrClass.substring(0, namespaceOrClass.lastIndexOf('.'))
+ : namespaceOrClass,
+ ns = cache[namespace],
+ i, n, part, parts, partials;
+
+ if (!ns) {
+ ns = Ext.global;
+ if (namespace) {
+ partials = [];
+ parts = namespace.split('.');
+
+ for (i = 0, n = parts.length; i < n; ++i) {
+ part = parts[i];
+
+ ns = ns[part] || (ns[part] = {});
+ partials.push(part);
+
+ cache[partials.join('.')] = ns; // build up prefixes as we go
+ }
+ }
+ }
+
+ return ns;
+ },
+
+ getClassByName: function (className) {
+ var parts = className.split('.'),
+ cls = Ext.global,
+ n = parts.length,
+ i;
+
+ for (i = 0; cls && i < n; ++i) {
+ cls = cls[parts[i]];
+ }
+
+ return cls || null;
+ },
+
+ addMembers: function (cls, target, members, handleNonEnumerables) {
+ var i, name, member;
+
+ for (name in members) {
+ if (members.hasOwnProperty(name)) {
+ member = members[name];
+ if (typeof member == 'function') {
+ member.$owner = cls;
+ member.$name = name;
+ }
+
+ target[name] = member;
+ }
+ }
+
+ if (handleNonEnumerables && nonEnumerables) {
+ for (i = nonEnumerables.length; i-- > 0; ) {
+ name = nonEnumerables[i];
+ if (members.hasOwnProperty(name)) {
+ member = members[name];
+ if (typeof member == 'function') {
+ member.$owner = cls;
+ member.$name = name;
+ }
+
+ target[name] = member;
+ }
+ }
+ }
+ },
+
+ /**
+ * @method
+ * Defines a class or override. A basic class is defined like this:
+ *
+ * Ext.define('My.awesome.Class', {
+ * someProperty: 'something',
+ *
+ * someMethod: function(s) {
+ * alert(s + this.someProperty);
+ * }
+ *
+ * ...
+ * });
+ *
+ * var obj = new My.awesome.Class();
+ *
+ * obj.someMethod('Say '); // alerts 'Say something'
+ *
+ * To create an anonymous class, pass `null` for the `className`:
+ *
+ * Ext.define(null, {
+ * constructor: function () {
+ * // ...
+ * }
+ * });
+ *
+ * In some cases, it is helpful to create a nested scope to contain some private
+ * properties. The best way to do this is to pass a function instead of an object
+ * as the second parameter. This function will be called to produce the class
+ * body:
+ *
+ * Ext.define('MyApp.foo.Bar', function () {
+ * var id = 0;
+ *
+ * return {
+ * nextId: function () {
+ * return ++id;
+ * }
+ * };
+ * });
+ *
+ * When using this form of `Ext.define`, the function is passed a reference to its
+ * class. This can be used as an efficient way to access any static properties you
+ * may have:
+ *
+ * Ext.define('MyApp.foo.Bar', function (Bar) {
+ * return {
+ * statics: {
+ * staticMethod: function () {
+ * // ...
+ * }
+ * },
+ *
+ * method: function () {
+ * return Bar.staticMethod();
+ * }
+ * };
+ * });
+ *
+ * To define an override, include the `override` property. The content of an
+ * override is aggregated with the specified class in order to extend or modify
+ * that class. This can be as simple as setting default property values or it can
+ * extend and/or replace methods. This can also extend the statics of the class.
+ *
+ * One use for an override is to break a large class into manageable pieces.
+ *
+ * // File: /src/app/Panel.js
+ *
+ * Ext.define('My.app.Panel', {
+ * extend: 'Ext.panel.Panel',
+ *
+ * constructor: function (config) {
+ * this.callParent(arguments); // calls Ext.panel.Panel's constructor
+ * //...
+ * },
+ *
+ * statics: {
+ * method: function () {
+ * return 'abc';
+ * }
+ * }
+ * });
+ *
+ * // File: /src/app/PanelPart2.js
+ * Ext.define('My.app.PanelPart2', {
+ * override: 'My.app.Panel',
+ *
+ * constructor: function (config) {
+ * this.callParent(arguments); // calls My.app.Panel's constructor
+ * //...
+ * }
+ * });
+ *
+ * Another use of overrides is to provide optional parts of classes that can be
+ * independently required. In this case, the class may even be unaware of the
+ * override altogether.
+ *
+ * Ext.define('My.ux.CoolTip', {
+ * override: 'Ext.tip.ToolTip',
+ *
+ * constructor: function (config) {
+ * this.callParent(arguments); // calls Ext.tip.ToolTip's constructor
+ * //...
+ * }
+ * });
+ *
+ * Overrides can also contain statics:
+ *
+ * Ext.define('My.app.BarMod', {
+ * override: 'Ext.foo.Bar',
+ *
+ * statics: {
+ * method: function (x) {
+ * return this.callParent([x * 2]); // call Ext.foo.Bar.method
+ * }
+ * }
+ * });
+ *
+ * @param {String} className The class name to create in string dot-namespaced format, for example:
+ * 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'
+ * It is highly recommended to follow this simple convention:
+ * - The root and the class name are 'CamelCased'
+ * - Everything else is lower-cased
+ * Pass `null` to create an anonymous class.
+ * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid
+ * strings, except those in the reserved listed below:
+ * - `mixins`
+ * - `statics`
+ * - `config`
+ * - `alias`
+ * - `self`
+ * - `singleton`
+ * - `alternateClassName`
+ * - `override`
+ *
+ * @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which
+ * (`this`) will be the newly created class itself.
+ * @return {Ext.Base}
+ * @markdown
+ * @member Ext
+ * @method define
+ */
+ define: function (className, body, createdFn) {
+ var override = body.override,
+ cls, extend, name, namespace;
+
+ if (override) {
+ delete body.override;
+ cls = Ext.getClassByName(override);
+ Ext.override(cls, body);
+ } else {
+ if (className) {
+ namespace = Ext.createNamespace(className, true);
+ name = className.substring(className.lastIndexOf('.')+1);
+ }
+
+ cls = function ctor () {
+ this.constructor.apply(this, arguments);
+ }
+
+ if (className) {
+ cls.displayName = className;
+ }
+ cls.$isClass = true;
+ cls.callParent = Ext.Base.callParent;
+
+ if (typeof body == 'function') {
+ body = body(cls);
+ }
+
+ extend = body.extend;
+ if (extend) {
+ delete body.extend;
+ if (typeof extend == 'string') {
+ extend = Ext.getClassByName(extend);
+ }
+ } else {
+ extend = Base;
+ }
+
+ Ext.extend(cls, extend, body);
+ if (cls.prototype.constructor === cls) {
+ delete cls.prototype.constructor;
+ }
+
+ // Not extending a class which derives from Base...
+ if (!cls.prototype.$isClass) {
+ Ext.applyIf(cls.prototype, Base.prototype);
+ }
+ cls.prototype.self = cls;
+
+ if (body.xtype) {
+ Ext.reg(body.xtype, cls);
+ }
+ cls = body.singleton ? new cls() : cls;
+ if (className) {
+ namespace[name] = cls;
+ }
+ }
+
+ if (createdFn) {
+ createdFn.call(cls);
+ }
+
+ return cls;
+ },
+
+ /**
+ * Overrides members of the specified `target` with the given values.
+ *
+ * If the `target` is a function, it is assumed to be a constructor and the contents
+ * of `overrides` are applied to its `prototype` using {@link Ext#apply Ext.apply}.
+ *
+ * If the `target` is an instance of a class created using {@link #define},
+ * the `overrides` are applied to only that instance. In this case, methods are
+ * specially processed to allow them to use {@link Ext.Base#callParent}.
+ *
+ * var panel = new Ext.Panel({ ... });
+ *
+ * Ext.override(panel, {
+ * initComponent: function () {
+ * // extra processing...
+ *
+ * this.callParent();
+ * }
+ * });
+ *
+ * If the `target` is none of these, the `overrides` are applied to the `target`
+ * using {@link Ext#apply Ext.apply}.
+ *
+ * Please refer to {@link Ext#define Ext.define} for further details.
+ *
+ * @param {Object} target The target to override.
+ * @param {Object} overrides The properties to add or replace on `target`.
+ * @method override
+ */
+ override: function (target, overrides) {
+ var proto, statics;
+
+ if (overrides) {
+ if (target.$isClass) {
+ statics = overrides.statics;
+ if (statics) {
+ delete overrides.statics;
+ }
+
+ Ext.addMembers(target, target.prototype, overrides, true);
+ if (statics) {
+ Ext.addMembers(target, target, statics);
+ }
+ } else if (typeof target == 'function') {
+ proto = target.prototype;
+ Ext.apply(proto, overrides);
+ if(Ext.isIE && overrides.hasOwnProperty('toString')){
+ proto.toString = overrides.toString;
+ }
+ } else {
+ var owner = target.self,
+ name, value;
+
+ if (owner && owner.$isClass) {
+ for (name in overrides) {
+ if (overrides.hasOwnProperty(name)) {
+ value = overrides[name];
+
+ if (typeof value == 'function') {
+ //<debug>
+ if (owner.$className) {
+ value.displayName = owner.$className + '#' + name;
+ }
+ //</debug>
+
+ value.$name = name;
+ value.$owner = owner;
+ value.$previous = target.hasOwnProperty(name)
+ ? target[name] // already hooked, so call previous hook
+ : callOverrideParent; // calls by name on prototype
+ }
+
+ target[name] = value;
+ }
+ }
+ } else {
+ Ext.apply(target, overrides);
+
+ if (!target.constructor.$isClass) {
+ target.constructor.prototype.callParent = Base.prototype.callParent;
+ target.constructor.callParent = Base.callParent;
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Creates namespaces to be used for scoping variables and classes so that they are not global.
+ * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
+ * <pre><code>
+Ext.namespace('Company', 'Company.data');
+Ext.namespace('Company.data'); // equivalent and preferable to above syntax
+Company.Widget = function() { ... }
+Company.data.CustomStore = function(config) { ... }
+</code></pre>
+ * @param {String} namespace1
+ * @param {String} namespace2
+ * @param {String} etc
+ * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
+ * @method namespace
+ */
+ namespace : function(){
+ var len1 = arguments.length,
+ i = 0,
+ len2,
+ j,
+ main,
+ ns,
+ sub,
+ current;
+
+ for(; i < len1; ++i) {
+ main = arguments[i];
+ ns = arguments[i].split('.');
+ current = window[ns[0]];
+ if (current === undefined) {
+ current = window[ns[0]] = {};
+ }
+ sub = ns.slice(1);
+ len2 = sub.length;
+ for(j = 0; j < len2; ++j) {
+ current = current[sub[j]] = current[sub[j]] || {};
+ }
+ }
+ return current;
+ },
+
+ /**
+ * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
+ * @param {Object} o
+ * @param {String} pre (optional) A prefix to add to the url encoded string
+ * @return {String}
+ */
+ urlEncode : function(o, pre){
+ var empty,
+ buf = [],
+ e = encodeURIComponent;
+
+ Ext.iterate(o, function(key, item){
+ empty = Ext.isEmpty(item);
+ Ext.each(empty ? key : item, function(val){
+ buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : '');
+ });
+ });
+ if(!pre){
+ buf.shift();
+ pre = '';
+ }
+ return pre + buf.join('');
+ },
+
+ /**
+ * Takes an encoded URL and and converts it to an object. Example: <pre><code>
+Ext.urlDecode("foo=1&bar=2"); // returns {foo: "1", bar: "2"}
+Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); // returns {foo: "1", bar: ["2", "3", "4"]}
+</code></pre>
+ * @param {String} string
+ * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
+ * @return {Object} A literal with members
+ */
+ urlDecode : function(string, overwrite){
+ if(Ext.isEmpty(string)){
+ return {};
+ }
+ var obj = {},
+ pairs = string.split('&'),
+ d = decodeURIComponent,
+ name,
+ value;
+ Ext.each(pairs, function(pair) {
+ pair = pair.split('=');
+ name = d(pair[0]);
+ value = d(pair[1]);
+ obj[name] = overwrite || !obj[name] ? value :
+ [].concat(obj[name]).concat(value);
+ });
+ return obj;
+ },
+
+ /**
+ * Appends content to the query string of a URL, handling logic for whether to place
+ * a question mark or ampersand.
+ * @param {String} url The URL to append to.
+ * @param {String} s The content to append to the URL.
+ * @return (String) The resulting URL
+ */
+ urlAppend : function(url, s){
+ if(!Ext.isEmpty(s)){
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
+ }
+ return url;
+ },
+
+ /**
+ * Converts any iterable (numeric indices and a length property) into a true array
+ * Don't use this on strings. IE doesn't support "abc"[0] which this implementation depends on.
+ * For strings, use this instead: "abc".match(/./g) => [a,b,c];
+ * @param {Iterable} the iterable object to be turned into a true Array.
+ * @return (Array) array
+ */
+ toArray : function(){
+ return isIE ?
+ function(a, i, j, res){
+ res = [];
+ for(var x = 0, len = a.length; x < len; x++) {
+ res.push(a[x]);
+ }
+ return res.slice(i || 0, j || res.length);
+ } :
+ function(a, i, j){
+ return Array.prototype.slice.call(a, i || 0, j || a.length);
+ };
+ }(),
+
+ isIterable : function(v){
+ //check for array or arguments
+ if(Ext.isArray(v) || v.callee){
+ return true;
+ }
+ //check for node list type
+ if(/NodeList|HTMLCollection/.test(toString.call(v))){
+ return true;
+ }
+ //NodeList has an item and length property
+ //IXMLDOMNodeList has nextNode method, needs to be checked first.
+ return ((typeof v.nextNode != 'undefined' || v.item) && Ext.isNumber(v.length));
+ },
+
+ /**
+ * Iterates an array calling the supplied function.
+ * @param {Array/NodeList/Mixed} array The array to be iterated. If this
+ * argument is not really an array, the supplied function is called once.
+ * @param {Function} fn The function to be called with each item. If the
+ * supplied function returns false, iteration stops and this method returns
+ * the current <code>index</code>. This function is called with
+ * the following arguments:
+ * <div class="mdetail-params"><ul>
+ * <li><code>item</code> : <i>Mixed</i>
+ * <div class="sub-desc">The item at the current <code>index</code>
+ * in the passed <code>array</code></div></li>
+ * <li><code>index</code> : <i>Number</i>
+ * <div class="sub-desc">The current index within the array</div></li>
+ * <li><code>allItems</code> : <i>Array</i>
+ * <div class="sub-desc">The <code>array</code> passed as the first
+ * argument to <code>Ext.each</code>.</div></li>
+ * </ul></div>
+ * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed.
+ * Defaults to the <code>item</code> at the current <code>index</code>
+ * within the passed <code>array</code>.
+ * @return See description for the fn parameter.
+ */
+ each : function(array, fn, scope){
+ if(Ext.isEmpty(array, true)){
+ return;
+ }
+ if(!Ext.isIterable(array) || Ext.isPrimitive(array)){
+ array = [array];
+ }
+ for(var i = 0, len = array.length; i < len; i++){
+ if(fn.call(scope || array[i], array[i], i, array) === false){
+ return i;
+ };
+ }
+ },
+
+ /**
+ * Iterates either the elements in an array, or each of the properties in an object.
+ * <b>Note</b>: If you are only iterating arrays, it is better to call {@link #each}.
+ * @param {Object/Array} object The object or array to be iterated
+ * @param {Function} fn The function to be called for each iteration.
+ * The iteration will stop if the supplied function returns false, or
+ * all array elements / object properties have been covered. The signature
+ * varies depending on the type of object being interated:
+ * <div class="mdetail-params"><ul>
+ * <li>Arrays : <tt>(Object item, Number index, Array allItems)</tt>
+ * <div class="sub-desc">
+ * When iterating an array, the supplied function is called with each item.</div></li>
+ * <li>Objects : <tt>(String key, Object value, Object)</tt>
+ * <div class="sub-desc">
+ * When iterating an object, the supplied function is called with each key-value pair in
+ * the object, and the iterated object</div></li>
+ * </ul></div>
+ * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to
+ * the <code>object</code> being iterated.
+ */
+ iterate : function(obj, fn, scope){
+ if(Ext.isEmpty(obj)){
+ return;
+ }
+ if(Ext.isIterable(obj)){
+ Ext.each(obj, fn, scope);
+ return;
+ }else if(typeof obj == 'object'){
+ for(var prop in obj){
+ if(obj.hasOwnProperty(prop)){
+ if(fn.call(scope || obj, prop, obj[prop], obj) === false){
+ return;
+ };
+ }
+ }
+ }
+ },
+
+ /**
+ * Return the dom node for the passed String (id), dom node, or Ext.Element.
+ * Optional 'strict' flag is needed for IE since it can return 'name' and
+ * 'id' elements by using getElementById.
+ * Here are some examples:
+ * <pre><code>
+// gets dom node based on id
+var elDom = Ext.getDom('elId');
+// gets dom node based on the dom node
+var elDom1 = Ext.getDom(elDom);
+
+// If we don&#39;t know if we are working with an
+// Ext.Element or a dom node use Ext.getDom
+function(el){
+ var dom = Ext.getDom(el);
+ // do something with the dom node
+}
+ * </code></pre>
+ * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc)
+ * when this method is called to be successful.
+ * @param {Mixed} el
+ * @return HTMLElement
+ */
+ getDom : function(el, strict){
+ if(!el || !DOC){
+ return null;
+ }
+ if (el.dom){
+ return el.dom;
+ } else {
+ if (typeof el == 'string') {
+ var e = DOC.getElementById(el);
+ // IE returns elements with the 'name' and 'id' attribute.
+ // we do a strict check to return the element with only the id attribute
+ if (e && isIE && strict) {
+ if (el == e.getAttribute('id')) {
+ return e;
+ } else {
+ return null;
+ }
+ }
+ return e;
+ } else {
+ return el;
+ }
+ }
+ },
+
+ /**
+ * Returns the current document body as an {@link Ext.Element}.
+ * @return Ext.Element The document body
+ */
+ getBody : function(){
+ return Ext.get(DOC.body || DOC.documentElement);
+ },
+
+ /**
+ * Returns the current document body as an {@link Ext.Element}.
+ * @return Ext.Element The document body
+ * @method
+ */
+ getHead : function() {
+ var head;
+
+ return function() {
+ if (head == undefined) {
+ head = Ext.get(DOC.getElementsByTagName("head")[0]);
+ }
+
+ return head;
+ };
+ }(),
+
+ /**
+ * <p>Removes this element from the document, removes all DOM event listeners, and deletes the cache reference.
+ * All DOM event listeners are removed from this element. If {@link Ext#enableNestedListenerRemoval} is
+ * <code>true</code>, then DOM event listeners are also removed from all child nodes. The body node
+ * will be ignored if passed in.</p>
+ * @param {HTMLElement} node The node to remove
+ * @method
+ */
+ removeNode : isIE && !isIE8 ? function(){
+ var d;
+ return function(n){
+ if(n && n.tagName != 'BODY'){
+ (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
+ d = d || DOC.createElement('div');
+ d.appendChild(n);
+ d.innerHTML = '';
+ delete Ext.elCache[n.id];
+ }
+ };
+ }() : function(n){
+ if(n && n.parentNode && n.tagName != 'BODY'){
+ (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
+ n.parentNode.removeChild(n);
+ delete Ext.elCache[n.id];
+ }
+ },
+
+ /**
+ * <p>Returns true if the passed value is empty.</p>
+ * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
+ * <li>null</li>
+ * <li>undefined</li>
+ * <li>an empty array</li>
+ * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
+ * </ul></div>
+ * @param {Mixed} value The value to test
+ * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
+ * @return {Boolean}
+ */
+ isEmpty : function(v, allowBlank){
+ return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
+ },
+
+ /**
+ * Returns true if the passed value is a JavaScript array, otherwise false.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isArray : function(v){
+ return toString.apply(v) === '[object Array]';
+ },
+
+ /**
+ * Returns true if the passed object is a JavaScript date object, otherwise false.
+ * @param {Object} object The object to test
+ * @return {Boolean}
+ */
+ isDate : function(v){
+ return toString.apply(v) === '[object Date]';
+ },
+
+ /**
+ * Returns true if the passed value is a JavaScript Object, otherwise false.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isObject : function(v){
+ return !!v && Object.prototype.toString.call(v) === '[object Object]';
+ },
+
+ /**
+ * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isPrimitive : function(v){
+ return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
+ },
+
+ /**
+ * Returns true if the passed value is a JavaScript Function, otherwise false.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isFunction : function(v){
+ return toString.apply(v) === '[object Function]';
+ },
+
+ /**
+ * Returns true if the passed value is a number. Returns false for non-finite numbers.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isNumber : function(v){
+ return typeof v === 'number' && isFinite(v);
+ },
+
+ /**
+ * Returns true if the passed value is a string.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isString : function(v){
+ return typeof v === 'string';
+ },
+
+ /**
+ * Returns true if the passed value is a boolean.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isBoolean : function(v){
+ return typeof v === 'boolean';
+ },
+
+ /**
+ * Returns true if the passed value is an HTMLElement
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isElement : function(v) {
+ return v ? !!v.tagName : false;
+ },
+
+ /**
+ * Returns true if the passed value is not undefined.
+ * @param {Mixed} value The value to test
+ * @return {Boolean}
+ */
+ isDefined : function(v){
+ return typeof v !== 'undefined';
+ },
+
+ /**
+ * True if the detected browser is Opera.
+ * @type Boolean
+ */
+ isOpera : isOpera,
+ /**
+ * True if the detected browser uses WebKit.
+ * @type Boolean
+ */
+ isWebKit : isWebKit,
+ /**
+ * True if the detected browser is Chrome.
+ * @type Boolean
+ */
+ isChrome : isChrome,
+ /**
+ * True if the detected browser is Safari.
+ * @type Boolean
+ */
+ isSafari : isSafari,
+ /**
+ * True if the detected browser is Safari 3.x.
+ * @type Boolean
+ */
+ isSafari3 : isSafari3,
+ /**
+ * True if the detected browser is Safari 4.x.
+ * @type Boolean
+ */
+ isSafari4 : isSafari4,
+ /**
+ * True if the detected browser is Safari 2.x.
+ * @type Boolean
+ */
+ isSafari2 : isSafari2,
+ /**
+ * True if the detected browser is Internet Explorer.
+ * @type Boolean
+ */
+ isIE : isIE,
+ /**
+ * True if the detected browser is Internet Explorer 6.x.
+ * @type Boolean
+ */
+ isIE6 : isIE6,
+ /**
+ * True if the detected browser is Internet Explorer 7.x.
+ * @type Boolean
+ */
+ isIE7 : isIE7,
+ /**
+ * True if the detected browser is Internet Explorer 8.x.
+ * @type Boolean
+ */
+ isIE8 : isIE8,
+ /**
+ * True if the detected browser is Internet Explorer 9.x.
+ * @type Boolean
+ */
+ isIE9 : isIE9,
+
+ /**
+ * True if the detected browser is Internet Explorer 10.x
+ * @type Boolean
+ */
+ isIE10 : isIE10,
+
+ /**
+ * True if the detected browser is Internet Explorer 9.x or lower
+ * @type Boolean
+ */
+ isIE9m : isIE9m,
+
+ /**
+ * True if the detected browser is Internet Explorer 10.x or higher
+ * @type Boolean
+ */
+ isIE10p : isIE && !(isIE6 || isIE7 || isIE8 || isIE9),
+
+ // IE10 quirks behaves like Gecko/WebKit quirks, so don't include it here
+ // Used internally
+ isIEQuirks: isIE && (!isStrict && (isIE6 || isIE7 || isIE8 || isIE9)),
+
+ /**
+ * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
+ * @type Boolean
+ */
+ isGecko : isGecko,
+ /**
+ * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
+ * @type Boolean
+ */
+ isGecko2 : isGecko2,
+ /**
+ * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
+ * @type Boolean
+ */
+ isGecko3 : isGecko3,
+ /**
+ * True if the detected browser is Internet Explorer running in non-strict mode.
+ * @type Boolean
+ */
+ isBorderBox : isBorderBox,
+ /**
+ * True if the detected platform is Linux.
+ * @type Boolean
+ */
+ isLinux : isLinux,
+ /**
+ * True if the detected platform is Windows.
+ * @type Boolean
+ */
+ isWindows : isWindows,
+ /**
+ * True if the detected platform is Mac OS.
+ * @type Boolean
+ */
+ isMac : isMac,
+ /**
+ * True if the detected platform is Adobe Air.
+ * @type Boolean
+ */
+ isAir : isAir
+ });
+
+ /**
+ * Creates namespaces to be used for scoping variables and classes so that they are not global.
+ * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
+ * <pre><code>
+Ext.namespace('Company', 'Company.data');
+Ext.namespace('Company.data'); // equivalent and preferable to above syntax
+Company.Widget = function() { ... }
+Company.data.CustomStore = function(config) { ... }
+</code></pre>
+ * @param {String} namespace1
+ * @param {String} namespace2
+ * @param {String} etc
+ * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
+ * @method ns
+ */
+ Ext.ns = Ext.namespace;
+})();
+
+Ext.ns('Ext.util', 'Ext.lib', 'Ext.data', 'Ext.supports');
+
+Ext.elCache = {};
+
+/**
+ * @class Function
+ * These functions are available on every Function object (any JavaScript function).
+ */
+Ext.apply(Function.prototype, {
+ /**
+ * Creates an interceptor function. The passed function is called before the original one. If it returns false,
+ * the original one is not called. The resulting function returns the results of the original function.
+ * The passed function is called with the parameters of the original function. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+sayHi('Fred'); // alerts "Hi, Fred"
+
+// create a new function that validates input without
+// directly modifying the original function:
+var sayHiToFriend = sayHi.createInterceptor(function(name){
+ return name == 'Brian';
+});
+
+sayHiToFriend('Fred'); // no alert
+sayHiToFriend('Brian'); // alerts "Hi, Brian"
+</code></pre>
+ * @param {Function} fcn The function to call before the original
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
+ * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
+ * @return {Function} The new function
+ */
+ createInterceptor : function(fcn, scope){
+ var method = this;
+ return !Ext.isFunction(fcn) ?
+ this :
+ function() {
+ var me = this,
+ args = arguments;
+ fcn.target = me;
+ fcn.method = method;
+ return (fcn.apply(scope || me || window, args) !== false) ?
+ method.apply(me || window, args) :
+ null;
+ };
+ },
+
+ /**
+ * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
+ * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
+ * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
+ * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
+ * executes in the window scope.
+ * <p>This method is required when you want to pass arguments to a callback function. If no arguments
+ * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
+ * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
+ * would simply execute immediately when the code is parsed. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+// clicking the button alerts "Hi, Fred"
+new Ext.Button({
+ text: 'Say Hi',
+ renderTo: Ext.getBody(),
+ handler: sayHi.createCallback('Fred')
+});
+</code></pre>
+ * @return {Function} The new function
+ */
+ createCallback : function(/*args...*/){
+ // make args available, in function below
+ var args = arguments,
+ method = this;
+ return function() {
+ return method.apply(window, args);
+ };
+ },
+
+ /**
+ * Creates a delegate (callback) that sets the scope to obj.
+ * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
+ * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
+ * callback points to obj. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ // Note this use of "this.text" here. This function expects to
+ // execute within a scope that contains a text property. In this
+ // example, the "this" variable is pointing to the btn object that
+ // was passed in createDelegate below.
+ alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
+}
+
+var btn = new Ext.Button({
+ text: 'Say Hi',
+ renderTo: Ext.getBody()
+});
+
+// This callback will execute in the scope of the
+// button instance. Clicking the button alerts
+// "Hi, Fred. You clicked the "Say Hi" button."
+btn.on('click', sayHi.createDelegate(btn, ['Fred']));
+</code></pre>
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Function} The new function
+ */
+ createDelegate : function(obj, args, appendArgs){
+ var method = this;
+ return function() {
+ var callArgs = args || arguments;
+ if (appendArgs === true){
+ callArgs = Array.prototype.slice.call(arguments, 0);
+ callArgs = callArgs.concat(args);
+ }else if (Ext.isNumber(appendArgs)){
+ callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
+ var applyArgs = [appendArgs, 0].concat(args); // create method call params
+ Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
+ }
+ return method.apply(obj || window, callArgs);
+ };
+ },
+
+ /**
+ * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
+ * <pre><code>
+var sayHi = function(name){
+ alert('Hi, ' + name);
+}
+
+// executes immediately:
+sayHi('Fred');
+
+// executes after 2 seconds:
+sayHi.defer(2000, this, ['Fred']);
+
+// this syntax is sometimes useful for deferring
+// execution of an anonymous function:
+(function(){
+ alert('Anonymous');
+}).defer(100);
+</code></pre>
+ * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
+ * <b>If omitted, defaults to the browser window.</b>
+ * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
+ * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
+ * if a number the args are inserted at the specified position
+ * @return {Number} The timeout id that can be used with clearTimeout
+ */
+ defer : function(millis, obj, args, appendArgs){
+ var fn = this.createDelegate(obj, args, appendArgs);
+ if(millis > 0){
+ return setTimeout(fn, millis);
+ }
+ fn();
+ return 0;
+ }
+});
+
+/**
+ * @class String
+ * These functions are available on every String object.
+ */
+Ext.applyIf(String, {
+ /**
+ * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
+ * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
+ * <pre><code>
+var cls = 'my-class', text = 'Some text';
+var s = String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
+// s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
+ * </code></pre>
+ * @param {String} string The tokenized string to be formatted
+ * @param {String} value1 The value to replace token {0}
+ * @param {String} value2 Etc...
+ * @return {String} The formatted string
+ * @static
+ */
+ format : function(format){
+ var args = Ext.toArray(arguments, 1);
+ return format.replace(/\{(\d+)\}/g, function(m, i){
+ return args[i];
+ });
+ }
+});
+
+/**
+ * @class Array
+ */
+Ext.applyIf(Array.prototype, {
+ /**
+ * Checks whether or not the specified object exists in the array.
+ * @param {Object} o The object to check for
+ * @param {Number} from (Optional) The index at which to begin the search
+ * @return {Number} The index of o in the array (or -1 if it is not found)
+ */
+ indexOf : function(o, from){
+ var len = this.length;
+ from = from || 0;
+ from += (from < 0) ? len : 0;
+ for (; from < len; ++from){
+ if(this[from] === o){
+ return from;
+ }
+ }
+ return -1;
+ },
+
+ /**
+ * Removes the specified object from the array. If the object is not found nothing happens.
+ * @param {Object} o The object to remove
+ * @return {Array} this array
+ */
+ remove : function(o){
+ var index = this.indexOf(o);
+ if(index != -1){
+ this.splice(index, 1);
+ }
+ return this;
+ }
+});
+/**
+ * @class Ext.util.TaskRunner
+ * Provides the ability to execute one or more arbitrary tasks in a multithreaded
+ * manner. Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
+ * if needed, you can create separate instances of TaskRunner. Any number of
+ * separate tasks can be started at any time and will run independently of each
+ * other. Example usage:
+ * <pre><code>
+// Start a simple clock task that updates a div once per second
+var updateClock = function(){
+ Ext.fly('clock').update(new Date().format('g:i:s A'));
+}
+var task = {
+ run: updateClock,
+ interval: 1000 //1 second
+}
+var runner = new Ext.util.TaskRunner();
+runner.start(task);
+
+// equivalent using TaskMgr
+Ext.TaskMgr.start({
+ run: updateClock,
+ interval: 1000
+});
+
+ * </code></pre>
+ * <p>See the {@link #start} method for details about how to configure a task object.</p>
+ * Also see {@link Ext.util.DelayedTask}.
+ *
+ * @constructor
+ * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
+ * (defaults to 10)
+ */
+Ext.util.TaskRunner = function(interval){
+ interval = interval || 10;
+ var tasks = [],
+ removeQueue = [],
+ id = 0,
+ running = false,
+
+ // private
+ stopThread = function(){
+ running = false;
+ clearInterval(id);
+ id = 0;
+ },
+
+ // private
+ startThread = function(){
+ if(!running){
+ running = true;
+ id = setInterval(runTasks, interval);
+ }
+ },
+
+ // private
+ removeTask = function(t){
+ removeQueue.push(t);
+ if(t.onStop){
+ t.onStop.apply(t.scope || t);
+ }
+ },
+
+ // private
+ runTasks = function(){
+ var rqLen = removeQueue.length,
+ now = new Date().getTime();
+
+ if(rqLen > 0){
+ for(var i = 0; i < rqLen; i++){
+ tasks.remove(removeQueue[i]);
+ }
+ removeQueue = [];
+ if(tasks.length < 1){
+ stopThread();
+ return;
+ }
+ }
+ for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
+ t = tasks[i];
+ itime = now - t.taskRunTime;
+ if(t.interval <= itime){
+ rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
+ t.taskRunTime = now;
+ if(rt === false || t.taskRunCount === t.repeat){
+ removeTask(t);
+ return;
+ }
+ }
+ if(t.duration && t.duration <= (now - t.taskStartTime)){
+ removeTask(t);
+ }
+ }
+ };
+
+ /**
+ * Starts a new task.
+ * @method start
+ * @param {Object} task <p>A config object that supports the following properties:<ul>
+ * <li><code>run</code> : Function<div class="sub-desc"><p>The function to execute each time the task is invoked. The
+ * function will be called at each interval and passed the <code>args</code> argument if specified, and the
+ * current invocation count if not.</p>
+ * <p>If a particular scope (<code>this</code> reference) is required, be sure to specify it using the <code>scope</code> argument.</p>
+ * <p>Return <code>false</code> from this function to terminate the task.</p></div></li>
+ * <li><code>interval</code> : Number<div class="sub-desc">The frequency in milliseconds with which the task
+ * should be invoked.</div></li>
+ * <li><code>args</code> : Array<div class="sub-desc">(optional) An array of arguments to be passed to the function
+ * specified by <code>run</code>. If not specified, the current invocation count is passed.</div></li>
+ * <li><code>scope</code> : Object<div class="sub-desc">(optional) The scope (<tt>this</tt> reference) in which to execute the
+ * <code>run</code> function. Defaults to the task config object.</div></li>
+ * <li><code>duration</code> : Number<div class="sub-desc">(optional) The length of time in milliseconds to invoke
+ * the task before stopping automatically (defaults to indefinite).</div></li>
+ * <li><code>repeat</code> : Number<div class="sub-desc">(optional) The number of times to invoke the task before
+ * stopping automatically (defaults to indefinite).</div></li>
+ * </ul></p>
+ * <p>Before each invocation, Ext injects the property <code>taskRunCount</code> into the task object so
+ * that calculations based on the repeat count can be performed.</p>
+ * @return {Object} The task
+ */
+ this.start = function(task){
+ tasks.push(task);
+ task.taskStartTime = new Date().getTime();
+ task.taskRunTime = 0;
+ task.taskRunCount = 0;
+ startThread();
+ return task;
+ };
+
+ /**
+ * Stops an existing running task.
+ * @method stop
+ * @param {Object} task The task to stop
+ * @return {Object} The task
+ */
+ this.stop = function(task){
+ removeTask(task);
+ return task;
+ };
+
+ /**
+ * Stops all tasks that are currently running.
+ * @method stopAll
+ */
+ this.stopAll = function(){
+ stopThread();
+ for(var i = 0, len = tasks.length; i < len; i++){
+ if(tasks[i].onStop){
+ tasks[i].onStop();
+ }
+ }
+ tasks = [];
+ removeQueue = [];
+ };
+};
+
+/**
+ * @class Ext.TaskMgr
+ * @extends Ext.util.TaskRunner
+ * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks. See
+ * {@link Ext.util.TaskRunner} for supported methods and task config properties.
+ * <pre><code>
+// Start a simple clock task that updates a div once per second
+var task = {
+ run: function(){
+ Ext.fly('clock').update(new Date().format('g:i:s A'));
+ },
+ interval: 1000 //1 second
+}
+Ext.TaskMgr.start(task);
+</code></pre>
+ * <p>See the {@link #start} method for details about how to configure a task object.</p>
+ * @singleton
+ */
+Ext.TaskMgr = new Ext.util.TaskRunner();(function(){
+ var libFlyweight;
+
+ function fly(el) {
+ if (!libFlyweight) {
+ libFlyweight = new Ext.Element.Flyweight();
+ }
+ libFlyweight.dom = el;
+ return libFlyweight;
+ }
+
+ (function(){
+ var doc = document,
+ isCSS1 = doc.compatMode == "CSS1Compat",
+ MAX = Math.max,
+ ROUND = Math.round,
+ PARSEINT = parseInt;
+
+ Ext.lib.Dom = {
+ isAncestor : function(p, c) {
+ var ret = false;
+
+ p = Ext.getDom(p);
+ c = Ext.getDom(c);
+ if (p && c) {
+ if (p.contains) {
+ return p.contains(c);
+ } else if (p.compareDocumentPosition) {
+ return !!(p.compareDocumentPosition(c) & 16);
+ } else {
+ while (c = c.parentNode) {
+ ret = c == p || ret;
+ }
+ }
+ }
+ return ret;
+ },
+
+ getViewWidth : function(full) {
+ return full ? this.getDocumentWidth() : this.getViewportWidth();
+ },
+
+ getViewHeight : function(full) {
+ return full ? this.getDocumentHeight() : this.getViewportHeight();
+ },
+
+ getDocumentHeight: function() {
+ return MAX(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, this.getViewportHeight());
+ },
+
+ getDocumentWidth: function() {
+ return MAX(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, this.getViewportWidth());
+ },
+
+ getViewportHeight: function(){
+ return Ext.isIE9m ?
+ (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :
+ self.innerHeight;
+ },
+
+ getViewportWidth : function() {
+ return !Ext.isStrict && !Ext.isOpera ? doc.body.clientWidth :
+ Ext.isIE9m ? doc.documentElement.clientWidth : self.innerWidth;
+ },
+
+ getY : function(el) {
+ return this.getXY(el)[1];
+ },
+
+ getX : function(el) {
+ return this.getXY(el)[0];
+ },
+
+ getXY : function(el) {
+ var p,
+ pe,
+ b,
+ bt,
+ bl,
+ dbd,
+ x = 0,
+ y = 0,
+ scroll,
+ hasAbsolute,
+ bd = (doc.body || doc.documentElement),
+ ret = [0,0];
+
+ el = Ext.getDom(el);
+
+ if(el != bd){
+ if (el.getBoundingClientRect) {
+ b = el.getBoundingClientRect();
+ scroll = fly(document).getScroll();
+ ret = [ROUND(b.left + scroll.left), ROUND(b.top + scroll.top)];
+ } else {
+ p = el;
+ hasAbsolute = fly(el).isStyle("position", "absolute");
+
+ while (p) {
+ pe = fly(p);
+ x += p.offsetLeft;
+ y += p.offsetTop;
+
+ hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");
+
+ if (Ext.isGecko) {
+ y += bt = PARSEINT(pe.getStyle("borderTopWidth"), 10) || 0;
+ x += bl = PARSEINT(pe.getStyle("borderLeftWidth"), 10) || 0;
+
+ if (p != el && !pe.isStyle('overflow','visible')) {
+ x += bl;
+ y += bt;
+ }
+ }
+ p = p.offsetParent;
+ }
+
+ if (Ext.isSafari && hasAbsolute) {
+ x -= bd.offsetLeft;
+ y -= bd.offsetTop;
+ }
+
+ if (Ext.isGecko && !hasAbsolute) {
+ dbd = fly(bd);
+ x += PARSEINT(dbd.getStyle("borderLeftWidth"), 10) || 0;
+ y += PARSEINT(dbd.getStyle("borderTopWidth"), 10) || 0;
+ }
+
+ p = el.parentNode;
+ while (p && p != bd) {
+ if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
+ x -= p.scrollLeft;
+ y -= p.scrollTop;
+ }
+ p = p.parentNode;
+ }
+ ret = [x,y];
+ }
+ }
+ return ret;
+ },
+
+ setXY : function(el, xy) {
+ (el = Ext.fly(el, '_setXY')).position();
+
+ var pts = el.translatePoints(xy),
+ style = el.dom.style,
+ pos;
+
+ for (pos in pts) {
+ if (!isNaN(pts[pos])) {
+ style[pos] = pts[pos] + "px";
+ }
+ }
+ },
+
+ setX : function(el, x) {
+ this.setXY(el, [x, false]);
+ },
+
+ setY : function(el, y) {
+ this.setXY(el, [false, y]);
+ }
+ };
+})();Ext.lib.Event = function() {
+ var loadComplete = false,
+ unloadListeners = {},
+ retryCount = 0,
+ onAvailStack = [],
+ _interval,
+ locked = false,
+ win = window,
+ doc = document,
+
+ // constants
+ POLL_RETRYS = 200,
+ POLL_INTERVAL = 20,
+ TYPE = 0,
+ FN = 1,
+ OBJ = 2,
+ ADJ_SCOPE = 3,
+ SCROLLLEFT = 'scrollLeft',
+ SCROLLTOP = 'scrollTop',
+ UNLOAD = 'unload',
+ MOUSEOVER = 'mouseover',
+ MOUSEOUT = 'mouseout',
+ // private
+ doAdd = function() {
+ var ret;
+ if (win.addEventListener) {
+ ret = function(el, eventName, fn, capture) {
+ if (eventName == 'mouseenter') {
+ fn = fn.createInterceptor(checkRelatedTarget);
+ el.addEventListener(MOUSEOVER, fn, (capture));
+ } else if (eventName == 'mouseleave') {
+ fn = fn.createInterceptor(checkRelatedTarget);
+ el.addEventListener(MOUSEOUT, fn, (capture));
+ } else {
+ el.addEventListener(eventName, fn, (capture));
+ }
+ return fn;
+ };
+ } else if (win.attachEvent) {
+ ret = function(el, eventName, fn, capture) {
+ el.attachEvent("on" + eventName, fn);
+ return fn;
+ };
+ } else {
+ ret = function(){};
+ }
+ return ret;
+ }(),
+ // private
+ doRemove = function(){
+ var ret;
+ if (win.removeEventListener) {
+ ret = function (el, eventName, fn, capture) {
+ if (eventName == 'mouseenter') {
+ eventName = MOUSEOVER;
+ } else if (eventName == 'mouseleave') {
+ eventName = MOUSEOUT;
+ }
+ el.removeEventListener(eventName, fn, (capture));
+ };
+ } else if (win.detachEvent) {
+ ret = function (el, eventName, fn) {
+ el.detachEvent("on" + eventName, fn);
+ };
+ } else {
+ ret = function(){};
+ }
+ return ret;
+ }();
+
+ function checkRelatedTarget(e) {
+ return !elContains(e.currentTarget, pub.getRelatedTarget(e));
+ }
+
+ function elContains(parent, child) {
+ if(parent && parent.firstChild){
+ while(child) {
+ if(child === parent) {
+ return true;
+ }
+ child = child.parentNode;
+ if(child && (child.nodeType != 1)) {
+ child = null;
+ }
+ }
+ }
+ return false;
+ }
+
+ // private
+ function _tryPreloadAttach() {
+ var ret = false,
+ notAvail = [],
+ element, i, v, override,
+ tryAgain = !loadComplete || (retryCount > 0);
+
+ if(!locked){
+ locked = true;
+
+ for(i = 0; i < onAvailStack.length; ++i){
+ v = onAvailStack[i];
+ if(v && (element = doc.getElementById(v.id))){
+ if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
+ override = v.override;
+ element = override ? (override === true ? v.obj : override) : element;
+ v.fn.call(element, v.obj);
+ onAvailStack.remove(v);
+ --i;
+ }else{
+ notAvail.push(v);
+ }
+ }
+ }
+
+ retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
+
+ if (tryAgain) {
+ startInterval();
+ } else {
+ clearInterval(_interval);
+ _interval = null;
+ }
+ ret = !(locked = false);
+ }
+ return ret;
+ }
+
+ // private
+ function startInterval() {
+ if(!_interval){
+ var callback = function() {
+ _tryPreloadAttach();
+ };
+ _interval = setInterval(callback, POLL_INTERVAL);
+ }
+ }
+
+ // private
+ function getScroll() {
+ var dd = doc.documentElement,
+ db = doc.body;
+ if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
+ return [dd[SCROLLLEFT], dd[SCROLLTOP]];
+ }else if(db){
+ return [db[SCROLLLEFT], db[SCROLLTOP]];
+ }else{
+ return [0, 0];
+ }
+ }
+
+ // private
+ function getPageCoord (ev, xy) {
+ ev = ev.browserEvent || ev;
+ var coord = ev['page' + xy];
+ if (!coord && coord !== 0) {
+ coord = ev['client' + xy] || 0;
+
+ if (Ext.isIE) {
+ coord += getScroll()[xy == "X" ? 0 : 1];
+ }
+ }
+
+ return coord;
+ }
+
+ var pub = {
+ extAdapter: true,
+ 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 = POLL_RETRYS;
+ startInterval();
+ },
+
+ // This function should ALWAYS be called from Ext.EventManager
+ addListener: function(el, eventName, fn) {
+ el = Ext.getDom(el);
+ if (el && fn) {
+ if (eventName == UNLOAD) {
+ if (unloadListeners[el.id] === undefined) {
+ unloadListeners[el.id] = [];
+ }
+ unloadListeners[el.id].push([eventName, fn]);
+ return fn;
+ }
+ return doAdd(el, eventName, fn, false);
+ }
+ return false;
+ },
+
+ // This function should ALWAYS be called from Ext.EventManager
+ removeListener: function(el, eventName, fn) {
+ el = Ext.getDom(el);
+ var i, len, li, lis;
+ if (el && fn) {
+ if(eventName == UNLOAD){
+ if((lis = unloadListeners[el.id]) !== undefined){
+ for(i = 0, len = lis.length; i < len; i++){
+ if((li = lis[i]) && li[TYPE] == eventName && li[FN] == fn){
+ unloadListeners[el.id].splice(i, 1);
+ }
+ }
+ }
+ return;
+ }
+ doRemove(el, eventName, fn, false);
+ }
+ },
+
+ getTarget : function(ev) {
+ ev = ev.browserEvent || ev;
+ return this.resolveTextNode(ev.target || ev.srcElement);
+ },
+
+ resolveTextNode : Ext.isGecko ? function(node){
+ if(!node){
+ return;
+ }
+ // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
+ var s = HTMLElement.prototype.toString.call(node);
+ if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
+ return;
+ }
+ return node.nodeType == 3 ? node.parentNode : node;
+ } : function(node){
+ return node && node.nodeType == 3 ? node.parentNode : node;
+ },
+
+ getRelatedTarget : function(ev) {
+ ev = ev.browserEvent || ev;
+ return this.resolveTextNode(ev.relatedTarget ||
+ (/(mouseout|mouseleave)/.test(ev.type) ? ev.toElement :
+ /(mouseover|mouseenter)/.test(ev.type) ? ev.fromElement : null));
+ },
+
+ getPageX : function(ev) {
+ return getPageCoord(ev, "X");
+ },
+
+ getPageY : function(ev) {
+ return getPageCoord(ev, "Y");
+ },
+
+
+ getXY : function(ev) {
+ return [this.getPageX(ev), this.getPageY(ev)];
+ },
+
+ stopEvent : function(ev) {
+ this.stopPropagation(ev);
+ this.preventDefault(ev);
+ },
+
+ stopPropagation : function(ev) {
+ ev = ev.browserEvent || ev;
+ if (ev.stopPropagation) {
+ ev.stopPropagation();
+ } else {
+ ev.cancelBubble = true;
+ }
+ },
+
+ preventDefault : function(ev) {
+ ev = ev.browserEvent || ev;
+ if (ev.preventDefault) {
+ ev.preventDefault();
+ } else {
+ if (ev.keyCode) {
+ ev.keyCode = 0;
+ }
+ ev.returnValue = false;
+ }
+ },
+
+ getEvent : function(e) {
+ e = e || win.event;
+ if (!e) {
+ var c = this.getEvent.caller;
+ while (c) {
+ e = c.arguments[0];
+ if (e && Event == e.constructor) {
+ break;
+ }
+ c = c.caller;
+ }
+ }
+ return e;
+ },
+
+ getCharCode : function(ev) {
+ ev = ev.browserEvent || ev;
+ return ev.charCode || ev.keyCode || 0;
+ },
+
+ //clearCache: function() {},
+ // deprecated, call from EventManager
+ getListeners : function(el, eventName) {
+ Ext.EventManager.getListeners(el, eventName);
+ },
+
+ // deprecated, call from EventManager
+ purgeElement : function(el, recurse, eventName) {
+ Ext.EventManager.purgeElement(el, recurse, eventName);
+ },
+
+ _load : function(e) {
+ loadComplete = true;
+
+ if (Ext.isIE9m && e !== true) {
+ // IE8 complains that _load is null or not an object
+ // so lets remove self via arguments.callee
+ doRemove(win, "load", arguments.callee);
+ }
+ },
+
+ _unload : function(e) {
+ var EU = Ext.lib.Event,
+ i, v, ul, id, len, scope;
+
+ for (id in unloadListeners) {
+ ul = unloadListeners[id];
+ for (i = 0, len = ul.length; i < len; i++) {
+ v = ul[i];
+ if (v) {
+ try{
+ scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win;
+ v[FN].call(scope, EU.getEvent(e), v[OBJ]);
+ }catch(ex){}
+ }
+ }
+ };
+
+ Ext.EventManager._unload();
+
+ doRemove(win, UNLOAD, EU._unload);
+ }
+ };
+
+ // Initialize stuff.
+ pub.on = pub.addListener;
+ pub.un = pub.removeListener;
+ if (doc && doc.body) {
+ pub._load(true);
+ } else {
+ doAdd(win, "load", pub._load);
+ }
+ doAdd(win, UNLOAD, pub._unload);
+ _tryPreloadAttach();
+
+ return pub;
+}();
+/*
+* Portions of this file are based on pieces of Yahoo User Interface Library
+* Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+* YUI licensed under the BSD License:
+* http://developer.yahoo.net/yui/license.txt
+*/
+Ext.lib.Ajax = function() {
+ var activeX = ['Msxml2.XMLHTTP.3.0',
+ 'Msxml2.XMLHTTP'],
+ CONTENTTYPE = 'Content-Type';
+
+ // private
+ function setHeader(o) {
+ var conn = o.conn,
+ prop,
+ headers = {};
+
+ function setTheHeaders(conn, headers){
+ for (prop in headers) {
+ if (headers.hasOwnProperty(prop)) {
+ conn.setRequestHeader(prop, headers[prop]);
+ }
+ }
+ }
+
+ Ext.apply(headers, pub.headers, pub.defaultHeaders);
+ setTheHeaders(conn, headers);
+ delete pub.headers;
+ }
+
+ // private
+ function createExceptionObject(tId, callbackArg, isAbort, isTimeout) {
+ return {
+ tId : tId,
+ status : isAbort ? -1 : 0,
+ statusText : isAbort ? 'transaction aborted' : 'communication failure',
+ isAbort: isAbort,
+ isTimeout: isTimeout,
+ argument : callbackArg
+ };
+ }
+
+ // private
+ function initHeader(label, value) {
+ (pub.headers = pub.headers || {})[label] = value;
+ }
+
+ // private
+ function createResponseObject(o, callbackArg) {
+ var headerObj = {},
+ headerStr,
+ conn = o.conn,
+ t,
+ s,
+ // see: https://prototype.lighthouseapp.com/projects/8886/tickets/129-ie-mangles-http-response-status-code-204-to-1223
+ isBrokenStatus = conn.status == 1223;
+
+ try {
+ headerStr = o.conn.getAllResponseHeaders();
+ Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){
+ t = v.indexOf(':');
+ if(t >= 0){
+ s = v.substr(0, t).toLowerCase();
+ if(v.charAt(t + 1) == ' '){
+ ++t;
+ }
+ headerObj[s] = v.substr(t + 1);
+ }
+ });
+ } catch(e) {}
+
+ return {
+ tId : o.tId,
+ // Normalize the status and statusText when IE returns 1223, see the above link.
+ status : isBrokenStatus ? 204 : conn.status,
+ statusText : isBrokenStatus ? 'No Content' : conn.statusText,
+ getResponseHeader : function(header){return headerObj[header.toLowerCase()];},
+ getAllResponseHeaders : function(){return headerStr;},
+ responseText : conn.responseText,
+ responseXML : conn.responseXML,
+ argument : callbackArg
+ };
+ }
+
+ // private
+ function releaseObject(o) {
+ if (o.tId) {
+ pub.conn[o.tId] = null;
+ }
+ o.conn = null;
+ o = null;
+ }
+
+ // private
+ function handleTransactionResponse(o, callback, isAbort, isTimeout) {
+ if (!callback) {
+ releaseObject(o);
+ return;
+ }
+
+ var httpStatus, responseObject;
+
+ try {
+ if (o.conn.status !== undefined && o.conn.status != 0) {
+ httpStatus = o.conn.status;
+ }
+ else {
+ httpStatus = 13030;
+ }
+ }
+ catch(e) {
+ httpStatus = 13030;
+ }
+
+ if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) {
+ responseObject = createResponseObject(o, callback.argument);
+ if (callback.success) {
+ if (!callback.scope) {
+ callback.success(responseObject);
+ }
+ else {
+ callback.success.apply(callback.scope, [responseObject]);
+ }
+ }
+ }
+ else {
+ switch (httpStatus) {
+ case 12002:
+ case 12029:
+ case 12030:
+ case 12031:
+ case 12152:
+ case 13030:
+ responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout);
+ if (callback.failure) {
+ if (!callback.scope) {
+ callback.failure(responseObject);
+ }
+ else {
+ callback.failure.apply(callback.scope, [responseObject]);
+ }
+ }
+ break;
+ default:
+ responseObject = createResponseObject(o, callback.argument);
+ if (callback.failure) {
+ if (!callback.scope) {
+ callback.failure(responseObject);
+ }
+ else {
+ callback.failure.apply(callback.scope, [responseObject]);
+ }
+ }
+ }
+ }
+
+ releaseObject(o);
+ responseObject = null;
+ }
+
+ function checkResponse(o, callback, conn, tId, poll, cbTimeout){
+ if (conn && conn.readyState == 4) {
+ clearInterval(poll[tId]);
+ poll[tId] = null;
+
+ if (cbTimeout) {
+ clearTimeout(pub.timeout[tId]);
+ pub.timeout[tId] = null;
+ }
+ handleTransactionResponse(o, callback);
+ }
+ }
+
+ function checkTimeout(o, callback){
+ pub.abort(o, callback, true);
+ }
+
+
+ // private
+ function handleReadyState(o, callback){
+ callback = callback || {};
+ var conn = o.conn,
+ tId = o.tId,
+ poll = pub.poll,
+ cbTimeout = callback.timeout || null;
+
+ if (cbTimeout) {
+ pub.conn[tId] = conn;
+ pub.timeout[tId] = setTimeout(checkTimeout.createCallback(o, callback), cbTimeout);
+ }
+ poll[tId] = setInterval(checkResponse.createCallback(o, callback, conn, tId, poll, cbTimeout), pub.pollInterval);
+ }
+
+ // private
+ function asyncRequest(method, uri, callback, postData) {
+ var o = getConnectionObject() || null;
+
+ if (o) {
+ o.conn.open(method, uri, true);
+
+ if (pub.useDefaultXhrHeader) {
+ initHeader('X-Requested-With', pub.defaultXhrHeader);
+ }
+
+ if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){
+ initHeader(CONTENTTYPE, pub.defaultPostHeader);
+ }
+
+ if (pub.defaultHeaders || pub.headers) {
+ setHeader(o);
+ }
+
+ handleReadyState(o, callback);
+ o.conn.send(postData || null);
+ }
+ return o;
+ }
+
+ // private
+ function getConnectionObject() {
+ var o;
+
+ try {
+ if (o = createXhrObject(pub.transactionId)) {
+ pub.transactionId++;
+ }
+ } catch(e) {
+ } finally {
+ return o;
+ }
+ }
+
+ // private
+ function createXhrObject(transactionId) {
+ var http;
+
+ try {
+ http = new XMLHttpRequest();
+ } catch(e) {
+ for (var i = Ext.isIE6 ? 1 : 0; i < activeX.length; ++i) {
+ try {
+ http = new ActiveXObject(activeX[i]);
+ break;
+ } catch(e) {}
+ }
+ } finally {
+ return {conn : http, tId : transactionId};
+ }
+ }
+
+ var pub = {
+ request : function(method, uri, cb, data, options) {
+ if(options){
+ var me = this,
+ xmlData = options.xmlData,
+ jsonData = options.jsonData,
+ hs;
+
+ Ext.applyIf(me, options);
+
+ if(xmlData || jsonData){
+ hs = me.headers;
+ if(!hs || !hs[CONTENTTYPE]){
+ initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json');
+ }
+ data = xmlData || (!Ext.isPrimitive(jsonData) ? Ext.encode(jsonData) : jsonData);
+ }
+ }
+ return asyncRequest(method || options.method || "POST", uri, cb, data);
+ },
+
+ serializeForm : function(form) {
+ var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
+ hasSubmit = false,
+ encoder = encodeURIComponent,
+ name,
+ data = '',
+ type,
+ hasValue;
+
+ Ext.each(fElements, function(element){
+ name = element.name;
+ type = element.type;
+
+ if (!element.disabled && name) {
+ if (/select-(one|multiple)/i.test(type)) {
+ Ext.each(element.options, function(opt){
+ if (opt.selected) {
+ hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
+ data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
+ }
+ });
+ } else if (!(/file|undefined|reset|button/i.test(type))) {
+ if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {
+ data += encoder(name) + '=' + encoder(element.value) + '&';
+ hasSubmit = /submit/i.test(type);
+ }
+ }
+ }
+ });
+ return data.substr(0, data.length - 1);
+ },
+
+ useDefaultHeader : true,
+ defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
+ useDefaultXhrHeader : true,
+ defaultXhrHeader : 'XMLHttpRequest',
+ poll : {},
+ timeout : {},
+ conn: {},
+ pollInterval : 50,
+ transactionId : 0,
+
+// This is never called - Is it worth exposing this?
+// setProgId : function(id) {
+// activeX.unshift(id);
+// },
+
+// This is never called - Is it worth exposing this?
+// setDefaultPostHeader : function(b) {
+// this.useDefaultHeader = b;
+// },
+
+// This is never called - Is it worth exposing this?
+// setDefaultXhrHeader : function(b) {
+// this.useDefaultXhrHeader = b;
+// },
+
+// This is never called - Is it worth exposing this?
+// setPollingInterval : function(i) {
+// if (typeof i == 'number' && isFinite(i)) {
+// this.pollInterval = i;
+// }
+// },
+
+// This is never called - Is it worth exposing this?
+// resetDefaultHeaders : function() {
+// this.defaultHeaders = null;
+// },
+
+ abort : function(o, callback, isTimeout) {
+ var me = this,
+ tId = o.tId,
+ isAbort = false;
+
+ if (me.isCallInProgress(o)) {
+ o.conn.abort();
+ clearInterval(me.poll[tId]);
+ me.poll[tId] = null;
+ clearTimeout(pub.timeout[tId]);
+ me.timeout[tId] = null;
+
+ handleTransactionResponse(o, callback, (isAbort = true), isTimeout);
+ }
+ return isAbort;
+ },
+
+ isCallInProgress : function(o) {
+ // if there is a connection and readyState is not 0 or 4
+ return o.conn && !{0:true,4:true}[o.conn.readyState];
+ }
+ };
+ return pub;
+}();(function(){
+ var EXTLIB = Ext.lib,
+ 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,
+ isset = function(v){
+ return typeof v !== 'undefined';
+ },
+ now = function(){
+ return new Date();
+ };
+
+ EXTLIB.Anim = {
+ motion : function(el, args, duration, easing, cb, scope) {
+ return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);
+ },
+
+ run : function(el, args, duration, easing, cb, scope, type) {
+ type = type || Ext.lib.AnimBase;
+ if (typeof easing == "string") {
+ easing = Ext.lib.Easing[easing];
+ }
+ var anim = new type(el, args, duration, easing);
+ anim.animateX(function() {
+ if(Ext.isFunction(cb)){
+ cb.call(scope);
+ }
+ });
+ return anim;
+ }
+ };
+
+ EXTLIB.AnimBase = function(el, attributes, duration, method) {
+ if (el) {
+ this.init(el, attributes, duration, method);
+ }
+ };
+
+ EXTLIB.AnimBase.prototype = {
+ doMethod: function(attr, start, end) {
+ var me = this;
+ return me.method(me.curFrame, start, end - start, me.totalFrames);
+ },
+
+
+ setAttr: function(attr, val, unit) {
+ if (noNegatives.test(attr) && val < 0) {
+ val = 0;
+ }
+ Ext.fly(this.el, '_anim').setStyle(attr, val + unit);
+ },
+
+
+ getAttr: function(attr) {
+ var el = Ext.fly(this.el),
+ val = el.getStyle(attr),
+ a = offsetAttribute.exec(attr) || [];
+
+ if (val !== 'auto' && !offsetUnit.test(val)) {
+ return parseFloat(val);
+ }
+
+ return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0;
+ },
+
+
+ getDefaultUnit: function(attr) {
+ return defaultUnit.test(attr) ? 'px' : '';
+ },
+
+ animateX : function(callback, scope) {
+ var me = this,
+ f = function() {
+ me.onComplete.removeListener(f);
+ if (Ext.isFunction(callback)) {
+ callback.call(scope || me, me);
+ }
+ };
+ me.onComplete.addListener(f, me);
+ me.animate();
+ },
+
+
+ setRunAttr: function(attr) {
+ var me = this,
+ a = this.attributes[attr],
+ to = a.to,
+ by = a.by,
+ from = a.from,
+ unit = a.unit,
+ ra = (this.runAttrs[attr] = {}),
+ end;
+
+ if (!isset(to) && !isset(by)){
+ return false;
+ }
+
+ var start = isset(from) ? from : me.getAttr(attr);
+ if (isset(to)) {
+ end = to;
+ }else if(isset(by)) {
+ if (Ext.isArray(start)){
+ end = [];
+ for(var i=0,len=start.length; i<len; i++) {
+ end[i] = start[i] + by[i];
+ }
+ }else{
+ end = start + by;
+ }
+ }
+
+ Ext.apply(ra, {
+ start: start,
+ end: end,
+ unit: isset(unit) ? unit : me.getDefaultUnit(attr)
+ });
+ },
+
+
+ init: function(el, attributes, duration, method) {
+ var me = this,
+ actualFrames = 0,
+ mgr = EXTLIB.AnimMgr;
+
+ Ext.apply(me, {
+ isAnimated: false,
+ startTime: null,
+ el: Ext.getDom(el),
+ attributes: attributes || {},
+ duration: duration || 1,
+ method: method || EXTLIB.Easing.easeNone,
+ useSec: true,
+ curFrame: 0,
+ totalFrames: mgr.fps,
+ runAttrs: {},
+ animate: function(){
+ var me = this,
+ d = me.duration;
+
+ if(me.isAnimated){
+ return false;
+ }
+
+ me.curFrame = 0;
+ me.totalFrames = me.useSec ? Math.ceil(mgr.fps * d) : d;
+ mgr.registerElement(me);
+ },
+
+ stop: function(finish){
+ var me = this;
+
+ if(finish){
+ me.curFrame = me.totalFrames;
+ me._onTween.fire();
+ }
+ mgr.stop(me);
+ }
+ });
+
+ var onStart = function(){
+ var me = this,
+ attr;
+
+ me.onStart.fire();
+ me.runAttrs = {};
+ for(attr in this.attributes){
+ this.setRunAttr(attr);
+ }
+
+ me.isAnimated = true;
+ me.startTime = now();
+ actualFrames = 0;
+ };
+
+
+ var onTween = function(){
+ var me = this;
+
+ me.onTween.fire({
+ duration: now() - me.startTime,
+ curFrame: me.curFrame
+ });
+
+ var ra = me.runAttrs;
+ for (var attr in ra) {
+ this.setAttr(attr, me.doMethod(attr, ra[attr].start, ra[attr].end), ra[attr].unit);
+ }
+
+ ++actualFrames;
+ };
+
+ var onComplete = function() {
+ var me = this,
+ actual = (now() - me.startTime) / 1000,
+ data = {
+ duration: actual,
+ frames: actualFrames,
+ fps: actualFrames / actual
+ };
+
+ me.isAnimated = false;
+ actualFrames = 0;
+ me.onComplete.fire(data);
+ };
+
+ me.onStart = new Ext.util.Event(me);
+ me.onTween = new Ext.util.Event(me);
+ me.onComplete = new Ext.util.Event(me);
+ (me._onStart = new Ext.util.Event(me)).addListener(onStart);
+ (me._onTween = new Ext.util.Event(me)).addListener(onTween);
+ (me._onComplete = new Ext.util.Event(me)).addListener(onComplete);
+ }
+ };
+
+
+ Ext.lib.AnimMgr = new function() {
+ var me = this,
+ thread = null,
+ queue = [],
+ tweenCount = 0;
+
+
+ Ext.apply(me, {
+ fps: 1000,
+ delay: 1,
+ registerElement: function(tween){
+ queue.push(tween);
+ ++tweenCount;
+ tween._onStart.fire();
+ me.start();
+ },
+
+ unRegister: function(tween, index){
+ tween._onComplete.fire();
+ index = index || getIndex(tween);
+ if (index != -1) {
+ queue.splice(index, 1);
+ }
+
+ if (--tweenCount <= 0) {
+ me.stop();
+ }
+ },
+
+ start: function(){
+ if(thread === null){
+ thread = setInterval(me.run, me.delay);
+ }
+ },
+
+ stop: function(tween){
+ if(!tween){
+ clearInterval(thread);
+ for(var i = 0, len = queue.length; i < len; ++i){
+ if(queue[0].isAnimated){
+ me.unRegister(queue[0], 0);
+ }
+ }
+
+ queue = [];
+ thread = null;
+ tweenCount = 0;
+ }else{
+ me.unRegister(tween);
+ }
+ },
+
+ run: function(){
+ var tf, i, len, tween;
+ for(i = 0, len = queue.length; i<len; i++) {
+ tween = queue[i];
+ if(tween && tween.isAnimated){
+ tf = tween.totalFrames;
+ if(tween.curFrame < tf || tf === null){
+ ++tween.curFrame;
+ if(tween.useSec){
+ correctFrame(tween);
+ }
+ tween._onTween.fire();
+ }else{
+ me.stop(tween);
+ }
+ }
+ }
+ }
+ });
+
+ var getIndex = function(anim) {
+ var i, len;
+ for(i = 0, len = queue.length; i<len; i++) {
+ if(queue[i] === anim) {
+ return i;
+ }
+ }
+ return -1;
+ };
+
+ var correctFrame = function(tween) {
+ var frames = tween.totalFrames,
+ frame = tween.curFrame,
+ duration = tween.duration,
+ expected = (frame * duration * 1000 / frames),
+ elapsed = (now() - tween.startTime),
+ tweak = 0;
+
+ if(elapsed < duration * 1000){
+ tweak = Math.round((elapsed / expected - 1) * frame);
+ }else{
+ tweak = frames - (frame + 1);
+ }
+ if(tweak > 0 && isFinite(tweak)){
+ if(tween.curFrame + tweak >= frames){
+ tweak = frames - (frame + 1);
+ }
+ tween.curFrame += tweak;
+ }
+ };
+ };
+
+ EXTLIB.Bezier = new function() {
+
+ this.getPosition = function(points, t) {
+ var n = points.length,
+ tmp = [],
+ c = 1 - t,
+ i,
+ j;
+
+ for (i = 0; i < n; ++i) {
+ tmp[i] = [points[i][0], points[i][1]];
+ }
+
+ for (j = 1; j < n; ++j) {
+ for (i = 0; i < n - j; ++i) {
+ tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
+ tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
+ }
+ }
+
+ return [ tmp[0][0], tmp[0][1] ];
+
+ };
+ };
+
+
+ EXTLIB.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;
+ }
+ };
+
+ (function() {
+ EXTLIB.Motion = function(el, attributes, duration, method) {
+ if (el) {
+ EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method);
+ }
+ };
+
+ Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase);
+
+ var superclass = EXTLIB.Motion.superclass,
+ pointsRe = /^points$/i;
+
+ Ext.apply(EXTLIB.Motion.prototype, {
+ setAttr: function(attr, val, unit){
+ var me = this,
+ setAttr = superclass.setAttr;
+
+ if (pointsRe.test(attr)) {
+ unit = unit || 'px';
+ setAttr.call(me, 'left', val[0], unit);
+ setAttr.call(me, 'top', val[1], unit);
+ } else {
+ setAttr.call(me, attr, val, unit);
+ }
+ },
+
+ getAttr: function(attr){
+ var me = this,
+ getAttr = superclass.getAttr;
+
+ return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr);
+ },
+
+ doMethod: function(attr, start, end){
+ var me = this;
+
+ return pointsRe.test(attr)
+ ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100)
+ : superclass.doMethod.call(me, attr, start, end);
+ },
+
+ setRunAttr: function(attr){
+ if(pointsRe.test(attr)){
+
+ var me = this,
+ el = this.el,
+ points = this.attributes.points,
+ control = points.control || [],
+ from = points.from,
+ to = points.to,
+ by = points.by,
+ DOM = EXTLIB.Dom,
+ start,
+ i,
+ end,
+ len,
+ ra;
+
+
+ if(control.length > 0 && !Ext.isArray(control[0])){
+ control = [control];
+ }else{
+ /*
+ var tmp = [];
+ for (i = 0,len = control.length; i < len; ++i) {
+ tmp[i] = control[i];
+ }
+ control = tmp;
+ */
+ }
+
+ Ext.fly(el, '_anim').position();
+ DOM.setXY(el, isset(from) ? from : DOM.getXY(el));
+ start = me.getAttr('points');
+
+
+ if(isset(to)){
+ end = translateValues.call(me, to, start);
+ for (i = 0,len = control.length; i < len; ++i) {
+ control[i] = translateValues.call(me, control[i], start);
+ }
+ } else if (isset(by)) {
+ end = [start[0] + by[0], start[1] + by[1]];
+
+ for (i = 0,len = control.length; i < len; ++i) {
+ control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
+ }
+ }
+
+ ra = this.runAttrs[attr] = [start];
+ if (control.length > 0) {
+ ra = ra.concat(control);
+ }
+
+ ra[ra.length] = end;
+ }else{
+ superclass.setRunAttr.call(this, attr);
+ }
+ }
+ });
+
+ var translateValues = function(val, start) {
+ var pageXY = EXTLIB.Dom.getXY(this.el);
+ return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];
+ };
+ })();
+})();// Easing functions
+(function(){
+ // shortcuts to aid compression
+ var abs = Math.abs,
+ pi = Math.PI,
+ asin = Math.asin,
+ pow = Math.pow,
+ sin = Math.sin,
+ EXTLIB = Ext.lib;
+
+ Ext.apply(EXTLIB.Easing, {
+
+ easeBoth: function (t, b, c, d) {
+ return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -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) {
+ return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b;
+ },
+
+ elasticIn: function (t, b, c, d, a, p) {
+ if (t == 0 || (t /= d) == 1) {
+ return t == 0 ? b : b + c;
+ }
+ p = p || (d * .3);
+
+ var s;
+ if (a >= abs(c)) {
+ s = p / (2 * pi) * asin(c / a);
+ } else {
+ a = c;
+ s = p / 4;
+ }
+
+ return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b;
+
+ },
+
+ elasticOut: function (t, b, c, d, a, p) {
+ if (t == 0 || (t /= d) == 1) {
+ return t == 0 ? b : b + c;
+ }
+ p = p || (d * .3);
+
+ var s;
+ if (a >= abs(c)) {
+ s = p / (2 * pi) * asin(c / a);
+ } else {
+ a = c;
+ s = p / 4;
+ }
+
+ return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b;
+ },
+
+ elasticBoth: function (t, b, c, d, a, p) {
+ if (t == 0 || (t /= d / 2) == 2) {
+ return t == 0 ? b : b + c;
+ }
+
+ p = p || (d * (.3 * 1.5));
+
+ var s;
+ if (a >= abs(c)) {
+ s = p / (2 * pi) * asin(c / a);
+ } else {
+ a = c;
+ s = p / 4;
+ }
+
+ return t < 1 ?
+ -.5 * (a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b :
+ a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b;
+ },
+
+ backIn: function (t, b, c, d, s) {
+ s = s || 1.70158;
+ return c * (t /= d) * t * ((s + 1) * t - s) + b;
+ },
+
+
+ backOut: function (t, b, c, d, s) {
+ if (!s) {
+ s = 1.70158;
+ }
+ return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
+ },
+
+
+ backBoth: function (t, b, c, d, s) {
+ s = s || 1.70158;
+
+ return ((t /= d / 2 ) < 1) ?
+ c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b :
+ c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
+ },
+
+
+ bounceIn: function (t, b, c, d) {
+ return c - EXTLIB.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 + .75) + b;
+ } else if (t < (2.5 / 2.75)) {
+ return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
+ }
+ return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
+ },
+
+
+ bounceBoth: function (t, b, c, d) {
+ return (t < d / 2) ?
+ EXTLIB.Easing.bounceIn(t * 2, 0, c, d) * .5 + b :
+ EXTLIB.Easing.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
+ }
+ });
+})();
+
+(function() {
+ var EXTLIB = Ext.lib;
+ // Color Animation
+ EXTLIB.Anim.color = function(el, args, duration, easing, cb, scope) {
+ return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.ColorAnim);
+ };
+
+ EXTLIB.ColorAnim = function(el, attributes, duration, method) {
+ EXTLIB.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
+ };
+
+ Ext.extend(EXTLIB.ColorAnim, EXTLIB.AnimBase);
+
+ var superclass = EXTLIB.ColorAnim.superclass,
+ colorRE = /color$/i,
+ transparentRE = /^transparent|rgba\(0, 0, 0, 0\)$/,
+ rgbRE = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
+ hexRE= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
+ hex3RE = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,
+ isset = function(v){
+ return typeof v !== 'undefined';
+ };
+
+ // private
+ function parseColor(s) {
+ var pi = parseInt,
+ base,
+ out = null,
+ c;
+
+ if (s.length == 3) {
+ return s;
+ }
+
+ Ext.each([hexRE, rgbRE, hex3RE], function(re, idx){
+ base = (idx % 2 == 0) ? 16 : 10;
+ c = re.exec(s);
+ if(c && c.length == 4){
+ out = [pi(c[1], base), pi(c[2], base), pi(c[3], base)];
+ return false;
+ }
+ });
+ return out;
+ }
+
+ Ext.apply(EXTLIB.ColorAnim.prototype, {
+ getAttr : function(attr) {
+ var me = this,
+ el = me.el,
+ val;
+ if(colorRE.test(attr)){
+ while(el && transparentRE.test(val = Ext.fly(el).getStyle(attr))){
+ el = el.parentNode;
+ val = "fff";
+ }
+ }else{
+ val = superclass.getAttr.call(me, attr);
+ }
+ return val;
+ },
+
+ doMethod : function(attr, start, end) {
+ var me = this,
+ val,
+ floor = Math.floor,
+ i,
+ len,
+ v;
+
+ if(colorRE.test(attr)){
+ val = [];
+ end = end || [];
+
+ for(i = 0, len = start.length; i < len; i++) {
+ v = start[i];
+ val[i] = superclass.doMethod.call(me, attr, v, end[i]);
+ }
+ val = 'rgb(' + floor(val[0]) + ',' + floor(val[1]) + ',' + floor(val[2]) + ')';
+ }else{
+ val = superclass.doMethod.call(me, attr, start, end);
+ }
+ return val;
+ },
+
+ setRunAttr : function(attr) {
+ var me = this,
+ a = me.attributes[attr],
+ to = a.to,
+ by = a.by,
+ ra;
+
+ superclass.setRunAttr.call(me, attr);
+ ra = me.runAttrs[attr];
+ if(colorRE.test(attr)){
+ var start = parseColor(ra.start),
+ end = parseColor(ra.end);
+
+ if(!isset(to) && isset(by)){
+ end = parseColor(by);
+ for(var i=0,len=start.length; i<len; i++) {
+ end[i] = start[i] + end[i];
+ }
+ }
+ ra.start = start;
+ ra.end = end;
+ }
+ }
+ });
+})();
+
+
+(function() {
+ // Scroll Animation
+ var EXTLIB = Ext.lib;
+ EXTLIB.Anim.scroll = function(el, args, duration, easing, cb, scope) {
+ return EXTLIB.Anim.run(el, args, duration, easing, cb, scope, EXTLIB.Scroll);
+ };
+
+ EXTLIB.Scroll = function(el, attributes, duration, method) {
+ if(el){
+ EXTLIB.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
+ }
+ };
+
+ Ext.extend(EXTLIB.Scroll, EXTLIB.ColorAnim);
+
+ var superclass = EXTLIB.Scroll.superclass,
+ SCROLL = 'scroll';
+
+ Ext.apply(EXTLIB.Scroll.prototype, {
+
+ doMethod : function(attr, start, end) {
+ var val,
+ me = this,
+ curFrame = me.curFrame,
+ totalFrames = me.totalFrames;
+
+ if(attr == SCROLL){
+ val = [me.method(curFrame, start[0], end[0] - start[0], totalFrames),
+ me.method(curFrame, start[1], end[1] - start[1], totalFrames)];
+ }else{
+ val = superclass.doMethod.call(me, attr, start, end);
+ }
+ return val;
+ },
+
+ getAttr : function(attr) {
+ var me = this;
+
+ if (attr == SCROLL) {
+ return [me.el.scrollLeft, me.el.scrollTop];
+ }else{
+ return superclass.getAttr.call(me, attr);
+ }
+ },
+
+ setAttr : function(attr, val, unit) {
+ var me = this;
+
+ if(attr == SCROLL){
+ me.el.scrollLeft = val[0];
+ me.el.scrollTop = val[1];
+ }else{
+ superclass.setAttr.call(me, attr, val, unit);
+ }
+ }
+ });
+})();
+ if (Ext.isIE9m) {
+ function fnCleanUp() {
+ var p = Function.prototype;
+ delete p.createSequence;
+ delete p.defer;
+ delete p.createDelegate;
+ delete p.createCallback;
+ delete p.createInterceptor;
+
+ window.detachEvent("onunload", fnCleanUp);
+ }
+ window.attachEvent("onunload", fnCleanUp);
+ }
+})();
diff --git a/deluge/ui/web/js/extjs/ext-base.js b/deluge/ui/web/js/extjs/ext-base.js
new file mode 100644
index 0000000..29047a7
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-base.js
@@ -0,0 +1,21 @@
+/*
+This file is part of Ext JS 3.4
+
+Copyright (c) 2011-2013 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as
+published by the Free Software Foundation and appearing in the file LICENSE included in the
+packaging of this file.
+
+Please review the following information to ensure the GNU General Public License version 3.0
+requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department
+at http://www.sencha.com/contact.
+
+Build date: 2013-04-03 15:07:25
+*/
+window.undefined=window.undefined;Ext={version:"3.4.1.1",versionDetail:{major:3,minor:4,patch:1.1}};Ext.apply=function(d,e,b){if(b){Ext.apply(d,b)}if(d&&e&&typeof e=="object"){for(var a in e){d[a]=e[a]}}return d};(function(){var g=0,f=Object.prototype.toString,y=navigator.userAgent.toLowerCase(),n=function(e){return e.test(y)},s=document,q=s.documentMode,u=s.compatMode=="CSS1Compat",a=n(/opera/),H=n(/\bchrome\b/),z=n(/webkit/),d=!H&&n(/safari/),F=d&&n(/applewebkit\/4/),D=d&&n(/version\/3/),B=d&&n(/version\/4/),j=!a&&n(/msie/),G=j&&((n(/msie 7/)&&q!=8&&q!=9&&q!=10)||q==7),E=j&&((n(/msie 8/)&&q!=7&&q!=9&&q!=10)||q==8),C=j&&((n(/msie 9/)&&q!=7&&q!=8&&q!=10)||q==9),i=j&&((n(/msie 10/)&&q!=7&&q!=8&&q!=9)||q==10),J=j&&n(/msie 6/),K=j&&(J||G||E||C),c=!z&&n(/gecko/),M=c&&n(/rv:1\.8/),L=c&&n(/rv:1\.9/),m=K&&!u,h=n(/windows|win32/),A=n(/macintosh|mac os x/),p=n(/adobeair/),v=n(/linux/),r=/^https/i.test(window.location.protocol),b=[],w=[],o=Ext.emptyFn,x=Ext.apply({},{constructor:o,toString:o,valueOf:o}),l=function(){var e=l.caller.caller;return e.$owner.prototype[e.$name].apply(this,arguments)};if(x.constructor!==o){w.push("constructor")}if(x.toString!==o){w.push("toString")}if(x.valueOf!==o){w.push("valueOf")}if(!w.length){w=null}function k(){}Ext.apply(k,{$isClass:true,callParent:function(e){var t;return(t=this.callParent.caller)&&(t.$previous||((t=t.$owner?t:t.caller)&&t.$owner.superclass.self[t.$name])).apply(this,e||b)}});k.prototype={constructor:function(){},callParent:function(t){var N,e=(N=this.callParent.caller)&&(N.$previous||((N=N.$owner?N:N.caller)&&N.$owner.superclass[N.$name]));return e.apply(this,t||b)}};if(J){try{s.execCommand("BackgroundImageCache",false,true)}catch(I){}}Ext.apply(Ext,{SSL_SECURE_URL:r&&j?'javascript:""':"about:blank",isStrict:u,isSecure:r,isReady:false,enableForcedBoxModel:false,enableGarbageCollector:true,enableListenerCollection:false,enableNestedListenerRemoval:false,USE_NATIVE_JSON:false,applyIf:function(t,N){if(t){for(var e in N){if(!Ext.isDefined(t[e])){t[e]=N[e]}}}return t},id:function(e,t){e=Ext.getDom(e,true)||{};if(!e.id){e.id=(t||"ext-gen")+(++g)}return e.id},extend:function(){var t=function(O){for(var N in O){this[N]=O[N]}};var e=Object.prototype.constructor;return function(S,P,R){if(typeof P=="object"){R=P;P=S;S=R.constructor!=e?R.constructor:function(){P.apply(this,arguments)}}var O=function(){},Q,N=P.prototype;O.prototype=N;Q=S.prototype=new O();Q.constructor=S;S.superclass=N;if(N.constructor==e){N.constructor=P}S.override=function(T){Ext.override(S,T)};Q.superclass=Q.supr=(function(){return N});Q.override=t;Ext.override(S,R);S.extend=function(T){return Ext.extend(S,T)};return S}}(),global:(function(){return this})(),Base:k,namespaceCache:{},createNamespace:function(R,O){var e=Ext.namespaceCache,P=O?R.substring(0,R.lastIndexOf(".")):R,U=e[P],S,N,t,Q,T;if(!U){U=Ext.global;if(P){T=[];Q=P.split(".");for(S=0,N=Q.length;S<N;++S){t=Q[S];U=U[t]||(U[t]={});T.push(t);e[T.join(".")]=U}}}return U},getClassByName:function(N){var O=N.split("."),e=Ext.global,P=O.length,t;for(t=0;e&&t<P;++t){e=e[O[t]]}return e||null},addMembers:function(t,Q,N,e){var P,O,R;for(O in N){if(N.hasOwnProperty(O)){R=N[O];if(typeof R=="function"){R.$owner=t;R.$name=O}Q[O]=R}}if(e&&w){for(P=w.length;P-->0;){O=w[P];if(N.hasOwnProperty(O)){R=N[O];if(typeof R=="function"){R.$owner=t;R.$name=O}Q[O]=R}}}},define:function(R,P,N){var t=P.override,T,Q,e,O;if(t){delete P.override;T=Ext.getClassByName(t);Ext.override(T,P)}else{if(R){O=Ext.createNamespace(R,true);e=R.substring(R.lastIndexOf(".")+1)}T=function S(){this.constructor.apply(this,arguments)};if(R){T.displayName=R}T.$isClass=true;T.callParent=Ext.Base.callParent;if(typeof P=="function"){P=P(T)}Q=P.extend;if(Q){delete P.extend;if(typeof Q=="string"){Q=Ext.getClassByName(Q)}}else{Q=k}Ext.extend(T,Q,P);if(T.prototype.constructor===T){delete T.prototype.constructor}if(!T.prototype.$isClass){Ext.applyIf(T.prototype,k.prototype)}T.prototype.self=T;if(P.xtype){Ext.reg(P.xtype,T)}T=P.singleton?new T():T;if(R){O[e]=T}}if(N){N.call(T)}return T},override:function(P,R){var N,Q;if(R){if(P.$isClass){Q=R.statics;if(Q){delete R.statics}Ext.addMembers(P,P.prototype,R,true);if(Q){Ext.addMembers(P,P,Q)}}else{if(typeof P=="function"){N=P.prototype;Ext.apply(N,R);if(Ext.isIE&&R.hasOwnProperty("toString")){N.toString=R.toString}}else{var e=P.self,t,O;if(e&&e.$isClass){for(t in R){if(R.hasOwnProperty(t)){O=R[t];if(typeof O=="function"){if(e.$className){O.displayName=e.$className+"#"+t}O.$name=t;O.$owner=e;O.$previous=P.hasOwnProperty(t)?P[t]:l}P[t]=O}}}else{Ext.apply(P,R);if(!P.constructor.$isClass){P.constructor.prototype.callParent=k.prototype.callParent;P.constructor.callParent=k.callParent}}}}}},namespace:function(){var O=arguments.length,P=0,t,N,e,R,Q,S;for(;P<O;++P){e=arguments[P];R=arguments[P].split(".");S=window[R[0]];if(S===undefined){S=window[R[0]]={}}Q=R.slice(1);t=Q.length;for(N=0;N<t;++N){S=S[Q[N]]=S[Q[N]]||{}}}return S},urlEncode:function(Q,P){var N,t=[],O=encodeURIComponent;Ext.iterate(Q,function(e,R){N=Ext.isEmpty(R);Ext.each(N?e:R,function(S){t.push("&",O(e),"=",(!Ext.isEmpty(S)&&(S!=e||!N))?(Ext.isDate(S)?Ext.encode(S).replace(/"/g,""):O(S)):"")})});if(!P){t.shift();P=""}return P+t.join("")},urlDecode:function(N,t){if(Ext.isEmpty(N)){return{}}var Q={},P=N.split("&"),R=decodeURIComponent,e,O;Ext.each(P,function(S){S=S.split("=");e=R(S[0]);O=R(S[1]);Q[e]=t||!Q[e]?O:[].concat(Q[e]).concat(O)});return Q},urlAppend:function(e,t){if(!Ext.isEmpty(t)){return e+(e.indexOf("?")===-1?"?":"&")+t}return e},toArray:function(){return j?function(N,Q,O,P){P=[];for(var t=0,e=N.length;t<e;t++){P.push(N[t])}return P.slice(Q||0,O||P.length)}:function(e,N,t){return Array.prototype.slice.call(e,N||0,t||e.length)}}(),isIterable:function(e){if(Ext.isArray(e)||e.callee){return true}if(/NodeList|HTMLCollection/.test(f.call(e))){return true}return((typeof e.nextNode!="undefined"||e.item)&&Ext.isNumber(e.length))},each:function(P,O,N){if(Ext.isEmpty(P,true)){return}if(!Ext.isIterable(P)||Ext.isPrimitive(P)){P=[P]}for(var t=0,e=P.length;t<e;t++){if(O.call(N||P[t],P[t],t,P)===false){return t}}},iterate:function(N,t,e){if(Ext.isEmpty(N)){return}if(Ext.isIterable(N)){Ext.each(N,t,e);return}else{if(typeof N=="object"){for(var O in N){if(N.hasOwnProperty(O)){if(t.call(e||N,O,N[O],N)===false){return}}}}}},getDom:function(N,t){if(!N||!s){return null}if(N.dom){return N.dom}else{if(typeof N=="string"){var O=s.getElementById(N);if(O&&j&&t){if(N==O.getAttribute("id")){return O}else{return null}}return O}else{return N}}},getBody:function(){return Ext.get(s.body||s.documentElement)},getHead:function(){var e;return function(){if(e==undefined){e=Ext.get(s.getElementsByTagName("head")[0])}return e}}(),removeNode:j&&!E?function(){var e;return function(t){if(t&&t.tagName!="BODY"){(Ext.enableNestedListenerRemoval)?Ext.EventManager.purgeElement(t,true):Ext.EventManager.removeAll(t);e=e||s.createElement("div");e.appendChild(t);e.innerHTML="";delete Ext.elCache[t.id]}}}():function(e){if(e&&e.parentNode&&e.tagName!="BODY"){(Ext.enableNestedListenerRemoval)?Ext.EventManager.purgeElement(e,true):Ext.EventManager.removeAll(e);e.parentNode.removeChild(e);delete Ext.elCache[e.id]}},isEmpty:function(t,e){return t===null||t===undefined||((Ext.isArray(t)&&!t.length))||(!e?t==="":false)},isArray:function(e){return f.apply(e)==="[object Array]"},isDate:function(e){return f.apply(e)==="[object Date]"},isObject:function(e){return !!e&&Object.prototype.toString.call(e)==="[object Object]"},isPrimitive:function(e){return Ext.isString(e)||Ext.isNumber(e)||Ext.isBoolean(e)},isFunction:function(e){return f.apply(e)==="[object Function]"},isNumber:function(e){return typeof e==="number"&&isFinite(e)},isString:function(e){return typeof e==="string"},isBoolean:function(e){return typeof e==="boolean"},isElement:function(e){return e?!!e.tagName:false},isDefined:function(e){return typeof e!=="undefined"},isOpera:a,isWebKit:z,isChrome:H,isSafari:d,isSafari3:D,isSafari4:B,isSafari2:F,isIE:j,isIE6:J,isIE7:G,isIE8:E,isIE9:C,isIE10:i,isIE9m:K,isIE10p:j&&!(J||G||E||C),isIEQuirks:j&&(!u&&(J||G||E||C)),isGecko:c,isGecko2:M,isGecko3:L,isBorderBox:m,isLinux:v,isWindows:h,isMac:A,isAir:p});Ext.ns=Ext.namespace})();Ext.ns("Ext.util","Ext.lib","Ext.data","Ext.supports");Ext.elCache={};Ext.apply(Function.prototype,{createInterceptor:function(b,a){var c=this;return !Ext.isFunction(b)?this:function(){var e=this,d=arguments;b.target=e;b.method=c;return(b.apply(a||e||window,d)!==false)?c.apply(e||window,d):null}},createCallback:function(){var a=arguments,b=this;return function(){return b.apply(window,a)}},createDelegate:function(c,b,a){var d=this;return function(){var f=b||arguments;if(a===true){f=Array.prototype.slice.call(arguments,0);f=f.concat(b)}else{if(Ext.isNumber(a)){f=Array.prototype.slice.call(arguments,0);var e=[a,0].concat(b);Array.prototype.splice.apply(f,e)}}return d.apply(c||window,f)}},defer:function(c,e,b,a){var d=this.createDelegate(e,b,a);if(c>0){return setTimeout(d,c)}d();return 0}});Ext.applyIf(String,{format:function(b){var a=Ext.toArray(arguments,1);return b.replace(/\{(\d+)\}/g,function(c,d){return a[d]})}});Ext.applyIf(Array.prototype,{indexOf:function(b,c){var a=this.length;c=c||0;c+=(c<0)?a:0;for(;c<a;++c){if(this[c]===b){return c}}return -1},remove:function(b){var a=this.indexOf(b);if(a!=-1){this.splice(a,1)}return this}});Ext.util.TaskRunner=function(e){e=e||10;var f=[],a=[],b=0,g=false,d=function(){g=false;clearInterval(b);b=0},h=function(){if(!g){g=true;b=setInterval(i,e)}},c=function(j){a.push(j);if(j.onStop){j.onStop.apply(j.scope||j)}},i=function(){var l=a.length,n=new Date().getTime();if(l>0){for(var p=0;p<l;p++){f.remove(a[p])}a=[];if(f.length<1){d();return}}for(var p=0,o,k,m,j=f.length;p<j;++p){o=f[p];k=n-o.taskRunTime;if(o.interval<=k){m=o.run.apply(o.scope||o,o.args||[++o.taskRunCount]);o.taskRunTime=n;if(m===false||o.taskRunCount===o.repeat){c(o);return}}if(o.duration&&o.duration<=(n-o.taskStartTime)){c(o)}}};this.start=function(j){f.push(j);j.taskStartTime=new Date().getTime();j.taskRunTime=0;j.taskRunCount=0;h();return j};this.stop=function(j){c(j);return j};this.stopAll=function(){d();for(var k=0,j=f.length;k<j;k++){if(f[k].onStop){f[k].onStop()}}f=[];a=[]}};Ext.TaskMgr=new Ext.util.TaskRunner();(function(){var b;function c(d){if(!b){b=new Ext.Element.Flyweight()}b.dom=d;return b}(function(){var g=document,e=g.compatMode=="CSS1Compat",f=Math.max,d=Math.round,h=parseInt;Ext.lib.Dom={isAncestor:function(j,k){var i=false;j=Ext.getDom(j);k=Ext.getDom(k);if(j&&k){if(j.contains){return j.contains(k)}else{if(j.compareDocumentPosition){return !!(j.compareDocumentPosition(k)&16)}else{while(k=k.parentNode){i=k==j||i}}}}return i},getViewWidth:function(i){return i?this.getDocumentWidth():this.getViewportWidth()},getViewHeight:function(i){return i?this.getDocumentHeight():this.getViewportHeight()},getDocumentHeight:function(){return f(!e?g.body.scrollHeight:g.documentElement.scrollHeight,this.getViewportHeight())},getDocumentWidth:function(){return f(!e?g.body.scrollWidth:g.documentElement.scrollWidth,this.getViewportWidth())},getViewportHeight:function(){return Ext.isIE9m?(Ext.isStrict?g.documentElement.clientHeight:g.body.clientHeight):self.innerHeight},getViewportWidth:function(){return !Ext.isStrict&&!Ext.isOpera?g.body.clientWidth:Ext.isIE9m?g.documentElement.clientWidth:self.innerWidth},getY:function(i){return this.getXY(i)[1]},getX:function(i){return this.getXY(i)[0]},getXY:function(k){var j,q,s,v,l,m,u=0,r=0,t,i,n=(g.body||g.documentElement),o=[0,0];k=Ext.getDom(k);if(k!=n){if(k.getBoundingClientRect){s=k.getBoundingClientRect();t=c(document).getScroll();o=[d(s.left+t.left),d(s.top+t.top)]}else{j=k;i=c(k).isStyle("position","absolute");while(j){q=c(j);u+=j.offsetLeft;r+=j.offsetTop;i=i||q.isStyle("position","absolute");if(Ext.isGecko){r+=v=h(q.getStyle("borderTopWidth"),10)||0;u+=l=h(q.getStyle("borderLeftWidth"),10)||0;if(j!=k&&!q.isStyle("overflow","visible")){u+=l;r+=v}}j=j.offsetParent}if(Ext.isSafari&&i){u-=n.offsetLeft;r-=n.offsetTop}if(Ext.isGecko&&!i){m=c(n);u+=h(m.getStyle("borderLeftWidth"),10)||0;r+=h(m.getStyle("borderTopWidth"),10)||0}j=k.parentNode;while(j&&j!=n){if(!Ext.isOpera||(j.tagName!="TR"&&!c(j).isStyle("display","inline"))){u-=j.scrollLeft;r-=j.scrollTop}j=j.parentNode}o=[u,r]}}return o},setXY:function(j,k){(j=Ext.fly(j,"_setXY")).position();var l=j.translatePoints(k),i=j.dom.style,m;for(m in l){if(!isNaN(l[m])){i[m]=l[m]+"px"}}},setX:function(j,i){this.setXY(j,[i,false])},setY:function(i,j){this.setXY(i,[false,j])}}})();Ext.lib.Event=function(){var v=false,f={},z=0,o=[],d,A=false,k=window,E=document,l=200,r=20,p=0,i=1,s=2,w=3,t="scrollLeft",q="scrollTop",g="unload",y="mouseover",D="mouseout",e=function(){var F;if(k.addEventListener){F=function(J,H,I,G){if(H=="mouseenter"){I=I.createInterceptor(n);J.addEventListener(y,I,(G))}else{if(H=="mouseleave"){I=I.createInterceptor(n);J.addEventListener(D,I,(G))}else{J.addEventListener(H,I,(G))}}return I}}else{if(k.attachEvent){F=function(J,H,I,G){J.attachEvent("on"+H,I);return I}}else{F=function(){}}}return F}(),h=function(){var F;if(k.removeEventListener){F=function(J,H,I,G){if(H=="mouseenter"){H=y}else{if(H=="mouseleave"){H=D}}J.removeEventListener(H,I,(G))}}else{if(k.detachEvent){F=function(I,G,H){I.detachEvent("on"+G,H)}}else{F=function(){}}}return F}();function n(F){return !u(F.currentTarget,x.getRelatedTarget(F))}function u(F,G){if(F&&F.firstChild){while(G){if(G===F){return true}G=G.parentNode;if(G&&(G.nodeType!=1)){G=null}}}return false}function B(){var G=false,L=[],J,I,F,H,K=!v||(z>0);if(!A){A=true;for(I=0;I<o.length;++I){F=o[I];if(F&&(J=E.getElementById(F.id))){if(!F.checkReady||v||J.nextSibling||(E&&E.body)){H=F.override;J=H?(H===true?F.obj:H):J;F.fn.call(J,F.obj);o.remove(F);--I}else{L.push(F)}}}z=(L.length===0)?0:z-1;if(K){m()}else{clearInterval(d);d=null}G=!(A=false)}return G}function m(){if(!d){var F=function(){B()};d=setInterval(F,r)}}function C(){var F=E.documentElement,G=E.body;if(F&&(F[q]||F[t])){return[F[t],F[q]]}else{if(G){return[G[t],G[q]]}else{return[0,0]}}}function j(F,G){F=F.browserEvent||F;var H=F["page"+G];if(!H&&H!==0){H=F["client"+G]||0;if(Ext.isIE){H+=C()[G=="X"?0:1]}}return H}var x={extAdapter:true,onAvailable:function(H,F,I,G){o.push({id:H,fn:F,obj:I,override:G,checkReady:false});z=l;m()},addListener:function(H,F,G){H=Ext.getDom(H);if(H&&G){if(F==g){if(f[H.id]===undefined){f[H.id]=[]}f[H.id].push([F,G]);return G}return e(H,F,G,false)}return false},removeListener:function(L,H,K){L=Ext.getDom(L);var J,G,F,I;if(L&&K){if(H==g){if((I=f[L.id])!==undefined){for(J=0,G=I.length;J<G;J++){if((F=I[J])&&F[p]==H&&F[i]==K){f[L.id].splice(J,1)}}}return}h(L,H,K,false)}},getTarget:function(F){F=F.browserEvent||F;return this.resolveTextNode(F.target||F.srcElement)},resolveTextNode:Ext.isGecko?function(G){if(!G){return}var F=HTMLElement.prototype.toString.call(G);if(F=="[xpconnect wrapped native prototype]"||F=="[object XULElement]"){return}return G.nodeType==3?G.parentNode:G}:function(F){return F&&F.nodeType==3?F.parentNode:F},getRelatedTarget:function(F){F=F.browserEvent||F;return this.resolveTextNode(F.relatedTarget||(/(mouseout|mouseleave)/.test(F.type)?F.toElement:/(mouseover|mouseenter)/.test(F.type)?F.fromElement:null))},getPageX:function(F){return j(F,"X")},getPageY:function(F){return j(F,"Y")},getXY:function(F){return[this.getPageX(F),this.getPageY(F)]},stopEvent:function(F){this.stopPropagation(F);this.preventDefault(F)},stopPropagation:function(F){F=F.browserEvent||F;if(F.stopPropagation){F.stopPropagation()}else{F.cancelBubble=true}},preventDefault:function(F){F=F.browserEvent||F;if(F.preventDefault){F.preventDefault()}else{if(F.keyCode){F.keyCode=0}F.returnValue=false}},getEvent:function(F){F=F||k.event;if(!F){var G=this.getEvent.caller;while(G){F=G.arguments[0];if(F&&Event==F.constructor){break}G=G.caller}}return F},getCharCode:function(F){F=F.browserEvent||F;return F.charCode||F.keyCode||0},getListeners:function(G,F){Ext.EventManager.getListeners(G,F)},purgeElement:function(G,H,F){Ext.EventManager.purgeElement(G,H,F)},_load:function(F){v=true;if(Ext.isIE9m&&F!==true){h(k,"load",arguments.callee)}},_unload:function(J){var G=Ext.lib.Event,H,M,K,F,I,N;for(F in f){K=f[F];for(H=0,I=K.length;H<I;H++){M=K[H];if(M){try{N=M[w]?(M[w]===true?M[s]:M[w]):k;M[i].call(N,G.getEvent(J),M[s])}catch(L){}}}}Ext.EventManager._unload();h(k,g,G._unload)}};x.on=x.addListener;x.un=x.removeListener;if(E&&E.body){x._load(true)}else{e(k,"load",x._load)}e(k,g,x._unload);B();return x}();Ext.lib.Ajax=function(){var g=["Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP"],d="Content-Type";function h(v){var t=v.conn,w,u={};function s(x,y){for(w in y){if(y.hasOwnProperty(w)){x.setRequestHeader(w,y[w])}}}Ext.apply(u,k.headers,k.defaultHeaders);s(t,u);delete k.headers}function e(v,u,t,s){return{tId:v,status:t?-1:0,statusText:t?"transaction aborted":"communication failure",isAbort:t,isTimeout:s,argument:u}}function j(s,t){(k.headers=k.headers||{})[s]=t}function p(u,y){var C={},x,w=u.conn,A,B,v=w.status==1223;try{x=u.conn.getAllResponseHeaders();Ext.each(x.replace(/\r\n/g,"\n").split("\n"),function(s){A=s.indexOf(":");if(A>=0){B=s.substr(0,A).toLowerCase();if(s.charAt(A+1)==" "){++A}C[B]=s.substr(A+1)}})}catch(z){}return{tId:u.tId,status:v?204:w.status,statusText:v?"No Content":w.statusText,getResponseHeader:function(s){return C[s.toLowerCase()]},getAllResponseHeaders:function(){return x},responseText:w.responseText,responseXML:w.responseXML,argument:y}}function o(s){if(s.tId){k.conn[s.tId]=null}s.conn=null;s=null}function f(x,y,t,s){if(!y){o(x);return}var v,u;try{if(x.conn.status!==undefined&&x.conn.status!=0){v=x.conn.status}else{v=13030}}catch(w){v=13030}if((v>=200&&v<300)||(Ext.isIE&&v==1223)){u=p(x,y.argument);if(y.success){if(!y.scope){y.success(u)}else{y.success.apply(y.scope,[u])}}}else{switch(v){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:u=e(x.tId,y.argument,(t?t:false),s);if(y.failure){if(!y.scope){y.failure(u)}else{y.failure.apply(y.scope,[u])}}break;default:u=p(x,y.argument);if(y.failure){if(!y.scope){y.failure(u)}else{y.failure.apply(y.scope,[u])}}}}o(x);u=null}function m(u,x,s,w,t,v){if(s&&s.readyState==4){clearInterval(t[w]);t[w]=null;if(v){clearTimeout(k.timeout[w]);k.timeout[w]=null}f(u,x)}}function r(s,t){k.abort(s,t,true)}function n(u,x){x=x||{};var s=u.conn,w=u.tId,t=k.poll,v=x.timeout||null;if(v){k.conn[w]=s;k.timeout[w]=setTimeout(r.createCallback(u,x),v)}t[w]=setInterval(m.createCallback(u,x,s,w,t,v),k.pollInterval)}function i(w,t,v,s){var u=l()||null;if(u){u.conn.open(w,t,true);if(k.useDefaultXhrHeader){j("X-Requested-With",k.defaultXhrHeader)}if(s&&k.useDefaultHeader&&(!k.headers||!k.headers[d])){j(d,k.defaultPostHeader)}if(k.defaultHeaders||k.headers){h(u)}n(u,v);u.conn.send(s||null)}return u}function l(){var t;try{if(t=q(k.transactionId)){k.transactionId++}}catch(s){}finally{return t}}function q(v){var s;try{s=new XMLHttpRequest()}catch(u){for(var t=Ext.isIE6?1:0;t<g.length;++t){try{s=new ActiveXObject(g[t]);break}catch(u){}}}finally{return{conn:s,tId:v}}}var k={request:function(s,u,v,w,A){if(A){var x=this,t=A.xmlData,y=A.jsonData,z;Ext.applyIf(x,A);if(t||y){z=x.headers;if(!z||!z[d]){j(d,t?"text/xml":"application/json")}w=t||(!Ext.isPrimitive(y)?Ext.encode(y):y)}}return i(s||A.method||"POST",u,v,w)},serializeForm:function(y){var x=y.elements||(document.forms[y]||Ext.getDom(y)).elements,s=false,w=encodeURIComponent,t,z="",v,u;Ext.each(x,function(A){t=A.name;v=A.type;if(!A.disabled&&t){if(/select-(one|multiple)/i.test(v)){Ext.each(A.options,function(B){if(B.selected){u=B.hasAttribute?B.hasAttribute("value"):B.getAttributeNode("value").specified;z+=String.format("{0}={1}&",w(t),w(u?B.value:B.text))}})}else{if(!(/file|undefined|reset|button/i.test(v))){if(!(/radio|checkbox/i.test(v)&&!A.checked)&&!(v=="submit"&&s)){z+=w(t)+"="+w(A.value)+"&";s=/submit/i.test(v)}}}}});return z.substr(0,z.length-1)},useDefaultHeader:true,defaultPostHeader:"application/x-www-form-urlencoded; charset=UTF-8",useDefaultXhrHeader:true,defaultXhrHeader:"XMLHttpRequest",poll:{},timeout:{},conn:{},pollInterval:50,transactionId:0,abort:function(v,x,s){var u=this,w=v.tId,t=false;if(u.isCallInProgress(v)){v.conn.abort();clearInterval(u.poll[w]);u.poll[w]=null;clearTimeout(k.timeout[w]);u.timeout[w]=null;f(v,x,(t=true),s)}return t},isCallInProgress:function(s){return s.conn&&!{0:true,4:true}[s.conn.readyState]}};return k}();(function(){var g=Ext.lib,i=/width|height|opacity|padding/i,f=/^((width|height)|(top|left))$/,d=/width|height|top$|bottom$|left$|right$/i,h=/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,j=function(k){return typeof k!=="undefined"},e=function(){return new Date()};g.Anim={motion:function(n,l,o,p,k,m){return this.run(n,l,o,p,k,m,Ext.lib.Motion)},run:function(o,l,q,r,k,n,m){m=m||Ext.lib.AnimBase;if(typeof r=="string"){r=Ext.lib.Easing[r]}var p=new m(o,l,q,r);p.animateX(function(){if(Ext.isFunction(k)){k.call(n)}});return p}};g.AnimBase=function(l,k,m,n){if(l){this.init(l,k,m,n)}};g.AnimBase.prototype={doMethod:function(k,n,l){var m=this;return m.method(m.curFrame,n,l-n,m.totalFrames)},setAttr:function(k,m,l){if(i.test(k)&&m<0){m=0}Ext.fly(this.el,"_anim").setStyle(k,m+l)},getAttr:function(k){var m=Ext.fly(this.el),n=m.getStyle(k),l=f.exec(k)||[];if(n!=="auto"&&!h.test(n)){return parseFloat(n)}return(!!(l[2])||(m.getStyle("position")=="absolute"&&!!(l[3])))?m.dom["offset"+l[0].charAt(0).toUpperCase()+l[0].substr(1)]:0},getDefaultUnit:function(k){return d.test(k)?"px":""},animateX:function(n,k){var l=this,m=function(){l.onComplete.removeListener(m);if(Ext.isFunction(n)){n.call(k||l,l)}};l.onComplete.addListener(m,l);l.animate()},setRunAttr:function(p){var r=this,s=this.attributes[p],t=s.to,q=s.by,u=s.from,v=s.unit,l=(this.runAttrs[p]={}),m;if(!j(t)&&!j(q)){return false}var k=j(u)?u:r.getAttr(p);if(j(t)){m=t}else{if(j(q)){if(Ext.isArray(k)){m=[];for(var n=0,o=k.length;n<o;n++){m[n]=k[n]+q[n]}}else{m=k+q}}}Ext.apply(l,{start:k,end:m,unit:j(v)?v:r.getDefaultUnit(p)})},init:function(l,p,o,k){var r=this,n=0,s=g.AnimMgr;Ext.apply(r,{isAnimated:false,startTime:null,el:Ext.getDom(l),attributes:p||{},duration:o||1,method:k||g.Easing.easeNone,useSec:true,curFrame:0,totalFrames:s.fps,runAttrs:{},animate:function(){var u=this,v=u.duration;if(u.isAnimated){return false}u.curFrame=0;u.totalFrames=u.useSec?Math.ceil(s.fps*v):v;s.registerElement(u)},stop:function(u){var v=this;if(u){v.curFrame=v.totalFrames;v._onTween.fire()}s.stop(v)}});var t=function(){var v=this,u;v.onStart.fire();v.runAttrs={};for(u in this.attributes){this.setRunAttr(u)}v.isAnimated=true;v.startTime=e();n=0};var q=function(){var v=this;v.onTween.fire({duration:e()-v.startTime,curFrame:v.curFrame});var w=v.runAttrs;for(var u in w){this.setAttr(u,v.doMethod(u,w[u].start,w[u].end),w[u].unit)}++n};var m=function(){var u=this,w=(e()-u.startTime)/1000,v={duration:w,frames:n,fps:n/w};u.isAnimated=false;n=0;u.onComplete.fire(v)};r.onStart=new Ext.util.Event(r);r.onTween=new Ext.util.Event(r);r.onComplete=new Ext.util.Event(r);(r._onStart=new Ext.util.Event(r)).addListener(t);(r._onTween=new Ext.util.Event(r)).addListener(q);(r._onComplete=new Ext.util.Event(r)).addListener(m)}};Ext.lib.AnimMgr=new function(){var o=this,m=null,l=[],k=0;Ext.apply(o,{fps:1000,delay:1,registerElement:function(q){l.push(q);++k;q._onStart.fire();o.start()},unRegister:function(r,q){r._onComplete.fire();q=q||p(r);if(q!=-1){l.splice(q,1)}if(--k<=0){o.stop()}},start:function(){if(m===null){m=setInterval(o.run,o.delay)}},stop:function(s){if(!s){clearInterval(m);for(var r=0,q=l.length;r<q;++r){if(l[0].isAnimated){o.unRegister(l[0],0)}}l=[];m=null;k=0}else{o.unRegister(s)}},run:function(){var t,s,q,r;for(s=0,q=l.length;s<q;s++){r=l[s];if(r&&r.isAnimated){t=r.totalFrames;if(r.curFrame<t||t===null){++r.curFrame;if(r.useSec){n(r)}r._onTween.fire()}else{o.stop(r)}}}}});var p=function(s){var r,q;for(r=0,q=l.length;r<q;r++){if(l[r]===s){return r}}return -1};var n=function(r){var v=r.totalFrames,u=r.curFrame,t=r.duration,s=(u*t*1000/v),q=(e()-r.startTime),w=0;if(q<t*1000){w=Math.round((q/s-1)*u)}else{w=v-(u+1)}if(w>0&&isFinite(w)){if(r.curFrame+w>=v){w=v-(u+1)}r.curFrame+=w}}};g.Bezier=new function(){this.getPosition=function(p,o){var r=p.length,m=[],q=1-o,l,k;for(l=0;l<r;++l){m[l]=[p[l][0],p[l][1]]}for(k=1;k<r;++k){for(l=0;l<r-k;++l){m[l][0]=q*m[l][0]+o*m[parseInt(l+1,10)][0];m[l][1]=q*m[l][1]+o*m[parseInt(l+1,10)][1]}}return[m[0][0],m[0][1]]}};g.Easing={easeNone:function(l,k,n,m){return n*l/m+k},easeIn:function(l,k,n,m){return n*(l/=m)*l+k},easeOut:function(l,k,n,m){return -n*(l/=m)*(l-2)+k}};(function(){g.Motion=function(o,n,p,q){if(o){g.Motion.superclass.constructor.call(this,o,n,p,q)}};Ext.extend(g.Motion,Ext.lib.AnimBase);var m=g.Motion.superclass,l=/^points$/i;Ext.apply(g.Motion.prototype,{setAttr:function(n,r,q){var p=this,o=m.setAttr;if(l.test(n)){q=q||"px";o.call(p,"left",r[0],q);o.call(p,"top",r[1],q)}else{o.call(p,n,r,q)}},getAttr:function(n){var p=this,o=m.getAttr;return l.test(n)?[o.call(p,"left"),o.call(p,"top")]:o.call(p,n)},doMethod:function(n,q,o){var p=this;return l.test(n)?g.Bezier.getPosition(p.runAttrs[n],p.method(p.curFrame,0,100,p.totalFrames)/100):m.doMethod.call(p,n,q,o)},setRunAttr:function(u){if(l.test(u)){var w=this,p=this.el,z=this.attributes.points,s=z.control||[],x=z.from,y=z.to,v=z.by,A=g.Dom,o,r,q,t,n;if(s.length>0&&!Ext.isArray(s[0])){s=[s]}else{}Ext.fly(p,"_anim").position();A.setXY(p,j(x)?x:A.getXY(p));o=w.getAttr("points");if(j(y)){q=k.call(w,y,o);for(r=0,t=s.length;r<t;++r){s[r]=k.call(w,s[r],o)}}else{if(j(v)){q=[o[0]+v[0],o[1]+v[1]];for(r=0,t=s.length;r<t;++r){s[r]=[o[0]+s[r][0],o[1]+s[r][1]]}}}n=this.runAttrs[u]=[o];if(s.length>0){n=n.concat(s)}n[n.length]=q}else{m.setRunAttr.call(this,u)}}});var k=function(n,p){var o=g.Dom.getXY(this.el);return[n[0]-o[0]+p[0],n[1]-o[1]+p[1]]}})()})();(function(){var d=Math.abs,i=Math.PI,h=Math.asin,g=Math.pow,e=Math.sin,f=Ext.lib;Ext.apply(f.Easing,{easeBoth:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k+j:-m/2*((--k)*(k-2)-1)+j},easeInStrong:function(k,j,m,l){return m*(k/=l)*k*k*k+j},easeOutStrong:function(k,j,m,l){return -m*((k=k/l-1)*k*k*k-1)+j},easeBothStrong:function(k,j,m,l){return((k/=l/2)<1)?m/2*k*k*k*k+j:-m/2*((k-=2)*k*k*k-2)+j},elasticIn:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return -(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j},elasticOut:function(l,j,q,o,k,n){if(l==0||(l/=o)==1){return l==0?j:j+q}n=n||(o*0.3);var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return k*g(2,-10*l)*e((l*o-m)*(2*i)/n)+q+j},elasticBoth:function(l,j,q,o,k,n){if(l==0||(l/=o/2)==2){return l==0?j:j+q}n=n||(o*(0.3*1.5));var m;if(k>=d(q)){m=n/(2*i)*h(q/k)}else{k=q;m=n/4}return l<1?-0.5*(k*g(2,10*(l-=1))*e((l*o-m)*(2*i)/n))+j:k*g(2,-10*(l-=1))*e((l*o-m)*(2*i)/n)*0.5+q+j},backIn:function(k,j,n,m,l){l=l||1.70158;return n*(k/=m)*k*((l+1)*k-l)+j},backOut:function(k,j,n,m,l){if(!l){l=1.70158}return n*((k=k/m-1)*k*((l+1)*k+l)+1)+j},backBoth:function(k,j,n,m,l){l=l||1.70158;return((k/=m/2)<1)?n/2*(k*k*(((l*=(1.525))+1)*k-l))+j:n/2*((k-=2)*k*(((l*=(1.525))+1)*k+l)+2)+j},bounceIn:function(k,j,m,l){return m-f.Easing.bounceOut(l-k,0,m,l)+j},bounceOut:function(k,j,m,l){if((k/=l)<(1/2.75)){return m*(7.5625*k*k)+j}else{if(k<(2/2.75)){return m*(7.5625*(k-=(1.5/2.75))*k+0.75)+j}else{if(k<(2.5/2.75)){return m*(7.5625*(k-=(2.25/2.75))*k+0.9375)+j}}}return m*(7.5625*(k-=(2.625/2.75))*k+0.984375)+j},bounceBoth:function(k,j,m,l){return(k<l/2)?f.Easing.bounceIn(k*2,0,m,l)*0.5+j:f.Easing.bounceOut(k*2-l,0,m,l)*0.5+m*0.5+j}})})();(function(){var h=Ext.lib;h.Anim.color=function(p,n,q,r,m,o){return h.Anim.run(p,n,q,r,m,o,h.ColorAnim)};h.ColorAnim=function(n,m,o,p){h.ColorAnim.superclass.constructor.call(this,n,m,o,p)};Ext.extend(h.ColorAnim,h.AnimBase);var j=h.ColorAnim.superclass,i=/color$/i,f=/^transparent|rgba\(0, 0, 0, 0\)$/,l=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,d=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,e=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,g=function(m){return typeof m!=="undefined"};function k(n){var p=parseInt,o,m=null,q;if(n.length==3){return n}Ext.each([d,l,e],function(s,r){o=(r%2==0)?16:10;q=s.exec(n);if(q&&q.length==4){m=[p(q[1],o),p(q[2],o),p(q[3],o)];return false}});return m}Ext.apply(h.ColorAnim.prototype,{getAttr:function(m){var o=this,n=o.el,p;if(i.test(m)){while(n&&f.test(p=Ext.fly(n).getStyle(m))){n=n.parentNode;p="fff"}}else{p=j.getAttr.call(o,m)}return p},doMethod:function(s,m,o){var t=this,n,q=Math.floor,p,r,u;if(i.test(s)){n=[];o=o||[];for(p=0,r=m.length;p<r;p++){u=m[p];n[p]=j.doMethod.call(t,s,u,o[p])}n="rgb("+q(n[0])+","+q(n[1])+","+q(n[2])+")"}else{n=j.doMethod.call(t,s,m,o)}return n},setRunAttr:function(r){var t=this,u=t.attributes[r],v=u.to,s=u.by,n;j.setRunAttr.call(t,r);n=t.runAttrs[r];if(i.test(r)){var m=k(n.start),o=k(n.end);if(!g(v)&&g(s)){o=k(s);for(var p=0,q=m.length;p<q;p++){o[p]=m[p]+o[p]}}n.start=m;n.end=o}}})})();(function(){var d=Ext.lib;d.Anim.scroll=function(j,h,k,l,g,i){return d.Anim.run(j,h,k,l,g,i,d.Scroll)};d.Scroll=function(h,g,i,j){if(h){d.Scroll.superclass.constructor.call(this,h,g,i,j)}};Ext.extend(d.Scroll,d.ColorAnim);var f=d.Scroll.superclass,e="scroll";Ext.apply(d.Scroll.prototype,{doMethod:function(g,m,h){var k,j=this,l=j.curFrame,i=j.totalFrames;if(g==e){k=[j.method(l,m[0],h[0]-m[0],i),j.method(l,m[1],h[1]-m[1],i)]}else{k=f.doMethod.call(j,g,m,h)}return k},getAttr:function(g){var h=this;if(g==e){return[h.el.scrollLeft,h.el.scrollTop]}else{return f.getAttr.call(h,g)}},setAttr:function(g,j,i){var h=this;if(g==e){h.el.scrollLeft=j[0];h.el.scrollTop=j[1]}else{f.setAttr.call(h,g,j,i)}}})})();if(Ext.isIE9m){function a(){var d=Function.prototype;delete d.createSequence;delete d.defer;delete d.createDelegate;delete d.createCallback;delete d.createInterceptor;window.detachEvent("onunload",a)}window.attachEvent("onunload",a)}})(); \ No newline at end of file
diff --git a/deluge/ui/web/js/extjs/ext-extensions-debug.js b/deluge/ui/web/js/extjs/ext-extensions-debug.js
new file mode 100644
index 0000000..a5b4a60
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions-debug.js
@@ -0,0 +1,2931 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ * @class Ext.ux.form.FileUploadField
+ * @extends Ext.form.TextField
+ * Creates a file upload field.
+ * @xtype fileuploadfield
+ */
+Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField, {
+ /**
+ * @cfg {String} buttonText The button text to display on the upload button (defaults to
+ * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text
+ * value will be used instead if available.
+ */
+ buttonText: 'Browse...',
+ /**
+ * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible
+ * text field (defaults to false). If true, all inherited TextField members will still be available.
+ */
+ buttonOnly: false,
+ /**
+ * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field
+ * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false.
+ */
+ buttonOffset: 3,
+
+ /**
+ * @cfg {Boolean} multiple True to select more than one file. (defaults to false).
+ * Note that this only applies if the HTML doc is using HTML5.
+ */
+ multiple: false,
+
+ /**
+ * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object.
+ */
+
+ // private
+ readOnly: true,
+
+ /**
+ * @hide
+ * @method autoSize
+ */
+ autoSize: Ext.emptyFn,
+
+ // private
+ initComponent: function() {
+ Ext.ux.form.FileUploadField.superclass.initComponent.call(this);
+
+ this.addEvents(
+ /**
+ * @event fileselected
+ * Fires when the underlying file input field's value has changed from the user
+ * selecting a new file from the system file selection dialog.
+ * @param {Ext.ux.form.FileUploadField} this
+ * @param {String} value The file value returned by the underlying file input field
+ */
+ 'fileselected'
+ );
+ },
+
+ // private
+ onRender: function(ct, position) {
+ Ext.ux.form.FileUploadField.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+
+ this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
+ this.el.addClass('x-form-file-text');
+ this.el.dom.removeAttribute('name');
+ this.createFileInput();
+
+ var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
+ text: this.buttonText,
+ });
+ this.button = new Ext.Button(
+ Ext.apply(btnCfg, {
+ renderTo: this.wrap,
+ cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : ''),
+ })
+ );
+
+ if (this.buttonOnly) {
+ this.el.hide();
+ this.wrap.setWidth(this.button.getEl().getWidth());
+ }
+
+ this.bindListeners();
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+
+ bindListeners: function() {
+ this.fileInput.on({
+ scope: this,
+ mouseenter: function() {
+ this.button.addClass(['x-btn-over', 'x-btn-focus']);
+ },
+ mouseleave: function() {
+ this.button.removeClass([
+ 'x-btn-over',
+ 'x-btn-focus',
+ 'x-btn-click',
+ ]);
+ },
+ mousedown: function() {
+ this.button.addClass('x-btn-click');
+ },
+ mouseup: function() {
+ this.button.removeClass([
+ 'x-btn-over',
+ 'x-btn-focus',
+ 'x-btn-click',
+ ]);
+ },
+ change: function() {
+ var value = this.fileInput.dom.files;
+ // Fallback to value.
+ if (!value) value = this.fileInput.dom.value;
+ this.setValue(value);
+ this.fireEvent('fileselected', this, value);
+ },
+ });
+ },
+
+ createFileInput: function() {
+ this.fileInput = this.wrap.createChild({
+ id: this.getFileInputId(),
+ name: this.name || this.getId(),
+ cls: 'x-form-file',
+ tag: 'input',
+ type: 'file',
+ size: 1,
+ });
+ this.fileInput.dom.multiple = this.multiple;
+ },
+
+ reset: function() {
+ if (this.rendered) {
+ this.fileInput.remove();
+ this.createFileInput();
+ this.bindListeners();
+ }
+ Ext.ux.form.FileUploadField.superclass.reset.call(this);
+ },
+
+ // private
+ getFileInputId: function() {
+ return this.id + '-file';
+ },
+
+ // private
+ onResize: function(w, h) {
+ Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);
+
+ this.wrap.setWidth(w);
+
+ if (!this.buttonOnly) {
+ var w =
+ this.wrap.getWidth() -
+ this.button.getEl().getWidth() -
+ this.buttonOffset;
+ this.el.setWidth(w);
+ }
+ },
+
+ // private
+ onDestroy: function() {
+ Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
+ Ext.destroy(this.fileInput, this.button, this.wrap);
+ },
+
+ onDisable: function() {
+ Ext.ux.form.FileUploadField.superclass.onDisable.call(this);
+ this.doDisable(true);
+ },
+
+ onEnable: function() {
+ Ext.ux.form.FileUploadField.superclass.onEnable.call(this);
+ this.doDisable(false);
+ },
+
+ // private
+ doDisable: function(disabled) {
+ this.fileInput.dom.disabled = disabled;
+ this.button.setDisabled(disabled);
+ },
+
+ // private
+ preFocus: Ext.emptyFn,
+
+ // private
+ alignErrorIcon: function() {
+ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
+ },
+});
+
+Ext.reg('fileuploadfield', Ext.ux.form.FileUploadField);
+
+// backwards compat
+Ext.form.FileUploadField = Ext.ux.form.FileUploadField;
+/**
+ * Ext.ux.form.RadioGroup.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Allow radiogroups to be treated as a single form element.
+Ext.override(Ext.form.RadioGroup, {
+ afterRender: function() {
+ this.items.each(function(i) {
+ this.relayEvents(i, ['check']);
+ }, this);
+ if (this.lazyValue) {
+ this.setValue(this.value);
+ delete this.value;
+ delete this.lazyValue;
+ }
+ Ext.form.RadioGroup.superclass.afterRender.call(this);
+ },
+
+ getName: function() {
+ return this.items.first().getName();
+ },
+
+ getValue: function() {
+ return this.items.first().getGroupValue();
+ },
+
+ setValue: function(v) {
+ if (!this.items.each) {
+ this.value = v;
+ this.lazyValue = true;
+ return;
+ }
+ this.items.each(function(item) {
+ if (item.rendered) {
+ var checked = item.el.getValue() == String(v);
+ item.el.dom.checked = checked;
+ item.el.dom.defaultChecked = checked;
+ item.wrap[checked ? 'addClass' : 'removeClass'](
+ item.checkedCls
+ );
+ }
+ });
+ },
+});
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ * @class Ext.ux.form.SpinnerField
+ * @extends Ext.form.NumberField
+ * Creates a field utilizing Ext.ux.Spinner
+ * @xtype spinnerfield
+ */
+Ext.ux.form.SpinnerField = Ext.extend(Ext.form.NumberField, {
+ actionMode: 'wrap',
+ deferHeight: true,
+ autoSize: Ext.emptyFn,
+ onBlur: Ext.emptyFn,
+ adjustSize: Ext.BoxComponent.prototype.adjustSize,
+
+ constructor: function(config) {
+ var spinnerConfig = Ext.copyTo(
+ {},
+ config,
+ 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass'
+ );
+
+ var spl = (this.spinner = new Ext.ux.Spinner(spinnerConfig));
+
+ var plugins = config.plugins
+ ? Ext.isArray(config.plugins)
+ ? config.plugins.push(spl)
+ : [config.plugins, spl]
+ : spl;
+
+ Ext.ux.form.SpinnerField.superclass.constructor.call(
+ this,
+ Ext.apply(config, { plugins: plugins })
+ );
+ },
+
+ // private
+ getResizeEl: function() {
+ return this.wrap;
+ },
+
+ // private
+ getPositionEl: function() {
+ return this.wrap;
+ },
+
+ // private
+ alignErrorIcon: function() {
+ if (this.wrap) {
+ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
+ }
+ },
+
+ validateBlur: function() {
+ return true;
+ },
+});
+
+Ext.reg('spinnerfield', Ext.ux.form.SpinnerField);
+
+//backwards compat
+Ext.form.SpinnerField = Ext.ux.form.SpinnerField;
+/**
+ * Ext.ux.form.SpinnerField.js
+ *
+ * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.override(Ext.ux.form.SpinnerField, {
+ onBlur: Ext.form.Field.prototype.onBlur,
+});
+/**
+ * Ext.ux.form.SpinnerGroup.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ *
+ */
+Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
+ // private
+ defaultType: 'spinnerfield',
+ anchor: '98%',
+
+ // private
+ groupCls: 'x-form-spinner-group',
+
+ colCfg: {},
+
+ // private
+ onRender: function(ct, position) {
+ if (!this.el) {
+ var panelCfg = {
+ cls: this.groupCls,
+ layout: 'column',
+ border: false,
+ renderTo: ct,
+ };
+ var colCfg = Ext.apply(
+ {
+ defaultType: this.defaultType,
+ layout: 'form',
+ border: false,
+ labelWidth: 60,
+ defaults: {
+ hideLabel: true,
+ anchor: '60%',
+ },
+ },
+ this.colCfg
+ );
+
+ if (this.items[0].items) {
+ // The container has standard ColumnLayout configs, so pass them in directly
+
+ Ext.apply(panelCfg, {
+ layoutConfig: { columns: this.items.length },
+ defaults: this.defaults,
+ items: this.items,
+ });
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ Ext.applyIf(this.items[i], colCfg);
+ }
+ } else {
+ // The container has field item configs, so we have to generate the column
+ // panels first then move the items into the columns as needed.
+
+ var numCols,
+ cols = [];
+
+ if (typeof this.columns == 'string') {
+ // 'auto' so create a col per item
+ this.columns = this.items.length;
+ }
+ if (!Ext.isArray(this.columns)) {
+ var cs = [];
+ for (var i = 0; i < this.columns; i++) {
+ cs.push((100 / this.columns) * 0.01); // distribute by even %
+ }
+ this.columns = cs;
+ }
+
+ numCols = this.columns.length;
+
+ // Generate the column configs with the correct width setting
+ for (var i = 0; i < numCols; i++) {
+ var cc = Ext.apply({ items: [] }, colCfg);
+ cc[
+ this.columns[i] <= 1 ? 'columnWidth' : 'width'
+ ] = this.columns[i];
+ if (this.defaults) {
+ cc.defaults = Ext.apply(
+ cc.defaults || {},
+ this.defaults
+ );
+ }
+ cols.push(cc);
+ }
+
+ // Distribute the original items into the columns
+ if (this.vertical) {
+ var rows = Math.ceil(this.items.length / numCols),
+ ri = 0;
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ if (i > 0 && i % rows == 0) {
+ ri++;
+ }
+ if (this.items[i].fieldLabel) {
+ this.items[i].hideLabel = false;
+ }
+ cols[ri].items.push(this.items[i]);
+ }
+ } else {
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ var ci = i % numCols;
+ if (this.items[i].fieldLabel) {
+ this.items[i].hideLabel = false;
+ }
+ cols[ci].items.push(this.items[i]);
+ }
+ }
+
+ Ext.apply(panelCfg, {
+ layoutConfig: { columns: numCols },
+ items: cols,
+ });
+ }
+
+ this.panel = new Ext.Panel(panelCfg);
+ this.el = this.panel.getEl();
+
+ if (this.forId && this.itemCls) {
+ var l = this.el.up(this.itemCls).child('label', true);
+ if (l) {
+ l.setAttribute('htmlFor', this.forId);
+ }
+ }
+
+ var fields = this.panel.findBy(function(c) {
+ return c.isFormField;
+ }, this);
+
+ this.items = new Ext.util.MixedCollection();
+ this.items.addAll(fields);
+
+ this.items.each(function(field) {
+ field.on('spin', this.onFieldChange, this);
+ field.on('change', this.onFieldChange, this);
+ }, this);
+
+ if (this.lazyValueSet) {
+ this.setValue(this.value);
+ delete this.value;
+ delete this.lazyValueSet;
+ }
+
+ if (this.lazyRawValueSet) {
+ this.setRawValue(this.rawValue);
+ delete this.rawValue;
+ delete this.lazyRawValueSet;
+ }
+ }
+
+ Ext.ux.form.SpinnerGroup.superclass.onRender.call(this, ct, position);
+ },
+
+ onFieldChange: function(spinner) {
+ this.fireEvent('change', this, this.getValue());
+ },
+
+ initValue: Ext.emptyFn,
+
+ getValue: function() {
+ var value = [this.items.getCount()];
+ this.items.each(function(item, i) {
+ value[i] = Number(item.getValue());
+ });
+ return value;
+ },
+
+ getRawValue: function() {
+ var value = [this.items.getCount()];
+ this.items.each(function(item, i) {
+ value[i] = Number(item.getRawValue());
+ });
+ return value;
+ },
+
+ setValue: function(value) {
+ if (!this.rendered) {
+ this.value = value;
+ this.lazyValueSet = true;
+ } else {
+ this.items.each(function(item, i) {
+ item.setValue(value[i]);
+ });
+ }
+ },
+
+ setRawValue: function(value) {
+ if (!this.rendered) {
+ this.rawValue = value;
+ this.lazyRawValueSet = true;
+ } else {
+ this.items.each(function(item, i) {
+ item.setRawValue(value[i]);
+ });
+ }
+ },
+});
+Ext.reg('spinnergroup', Ext.ux.form.SpinnerGroup);
+/**
+ * Ext.ux.form.ToggleField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.ux.form');
+
+/**
+ * Ext.ux.form.ToggleField class
+ *
+ * @author Damien Churchill
+ * @version v0.1
+ *
+ * @class Ext.ux.form.ToggleField
+ * @extends Ext.form.TriggerField
+ */
+Ext.ux.form.ToggleField = Ext.extend(Ext.form.Field, {
+ cls: 'x-toggle-field',
+
+ initComponent: function() {
+ Ext.ux.form.ToggleField.superclass.initComponent.call(this);
+
+ this.toggle = new Ext.form.Checkbox();
+ this.toggle.on('check', this.onToggleCheck, this);
+
+ this.input = new Ext.form.TextField({
+ disabled: true,
+ });
+ },
+
+ onRender: function(ct, position) {
+ if (!this.el) {
+ this.panel = new Ext.Panel({
+ cls: this.groupCls,
+ layout: 'table',
+ layoutConfig: {
+ columns: 2,
+ },
+ border: false,
+ renderTo: ct,
+ });
+ this.panel.ownerCt = this;
+ this.el = this.panel.getEl();
+
+ this.panel.add(this.toggle);
+ this.panel.add(this.input);
+ this.panel.doLayout();
+
+ this.toggle
+ .getEl()
+ .parent()
+ .setStyle('padding-right', '10px');
+ }
+ Ext.ux.form.ToggleField.superclass.onRender.call(this, ct, position);
+ },
+
+ // private
+ onResize: function(w, h) {
+ this.panel.setSize(w, h);
+ this.panel.doLayout();
+
+ // we substract 10 for the padding :-)
+ var inputWidth = w - this.toggle.getSize().width - 25;
+ this.input.setSize(inputWidth, h);
+ },
+
+ onToggleCheck: function(toggle, checked) {
+ this.input.setDisabled(!checked);
+ },
+});
+Ext.reg('togglefield', Ext.ux.form.ToggleField);
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.grid');
+
+/**
+ * @class Ext.ux.grid.BufferView
+ * @extends Ext.grid.GridView
+ * A custom GridView which renders rows on an as-needed basis.
+ */
+Ext.ux.grid.BufferView = Ext.extend(Ext.grid.GridView, {
+ /**
+ * @cfg {Number} rowHeight
+ * The height of a row in the grid.
+ */
+ rowHeight: 19,
+
+ /**
+ * @cfg {Number} borderHeight
+ * The combined height of border-top and border-bottom of a row.
+ */
+ borderHeight: 2,
+
+ /**
+ * @cfg {Boolean/Number} scrollDelay
+ * The number of milliseconds before rendering rows out of the visible
+ * viewing area. Defaults to 100. Rows will render immediately with a config
+ * of false.
+ */
+ scrollDelay: 100,
+
+ /**
+ * @cfg {Number} cacheSize
+ * The number of rows to look forward and backwards from the currently viewable
+ * area. The cache applies only to rows that have been rendered already.
+ */
+ cacheSize: 20,
+
+ /**
+ * @cfg {Number} cleanDelay
+ * The number of milliseconds to buffer cleaning of extra rows not in the
+ * cache.
+ */
+ cleanDelay: 500,
+
+ initTemplates: function() {
+ Ext.ux.grid.BufferView.superclass.initTemplates.call(this);
+ var ts = this.templates;
+ // empty div to act as a place holder for a row
+ ts.rowHolder = new Ext.Template(
+ '<div class="x-grid3-row {alt}" style="{tstyle}"></div>'
+ );
+ ts.rowHolder.disableFormats = true;
+ ts.rowHolder.compile();
+
+ ts.rowBody = new Ext.Template(
+ '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+ '<tbody><tr>{cells}</tr>',
+ this.enableRowBody
+ ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>'
+ : '',
+ '</tbody></table>'
+ );
+ ts.rowBody.disableFormats = true;
+ ts.rowBody.compile();
+ },
+
+ getStyleRowHeight: function() {
+ return Ext.isBorderBox
+ ? this.rowHeight + this.borderHeight
+ : this.rowHeight;
+ },
+
+ getCalculatedRowHeight: function() {
+ return this.rowHeight + this.borderHeight;
+ },
+
+ getVisibleRowCount: function() {
+ var rh = this.getCalculatedRowHeight(),
+ visibleHeight = this.scroller.dom.clientHeight;
+ return visibleHeight < 1 ? 0 : Math.ceil(visibleHeight / rh);
+ },
+
+ getVisibleRows: function() {
+ var count = this.getVisibleRowCount(),
+ sc = this.scroller.dom.scrollTop,
+ start =
+ sc === 0
+ ? 0
+ : Math.floor(sc / this.getCalculatedRowHeight()) - 1;
+ return {
+ first: Math.max(start, 0),
+ last: Math.min(start + count + 2, this.ds.getCount() - 1),
+ };
+ },
+
+ doRender: function(cs, rs, ds, startRow, colCount, stripe, onlyBody) {
+ var ts = this.templates,
+ ct = ts.cell,
+ rt = ts.row,
+ rb = ts.rowBody,
+ last = colCount - 1,
+ rh = this.getStyleRowHeight(),
+ vr = this.getVisibleRows(),
+ tstyle = 'width:' + this.getTotalWidth() + ';height:' + rh + 'px;',
+ // buffers
+ buf = [],
+ cb,
+ c,
+ p = {},
+ rp = { tstyle: tstyle },
+ r;
+ for (var j = 0, len = rs.length; j < len; j++) {
+ r = rs[j];
+ cb = [];
+ var rowIndex = j + startRow,
+ visible = rowIndex >= vr.first && rowIndex <= vr.last;
+ if (visible) {
+ for (var i = 0; i < colCount; i++) {
+ c = cs[i];
+ p.id = c.id;
+ p.css =
+ i === 0
+ ? 'x-grid3-cell-first '
+ : i == last
+ ? 'x-grid3-cell-last '
+ : '';
+ p.attr = p.cellAttr = '';
+ p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
+ p.style = c.style;
+ if (p.value === undefined || p.value === '') {
+ p.value = '&#160;';
+ }
+ if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
+ p.css += ' x-grid3-dirty-cell';
+ }
+ cb[cb.length] = ct.apply(p);
+ }
+ }
+ var alt = [];
+ if (stripe && (rowIndex + 1) % 2 === 0) {
+ alt[0] = 'x-grid3-row-alt';
+ }
+ if (r.dirty) {
+ alt[1] = ' x-grid3-dirty-row';
+ }
+ rp.cols = colCount;
+ if (this.getRowClass) {
+ alt[2] = this.getRowClass(r, rowIndex, rp, ds);
+ }
+ rp.alt = alt.join(' ');
+ rp.cells = cb.join('');
+ buf[buf.length] = !visible
+ ? ts.rowHolder.apply(rp)
+ : onlyBody
+ ? rb.apply(rp)
+ : rt.apply(rp);
+ }
+ return buf.join('');
+ },
+
+ isRowRendered: function(index) {
+ var row = this.getRow(index);
+ return row && row.childNodes.length > 0;
+ },
+
+ syncScroll: function() {
+ Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments);
+ this.update();
+ },
+
+ // a (optionally) buffered method to update contents of gridview
+ update: function() {
+ if (this.scrollDelay) {
+ if (!this.renderTask) {
+ this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this);
+ }
+ this.renderTask.delay(this.scrollDelay);
+ } else {
+ this.doUpdate();
+ }
+ },
+
+ onRemove: function(ds, record, index, isUpdate) {
+ Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments);
+ if (isUpdate !== true) {
+ this.update();
+ }
+ },
+
+ doUpdate: function() {
+ if (this.getVisibleRowCount() > 0) {
+ var g = this.grid,
+ cm = g.colModel,
+ ds = g.store,
+ cs = this.getColumnData(),
+ vr = this.getVisibleRows(),
+ row;
+ for (var i = vr.first; i <= vr.last; i++) {
+ // if row is NOT rendered and is visible, render it
+ if (!this.isRowRendered(i) && (row = this.getRow(i))) {
+ var html = this.doRender(
+ cs,
+ [ds.getAt(i)],
+ ds,
+ i,
+ cm.getColumnCount(),
+ g.stripeRows,
+ true
+ );
+ row.innerHTML = html;
+ }
+ }
+ this.clean();
+ }
+ },
+
+ // a buffered method to clean rows
+ clean: function() {
+ if (!this.cleanTask) {
+ this.cleanTask = new Ext.util.DelayedTask(this.doClean, this);
+ }
+ this.cleanTask.delay(this.cleanDelay);
+ },
+
+ doClean: function() {
+ if (this.getVisibleRowCount() > 0) {
+ var vr = this.getVisibleRows();
+ vr.first -= this.cacheSize;
+ vr.last += this.cacheSize;
+
+ var i = 0,
+ rows = this.getRows();
+ // if first is less than 0, all rows have been rendered
+ // so lets clean the end...
+ if (vr.first <= 0) {
+ i = vr.last + 1;
+ }
+ for (var len = this.ds.getCount(); i < len; i++) {
+ // if current row is outside of first and last and
+ // has content, update the innerHTML to nothing
+ if ((i < vr.first || i > vr.last) && rows[i].innerHTML) {
+ rows[i].innerHTML = '';
+ }
+ }
+ }
+ },
+
+ removeTask: function(name) {
+ var task = this[name];
+ if (task && task.cancel) {
+ task.cancel();
+ this[name] = null;
+ }
+ },
+
+ destroy: function() {
+ this.removeTask('cleanTask');
+ this.removeTask('renderTask');
+ Ext.ux.grid.BufferView.superclass.destroy.call(this);
+ },
+
+ layout: function() {
+ Ext.ux.grid.BufferView.superclass.layout.call(this);
+ this.update();
+ },
+});
+/**
+ * Ext.ux.layout.FormLayoutFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Taken from http://extjs.com/forum/showthread.php?t=75273
+// remove spaces for hidden elements and make show(), hide(), enable() and disable() act on
+// the label. don't use hideLabel with this.
+Ext.override(Ext.layout.FormLayout, {
+ renderItem: function(c, position, target) {
+ if (
+ c &&
+ !c.rendered &&
+ (c.isFormField || c.fieldLabel) &&
+ c.inputType != 'hidden'
+ ) {
+ var args = this.getTemplateArgs(c);
+ if (typeof position == 'number') {
+ position = target.dom.childNodes[position] || null;
+ }
+ if (position) {
+ c.formItem = this.fieldTpl.insertBefore(position, args, true);
+ } else {
+ c.formItem = this.fieldTpl.append(target, args, true);
+ }
+ c.actionMode = 'formItem';
+ c.render('x-form-el-' + c.id);
+ c.container = c.formItem;
+ c.actionMode = 'container';
+ } else {
+ Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
+ }
+ },
+});
+/**
+ * Ext.ux.tree.MultiSelectionModelFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * This enhances the MSM to allow for shift selecting in tree grids etc.
+ * @author Damien Churchill <damoxc@gmail.com>
+ */
+Ext.override(Ext.tree.MultiSelectionModel, {
+ onNodeClick: function(node, e) {
+ if (e.ctrlKey && this.isSelected(node)) {
+ this.unselect(node);
+ } else if (e.shiftKey && !this.isSelected(node)) {
+ var parentNode = node.parentNode;
+ // We can only shift select files in the same node
+ if (this.lastSelNode.parentNode.id != parentNode.id) return;
+
+ // Get the node indexes
+ var fi = parentNode.indexOf(node),
+ li = parentNode.indexOf(this.lastSelNode);
+
+ // Select the last clicked node and wipe old selections
+ this.select(this.lastSelNode, e, false, true);
+
+ // Swap the values if required
+ if (fi > li) {
+ (fi = fi + li), (li = fi - li), (fi = fi - li);
+ }
+
+ // Select all the nodes
+ parentNode.eachChild(function(n) {
+ var i = parentNode.indexOf(n);
+ if (fi < i && i < li) {
+ this.select(n, e, true, true);
+ }
+ }, this);
+
+ // Select the clicked node
+ this.select(node, e, true);
+ } else {
+ this.select(node, e, e.ctrlKey);
+ }
+ },
+
+ select: function(node, e, keepExisting, suppressEvent) {
+ if (keepExisting !== true) {
+ this.clearSelections(true);
+ }
+ if (this.isSelected(node)) {
+ this.lastSelNode = node;
+ return node;
+ }
+ this.selNodes.push(node);
+ this.selMap[node.id] = node;
+ this.lastSelNode = node;
+ node.ui.onSelectedChange(true);
+ if (suppressEvent !== true) {
+ this.fireEvent('selectionchange', this, this.selNodes);
+ }
+ return node;
+ },
+});
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.tree');
+
+/**
+ * @class Ext.ux.tree.TreeGrid
+ * @extends Ext.tree.TreePanel
+ *
+ * @xtype treegrid
+ */
+Ext.ux.tree.TreeGrid = Ext.extend(Ext.tree.TreePanel, {
+ rootVisible: false,
+ useArrows: true,
+ lines: false,
+ borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
+ cls: 'x-treegrid',
+
+ columnResize: true,
+ enableSort: true,
+ reserveScrollOffset: true,
+ enableHdMenu: true,
+
+ columnsText: 'Columns',
+
+ initComponent: function() {
+ if (!this.root) {
+ this.root = new Ext.tree.AsyncTreeNode({ text: 'Root' });
+ }
+
+ // initialize the loader
+ var l = this.loader;
+ if (!l) {
+ l = new Ext.ux.tree.TreeGridLoader({
+ dataUrl: this.dataUrl,
+ requestMethod: this.requestMethod,
+ store: this.store,
+ });
+ } else if (Ext.isObject(l) && !l.load) {
+ l = new Ext.ux.tree.TreeGridLoader(l);
+ }
+ this.loader = l;
+
+ Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);
+
+ this.initColumns();
+
+ if (this.enableSort) {
+ this.treeGridSorter = new Ext.ux.tree.TreeGridSorter(
+ this,
+ this.enableSort
+ );
+ }
+
+ if (this.columnResize) {
+ this.colResizer = new Ext.tree.ColumnResizer(this.columnResize);
+ this.colResizer.init(this);
+ }
+
+ var c = this.columns;
+ if (!this.internalTpl) {
+ this.internalTpl = new Ext.XTemplate(
+ '<div class="x-grid3-header">',
+ '<div class="x-treegrid-header-inner">',
+ '<div class="x-grid3-header-offset">',
+ '<table style="table-layout: fixed;" cellspacing="0" cellpadding="0" border="0"><colgroup><tpl for="columns"><col /></tpl></colgroup>',
+ '<thead><tr class="x-grid3-hd-row">',
+ '<tpl for="columns">',
+ '<td class="x-grid3-hd x-grid3-cell x-treegrid-hd" style="text-align: {align};" id="',
+ this.id,
+ '-xlhd-{#}">',
+ '<div class="x-grid3-hd-inner x-treegrid-hd-inner" unselectable="on">',
+ this.enableHdMenu
+ ? '<a class="x-grid3-hd-btn" href="#"></a>'
+ : '',
+ '{header}<img class="x-grid3-sort-icon" src="',
+ Ext.BLANK_IMAGE_URL,
+ '" />',
+ '</div>',
+ '</td></tpl>',
+ '</tr></thead>',
+ '</table>',
+ '</div></div>',
+ '</div>',
+ '<div class="x-treegrid-root-node">',
+ '<table class="x-treegrid-root-table" cellpadding="0" cellspacing="0" style="table-layout: fixed;"></table>',
+ '</div>'
+ );
+ }
+
+ if (!this.colgroupTpl) {
+ this.colgroupTpl = new Ext.XTemplate(
+ '<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>'
+ );
+ }
+ },
+
+ initColumns: function() {
+ var cs = this.columns,
+ len = cs.length,
+ columns = [],
+ i,
+ c;
+
+ for (i = 0; i < len; i++) {
+ c = cs[i];
+ if (!c.isColumn) {
+ c.xtype = c.xtype
+ ? /^tg/.test(c.xtype)
+ ? c.xtype
+ : 'tg' + c.xtype
+ : 'tgcolumn';
+ c = Ext.create(c);
+ }
+ c.init(this);
+ columns.push(c);
+
+ if (this.enableSort !== false && c.sortable !== false) {
+ c.sortable = true;
+ this.enableSort = true;
+ }
+ }
+
+ this.columns = columns;
+ },
+
+ onRender: function() {
+ Ext.tree.TreePanel.superclass.onRender.apply(this, arguments);
+
+ this.el.addClass('x-treegrid');
+
+ this.outerCt = this.body.createChild({
+ cls:
+ 'x-tree-root-ct x-treegrid-ct ' +
+ (this.useArrows
+ ? 'x-tree-arrows'
+ : this.lines
+ ? 'x-tree-lines'
+ : 'x-tree-no-lines'),
+ });
+
+ this.internalTpl.overwrite(this.outerCt, { columns: this.columns });
+
+ this.mainHd = Ext.get(this.outerCt.dom.firstChild);
+ this.innerHd = Ext.get(this.mainHd.dom.firstChild);
+ this.innerBody = Ext.get(this.outerCt.dom.lastChild);
+ this.innerCt = Ext.get(this.innerBody.dom.firstChild);
+
+ this.colgroupTpl.insertFirst(this.innerCt, { columns: this.columns });
+
+ if (this.hideHeaders) {
+ this.el.child('.x-grid3-header').setDisplayed('none');
+ } else if (this.enableHdMenu !== false) {
+ this.hmenu = new Ext.menu.Menu({ id: this.id + '-hctx' });
+ if (this.enableColumnHide !== false) {
+ this.colMenu = new Ext.menu.Menu({
+ id: this.id + '-hcols-menu',
+ });
+ this.colMenu.on({
+ scope: this,
+ beforeshow: this.beforeColMenuShow,
+ itemclick: this.handleHdMenuClick,
+ });
+ this.hmenu.add({
+ itemId: 'columns',
+ hideOnClick: false,
+ text: this.columnsText,
+ menu: this.colMenu,
+ iconCls: 'x-cols-icon',
+ });
+ }
+ this.hmenu.on('itemclick', this.handleHdMenuClick, this);
+ }
+ },
+
+ setRootNode: function(node) {
+ node.attributes.uiProvider = Ext.ux.tree.TreeGridRootNodeUI;
+ node = Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this, node);
+ if (this.innerCt) {
+ this.colgroupTpl.insertFirst(this.innerCt, {
+ columns: this.columns,
+ });
+ }
+ return node;
+ },
+
+ clearInnerCt: function() {
+ if (Ext.isIE) {
+ var dom = this.innerCt.dom;
+ while (dom.firstChild) {
+ dom.removeChild(dom.firstChild);
+ }
+ } else {
+ Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this);
+ }
+ },
+
+ initEvents: function() {
+ Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this, arguments);
+
+ this.mon(this.innerBody, 'scroll', this.syncScroll, this);
+ this.mon(this.innerHd, 'click', this.handleHdDown, this);
+ this.mon(this.mainHd, {
+ scope: this,
+ mouseover: this.handleHdOver,
+ mouseout: this.handleHdOut,
+ });
+ },
+
+ onResize: function(w, h) {
+ Ext.ux.tree.TreeGrid.superclass.onResize.apply(this, arguments);
+
+ var bd = this.innerBody.dom;
+ var hd = this.innerHd.dom;
+
+ if (!bd) {
+ return;
+ }
+
+ if (Ext.isNumber(h)) {
+ bd.style.height =
+ this.body.getHeight(true) - hd.offsetHeight + 'px';
+ }
+
+ if (Ext.isNumber(w)) {
+ var sw = Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
+ if (
+ this.reserveScrollOffset ||
+ bd.offsetWidth - bd.clientWidth > 10
+ ) {
+ this.setScrollOffset(sw);
+ } else {
+ var me = this;
+ setTimeout(function() {
+ me.setScrollOffset(
+ bd.offsetWidth - bd.clientWidth > 10 ? sw : 0
+ );
+ }, 10);
+ }
+ }
+ },
+
+ updateColumnWidths: function() {
+ var cols = this.columns,
+ colCount = cols.length,
+ groups = this.outerCt.query('colgroup'),
+ groupCount = groups.length,
+ c,
+ g,
+ i,
+ j;
+
+ for (i = 0; i < colCount; i++) {
+ c = cols[i];
+ for (j = 0; j < groupCount; j++) {
+ g = groups[j];
+ g.childNodes[i].style.width = (c.hidden ? 0 : c.width) + 'px';
+ }
+ }
+
+ for (
+ i = 0, groups = this.innerHd.query('td'), len = groups.length;
+ i < len;
+ i++
+ ) {
+ c = Ext.fly(groups[i]);
+ if (cols[i] && cols[i].hidden) {
+ c.addClass('x-treegrid-hd-hidden');
+ } else {
+ c.removeClass('x-treegrid-hd-hidden');
+ }
+ }
+
+ var tcw = this.getTotalColumnWidth();
+ Ext.fly(this.innerHd.dom.firstChild).setWidth(
+ tcw + (this.scrollOffset || 0)
+ );
+ this.outerCt.select('table').setWidth(tcw);
+ this.syncHeaderScroll();
+ },
+
+ getVisibleColumns: function() {
+ var columns = [],
+ cs = this.columns,
+ len = cs.length,
+ i;
+
+ for (i = 0; i < len; i++) {
+ if (!cs[i].hidden) {
+ columns.push(cs[i]);
+ }
+ }
+ return columns;
+ },
+
+ getTotalColumnWidth: function() {
+ var total = 0;
+ for (
+ var i = 0, cs = this.getVisibleColumns(), len = cs.length;
+ i < len;
+ i++
+ ) {
+ total += cs[i].width;
+ }
+ return total;
+ },
+
+ setScrollOffset: function(scrollOffset) {
+ this.scrollOffset = scrollOffset;
+ this.updateColumnWidths();
+ },
+
+ // private
+ handleHdDown: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+
+ if (hd && Ext.fly(t).hasClass('x-grid3-hd-btn')) {
+ var ms = this.hmenu.items,
+ cs = this.columns,
+ index = this.findHeaderIndex(hd),
+ c = cs[index],
+ sort = c.sortable;
+
+ e.stopEvent();
+ Ext.fly(hd).addClass('x-grid3-hd-menu-open');
+ this.hdCtxIndex = index;
+
+ this.fireEvent('headerbuttonclick', ms, c, hd, index);
+
+ this.hmenu.on(
+ 'hide',
+ function() {
+ Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
+ },
+ this,
+ { single: true }
+ );
+
+ this.hmenu.show(t, 'tl-bl?');
+ } else if (hd) {
+ var index = this.findHeaderIndex(hd);
+ this.fireEvent('headerclick', this.columns[index], hd, index);
+ }
+ },
+
+ // private
+ handleHdOver: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+ if (hd && !this.headersDisabled) {
+ index = this.findHeaderIndex(hd);
+ this.activeHdRef = t;
+ this.activeHdIndex = index;
+ var el = Ext.get(hd);
+ this.activeHdRegion = el.getRegion();
+ el.addClass('x-grid3-hd-over');
+ this.activeHdBtn = el.child('.x-grid3-hd-btn');
+ if (this.activeHdBtn) {
+ this.activeHdBtn.dom.style.height =
+ hd.firstChild.offsetHeight - 1 + 'px';
+ }
+ }
+ },
+
+ // private
+ handleHdOut: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+ if (hd && (!Ext.isIE || !e.within(hd, true))) {
+ this.activeHdRef = null;
+ Ext.fly(hd).removeClass('x-grid3-hd-over');
+ hd.style.cursor = '';
+ }
+ },
+
+ findHeaderIndex: function(hd) {
+ hd = hd.dom || hd;
+ var cs = hd.parentNode.childNodes;
+ for (var i = 0, c; (c = cs[i]); i++) {
+ if (c == hd) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ // private
+ beforeColMenuShow: function() {
+ var cols = this.columns,
+ colCount = cols.length,
+ i,
+ c;
+ this.colMenu.removeAll();
+ for (i = 1; i < colCount; i++) {
+ c = cols[i];
+ if (c.hideable !== false) {
+ this.colMenu.add(
+ new Ext.menu.CheckItem({
+ itemId: 'col-' + i,
+ text: c.header,
+ checked: !c.hidden,
+ hideOnClick: false,
+ disabled: c.hideable === false,
+ })
+ );
+ }
+ }
+ },
+
+ // private
+ handleHdMenuClick: function(item) {
+ var index = this.hdCtxIndex,
+ id = item.getItemId();
+
+ if (
+ this.fireEvent(
+ 'headermenuclick',
+ this.columns[index],
+ id,
+ index
+ ) !== false
+ ) {
+ index = id.substr(4);
+ if (index > 0 && this.columns[index]) {
+ this.setColumnVisible(index, !item.checked);
+ }
+ }
+
+ return true;
+ },
+
+ setColumnVisible: function(index, visible) {
+ this.columns[index].hidden = !visible;
+ this.updateColumnWidths();
+ },
+
+ /**
+ * Scrolls the grid to the top
+ */
+ scrollToTop: function() {
+ this.innerBody.dom.scrollTop = 0;
+ this.innerBody.dom.scrollLeft = 0;
+ },
+
+ // private
+ syncScroll: function() {
+ this.syncHeaderScroll();
+ var mb = this.innerBody.dom;
+ this.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
+ },
+
+ // private
+ syncHeaderScroll: function() {
+ var mb = this.innerBody.dom;
+ this.innerHd.dom.scrollLeft = mb.scrollLeft;
+ this.innerHd.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
+ },
+
+ registerNode: function(n) {
+ Ext.ux.tree.TreeGrid.superclass.registerNode.call(this, n);
+ if (!n.uiProvider && !n.isRoot && !n.ui.isTreeGridNodeUI) {
+ n.ui = new Ext.ux.tree.TreeGridNodeUI(n);
+ }
+ },
+});
+
+Ext.reg('treegrid', Ext.ux.tree.TreeGrid);
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.tree.ColumnResizer
+ * @extends Ext.util.Observable
+ */
+Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, {
+ /**
+ * @cfg {Number} minWidth The minimum width the column can be dragged to.
+ * Defaults to <tt>14</tt>.
+ */
+ minWidth: 14,
+
+ constructor: function(config) {
+ Ext.apply(this, config);
+ Ext.tree.ColumnResizer.superclass.constructor.call(this);
+ },
+
+ init: function(tree) {
+ this.tree = tree;
+ tree.on('render', this.initEvents, this);
+ },
+
+ initEvents: function(tree) {
+ tree.mon(tree.innerHd, 'mousemove', this.handleHdMove, this);
+ this.tracker = new Ext.dd.DragTracker({
+ onBeforeStart: this.onBeforeStart.createDelegate(this),
+ onStart: this.onStart.createDelegate(this),
+ onDrag: this.onDrag.createDelegate(this),
+ onEnd: this.onEnd.createDelegate(this),
+ tolerance: 3,
+ autoStart: 300,
+ });
+ this.tracker.initEl(tree.innerHd);
+ tree.on('beforedestroy', this.tracker.destroy, this.tracker);
+ },
+
+ handleHdMove: function(e, t) {
+ var hw = 5,
+ x = e.getPageX(),
+ hd = e.getTarget('.x-treegrid-hd', 3, true);
+
+ if (hd) {
+ var r = hd.getRegion(),
+ ss = hd.dom.style,
+ pn = hd.dom.parentNode;
+
+ if (x - r.left <= hw && hd.dom !== pn.firstChild) {
+ var ps = hd.dom.previousSibling;
+ while (ps && Ext.fly(ps).hasClass('x-treegrid-hd-hidden')) {
+ ps = ps.previousSibling;
+ }
+ if (ps) {
+ this.activeHd = Ext.get(ps);
+ ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
+ }
+ } else if (r.right - x <= hw) {
+ var ns = hd.dom;
+ while (ns && Ext.fly(ns).hasClass('x-treegrid-hd-hidden')) {
+ ns = ns.previousSibling;
+ }
+ if (ns) {
+ this.activeHd = Ext.get(ns);
+ ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
+ }
+ } else {
+ delete this.activeHd;
+ ss.cursor = '';
+ }
+ }
+ },
+
+ onBeforeStart: function(e) {
+ this.dragHd = this.activeHd;
+ return !!this.dragHd;
+ },
+
+ onStart: function(e) {
+ this.dragHeadersDisabled = this.tree.headersDisabled;
+ this.tree.headersDisabled = true;
+ this.proxy = this.tree.body.createChild({ cls: 'x-treegrid-resizer' });
+ this.proxy.setHeight(this.tree.body.getHeight());
+
+ var x = this.tracker.getXY()[0];
+
+ this.hdX = this.dragHd.getX();
+ this.hdIndex = this.tree.findHeaderIndex(this.dragHd);
+
+ this.proxy.setX(this.hdX);
+ this.proxy.setWidth(x - this.hdX);
+
+ this.maxWidth =
+ this.tree.outerCt.getWidth() -
+ this.tree.innerBody.translatePoints(this.hdX).left;
+ },
+
+ onDrag: function(e) {
+ var cursorX = this.tracker.getXY()[0];
+ this.proxy.setWidth(
+ (cursorX - this.hdX).constrain(this.minWidth, this.maxWidth)
+ );
+ },
+
+ onEnd: function(e) {
+ var nw = this.proxy.getWidth(),
+ tree = this.tree,
+ disabled = this.dragHeadersDisabled;
+
+ this.proxy.remove();
+ delete this.dragHd;
+
+ tree.columns[this.hdIndex].width = nw;
+ tree.updateColumnWidths();
+
+ setTimeout(function() {
+ tree.headersDisabled = disabled;
+ }, 100);
+ },
+});
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+(function() {
+ Ext.override(Ext.list.Column, {
+ init: function() {
+ var types = Ext.data.Types,
+ st = this.sortType;
+
+ if (this.type) {
+ if (Ext.isString(this.type)) {
+ this.type =
+ Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
+ }
+ } else {
+ this.type = types.AUTO;
+ }
+
+ // named sortTypes are supported, here we look them up
+ if (Ext.isString(st)) {
+ this.sortType = Ext.data.SortTypes[st];
+ } else if (Ext.isEmpty(st)) {
+ this.sortType = this.type.sortType;
+ }
+ },
+ });
+
+ Ext.tree.Column = Ext.extend(Ext.list.Column, {});
+ Ext.tree.NumberColumn = Ext.extend(Ext.list.NumberColumn, {});
+ Ext.tree.DateColumn = Ext.extend(Ext.list.DateColumn, {});
+ Ext.tree.BooleanColumn = Ext.extend(Ext.list.BooleanColumn, {});
+
+ Ext.reg('tgcolumn', Ext.tree.Column);
+ Ext.reg('tgnumbercolumn', Ext.tree.NumberColumn);
+ Ext.reg('tgdatecolumn', Ext.tree.DateColumn);
+ Ext.reg('tgbooleancolumn', Ext.tree.BooleanColumn);
+})();
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.tree.TreeGridLoader
+ * @extends Ext.tree.TreeLoader
+ */
+Ext.ux.tree.TreeGridLoader = Ext.extend(Ext.tree.TreeLoader, {
+ createNode: function(attr) {
+ if (!attr.uiProvider) {
+ attr.uiProvider = Ext.ux.tree.TreeGridNodeUI;
+ }
+ return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
+ },
+});
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.tree.TreeGridNodeUI
+ * @extends Ext.tree.TreeNodeUI
+ */
+Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+ isTreeGridNodeUI: true,
+
+ renderElements: function(n, a, targetNode, bulkRender) {
+ var t = n.getOwnerTree(),
+ cols = t.columns,
+ c = cols[0],
+ i,
+ buf,
+ len;
+
+ this.indentMarkup = n.parentNode
+ ? n.parentNode.ui.getChildIndent()
+ : '';
+
+ buf = [
+ '<tbody class="x-tree-node">',
+ '<tr ext:tree-node-id="',
+ n.id,
+ '" class="x-tree-node-el x-tree-node-leaf ',
+ a.cls,
+ '">',
+ '<td class="x-treegrid-col">',
+ '<span class="x-tree-node-indent">',
+ this.indentMarkup,
+ '</span>',
+ '<img src="',
+ this.emptyIcon,
+ '" class="x-tree-ec-icon x-tree-elbow" />',
+ '<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" class="x-tree-node-anchor" href="',
+ a.href ? a.href : '#',
+ '" tabIndex="1" ',
+ a.hrefTarget ? ' target="' + a.hrefTarget + '"' : '',
+ '>',
+ '<span unselectable="on">',
+ c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text,
+ '</span></a>',
+ '</td>',
+ ];
+
+ for (i = 1, len = cols.length; i < len; i++) {
+ c = cols[i];
+ buf.push(
+ '<td class="x-treegrid-col ',
+ c.cls ? c.cls : '',
+ '">',
+ '<div unselectable="on" class="x-treegrid-text"',
+ c.align ? ' style="text-align: ' + c.align + ';"' : '',
+ '>',
+ c.tpl ? c.tpl.apply(a) : a[c.dataIndex],
+ '</div>',
+ '</td>'
+ );
+ }
+
+ buf.push(
+ '</tr><tr class="x-tree-node-ct"><td colspan="',
+ cols.length,
+ '">',
+ '<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',
+ t.innerCt.getWidth(),
+ 'px;"><colgroup>'
+ );
+ for (i = 0, len = cols.length; i < len; i++) {
+ buf.push(
+ '<col style="width: ',
+ cols[i].hidden ? 0 : cols[i].width,
+ 'px;" />'
+ );
+ }
+ buf.push('</colgroup></table></td></tr></tbody>');
+
+ if (bulkRender !== 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',
+ targetNode,
+ buf.join('')
+ );
+ }
+
+ this.elNode = this.wrap.childNodes[0];
+ this.ctNode = this.wrap.childNodes[1].firstChild.firstChild;
+ var cs = this.elNode.firstChild.childNodes;
+ this.indentNode = cs[0];
+ this.ecNode = cs[1];
+ this.iconNode = cs[2];
+ this.anchor = cs[3];
+ this.textNode = cs[3].firstChild;
+ },
+
+ // private
+ animExpand: function(cb) {
+ this.ctNode.style.display = '';
+ Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb);
+ },
+});
+
+Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+ isTreeGridNodeUI: true,
+
+ // private
+ render: function() {
+ if (!this.rendered) {
+ this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom;
+ this.node.expanded = true;
+ }
+
+ if (Ext.isWebKit) {
+ // weird table-layout: fixed issue in webkit
+ var ct = this.ctNode;
+ ct.style.tableLayout = null;
+ (function() {
+ ct.style.tableLayout = 'fixed';
+ }.defer(1));
+ }
+ },
+
+ destroy: function() {
+ if (this.elNode) {
+ Ext.dd.Registry.unregister(this.elNode.id);
+ }
+ delete this.node;
+ },
+
+ collapse: Ext.emptyFn,
+ expand: Ext.emptyFn,
+});
+/**
+ * Ext.ux.tree.TreeGridNodeUIFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.override(Ext.ux.tree.TreeGridNodeUI, {
+ updateColumns: function() {
+ if (!this.rendered) return;
+
+ var a = this.node.attributes,
+ t = this.node.getOwnerTree(),
+ cols = t.columns,
+ c = cols[0];
+
+ // Update the first column
+ this.anchor.firstChild.innerHTML = c.tpl
+ ? c.tpl.apply(a)
+ : a[c.dataIndex] || c.text;
+
+ // Update the remaining columns
+ for (i = 1, len = cols.length; i < len; i++) {
+ c = cols[i];
+ this.elNode.childNodes[i].firstChild.innerHTML = c.tpl
+ ? c.tpl.apply(a)
+ : a[c.dataIndex] || c.text;
+ }
+ },
+});
+Ext.tree.RenderColumn = Ext.extend(Ext.tree.Column, {
+ constructor: function(c) {
+ c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
+ c.tpl.format = c.renderer;
+ c.tpl.col = this;
+ Ext.tree.RenderColumn.superclass.constructor.call(this, c);
+ },
+});
+Ext.reg('tgrendercolumn', Ext.tree.RenderColumn);
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.tree');
+
+/**
+ * @class Ext.ux.tree.TreeGridSorter
+ * @extends Ext.tree.TreeSorter
+ * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}. The TreeGridSorter automatically monitors events on the
+ * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
+ * Example usage:<br />
+ * <pre><code>
+ new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
+ folderSort: true,
+ dir: "desc",
+ sortType: function(node) {
+ // sort by a custom, typed attribute:
+ return parseInt(node.id, 10);
+ }
+ });
+ </code></pre>
+ * @constructor
+ * @param {TreeGrid} tree
+ * @param {Object} config
+ */
+Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
+ /**
+ * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>['sort-asc', 'sort-desc']</tt>)
+ */
+ sortClasses: ['sort-asc', 'sort-desc'],
+ /**
+ * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to <tt>'Sort Ascending'</tt>)
+ */
+ sortAscText: 'Sort Ascending',
+ /**
+ * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to <tt>'Sort Descending'</tt>)
+ */
+ sortDescText: 'Sort Descending',
+
+ constructor: function(tree, config) {
+ if (!Ext.isObject(config)) {
+ config = {
+ property: tree.columns[0].dataIndex || 'text',
+ folderSort: true,
+ };
+ }
+
+ Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(
+ this,
+ arguments
+ );
+
+ this.tree = tree;
+ tree.on('headerclick', this.onHeaderClick, this);
+ tree.ddAppendOnly = true;
+
+ var me = this;
+ this.defaultSortFn = function(n1, n2) {
+ var desc = me.dir && me.dir.toLowerCase() == 'desc',
+ prop = me.property || 'text',
+ sortType = me.sortType,
+ caseSensitive = me.caseSensitive === true,
+ leafAttr = me.leafAttr || 'leaf',
+ attr1 = n1.attributes,
+ attr2 = n2.attributes;
+
+ if (me.folderSort) {
+ if (attr1[leafAttr] && !attr2[leafAttr]) {
+ return 1;
+ }
+ if (!attr1[leafAttr] && attr2[leafAttr]) {
+ return -1;
+ }
+ }
+ var prop1 = attr1[prop],
+ prop2 = attr2[prop],
+ v1 = sortType
+ ? sortType(prop1)
+ : caseSensitive
+ ? prop1
+ : prop1.toUpperCase();
+ v2 = sortType
+ ? sortType(prop2)
+ : caseSensitive
+ ? prop2
+ : prop2.toUpperCase();
+
+ if (v1 < v2) {
+ return desc ? +1 : -1;
+ } else if (v1 > v2) {
+ return desc ? -1 : +1;
+ } else {
+ return 0;
+ }
+ };
+
+ tree.on('afterrender', this.onAfterTreeRender, this, { single: true });
+ tree.on('headermenuclick', this.onHeaderMenuClick, this);
+ },
+
+ onAfterTreeRender: function() {
+ if (this.tree.hmenu) {
+ this.tree.hmenu.insert(
+ 0,
+ {
+ itemId: 'asc',
+ text: this.sortAscText,
+ cls: 'xg-hmenu-sort-asc',
+ },
+ {
+ itemId: 'desc',
+ text: this.sortDescText,
+ cls: 'xg-hmenu-sort-desc',
+ }
+ );
+ }
+ this.updateSortIcon(0, 'asc');
+ },
+
+ onHeaderMenuClick: function(c, id, index) {
+ if (id === 'asc' || id === 'desc') {
+ this.onHeaderClick(c, null, index);
+ return false;
+ }
+ },
+
+ onHeaderClick: function(c, el, i) {
+ if (c && !this.tree.headersDisabled) {
+ var me = this;
+
+ me.property = c.dataIndex;
+ me.dir = c.dir = c.dir === 'desc' ? 'asc' : 'desc';
+ me.sortType = c.sortType;
+ me.caseSensitive === Ext.isBoolean(c.caseSensitive)
+ ? c.caseSensitive
+ : this.caseSensitive;
+ me.sortFn = c.sortFn || this.defaultSortFn;
+
+ this.tree.root.cascade(function(n) {
+ if (!n.isLeaf()) {
+ me.updateSort(me.tree, n);
+ }
+ });
+
+ this.updateSortIcon(i, c.dir);
+ }
+ },
+
+ // private
+ updateSortIcon: function(col, dir) {
+ var sc = this.sortClasses,
+ hds = this.tree.innerHd.select('td').removeClass(sc);
+ hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]);
+ },
+});
+Ext.ux.JSLoader = function(options) {
+ Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index] = {
+ url: options.url,
+ success: true,
+ jsLoadObj: null,
+ options: options,
+ onLoad: options.onLoad || Ext.emptyFn,
+ onError: options.onError || Ext.ux.JSLoader.stdError,
+ scope: options.scope || this,
+ };
+
+ Ext.Ajax.request({
+ url: options.url,
+ scriptIndex: Ext.ux.JSLoader.index,
+ success: function(response, options) {
+ var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
+ try {
+ eval(response.responseText);
+ } catch (e) {
+ script.success = false;
+ script.onError(script.options, e);
+ }
+ if (script.success) {
+ script.onLoad.call(script.scope, script.options);
+ }
+ },
+ failure: function(response, options) {
+ var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
+ script.success = false;
+ script.onError(script.options, response.status);
+ },
+ });
+};
+Ext.ux.JSLoader.index = 0;
+Ext.ux.JSLoader.scripts = [];
+Ext.ux.JSLoader.stdError = function(options, e) {
+ window.alert(
+ 'Error loading script:\n\n' + options.url + '\n\nstatus: ' + e
+ );
+};
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.Spinner
+ * @extends Ext.util.Observable
+ * Creates a Spinner control utilized by Ext.ux.form.SpinnerField
+ */
+Ext.ux.Spinner = Ext.extend(Ext.util.Observable, {
+ incrementValue: 1,
+ alternateIncrementValue: 5,
+ triggerClass: 'x-form-spinner-trigger',
+ splitterClass: 'x-form-spinner-splitter',
+ alternateKey: Ext.EventObject.shiftKey,
+ defaultValue: 0,
+ accelerate: false,
+
+ constructor: function(config) {
+ Ext.ux.Spinner.superclass.constructor.call(this, config);
+ Ext.apply(this, config);
+ this.mimicing = false;
+ },
+
+ init: function(field) {
+ this.field = field;
+
+ field.afterMethod('onRender', this.doRender, this);
+ field.afterMethod('onEnable', this.doEnable, this);
+ field.afterMethod('onDisable', this.doDisable, this);
+ field.afterMethod('afterRender', this.doAfterRender, this);
+ field.afterMethod('onResize', this.doResize, this);
+ field.afterMethod('onFocus', this.doFocus, this);
+ field.beforeMethod('onDestroy', this.doDestroy, this);
+ },
+
+ doRender: function(ct, position) {
+ var el = (this.el = this.field.getEl());
+ var f = this.field;
+
+ if (!f.wrap) {
+ f.wrap = this.wrap = el.wrap({
+ cls: 'x-form-field-wrap',
+ });
+ } else {
+ this.wrap = f.wrap.addClass('x-form-field-wrap');
+ }
+
+ this.trigger = this.wrap.createChild({
+ tag: 'img',
+ src: Ext.BLANK_IMAGE_URL,
+ cls: 'x-form-trigger ' + this.triggerClass,
+ });
+
+ if (!f.width) {
+ this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
+ }
+
+ this.splitter = this.wrap.createChild({
+ tag: 'div',
+ cls: this.splitterClass,
+ style: 'width:13px; height:2px;',
+ });
+ this.splitter
+ .setRight(Ext.isIE ? 1 : 2)
+ .setTop(10)
+ .show();
+
+ this.proxy = this.trigger.createProxy('', this.splitter, true);
+ this.proxy.addClass('x-form-spinner-proxy');
+ this.proxy.setStyle('left', '0px');
+ this.proxy.setSize(14, 1);
+ this.proxy.hide();
+ this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, 'SpinnerDrag', {
+ dragElId: this.proxy.id,
+ });
+
+ this.initTrigger();
+ this.initSpinner();
+ },
+
+ doAfterRender: function() {
+ var y;
+ if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) {
+ this.el.position();
+ this.el.setY(y);
+ }
+ },
+
+ doEnable: function() {
+ if (this.wrap) {
+ this.disabled = false;
+ this.wrap.removeClass(this.field.disabledClass);
+ }
+ },
+
+ doDisable: function() {
+ if (this.wrap) {
+ this.disabled = true;
+ this.wrap.addClass(this.field.disabledClass);
+ this.el.removeClass(this.field.disabledClass);
+ }
+ },
+
+ doResize: function(w, h) {
+ if (typeof w == 'number') {
+ this.el.setWidth(w - this.trigger.getWidth());
+ }
+ this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth());
+ },
+
+ doFocus: function() {
+ if (!this.mimicing) {
+ this.wrap.addClass('x-trigger-wrap-focus');
+ this.mimicing = true;
+ Ext.get(Ext.isIE ? document.body : document).on(
+ 'mousedown',
+ this.mimicBlur,
+ this,
+ {
+ delay: 10,
+ }
+ );
+ this.el.on('keydown', this.checkTab, this);
+ }
+ },
+
+ // private
+ checkTab: function(e) {
+ if (e.getKey() == e.TAB) {
+ this.triggerBlur();
+ }
+ },
+
+ // private
+ mimicBlur: function(e) {
+ if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) {
+ this.triggerBlur();
+ }
+ },
+
+ // private
+ triggerBlur: function() {
+ this.mimicing = false;
+ Ext.get(Ext.isIE ? document.body : document).un(
+ 'mousedown',
+ this.mimicBlur,
+ this
+ );
+ this.el.un('keydown', this.checkTab, this);
+ this.field.beforeBlur();
+ this.wrap.removeClass('x-trigger-wrap-focus');
+ this.field.onBlur.call(this.field);
+ },
+
+ initTrigger: function() {
+ this.trigger.addClassOnOver('x-form-trigger-over');
+ this.trigger.addClassOnClick('x-form-trigger-click');
+ },
+
+ initSpinner: function() {
+ this.field.addEvents({
+ spin: true,
+ spinup: true,
+ spindown: true,
+ });
+
+ this.keyNav = new Ext.KeyNav(this.el, {
+ up: function(e) {
+ e.preventDefault();
+ this.onSpinUp();
+ },
+
+ down: function(e) {
+ e.preventDefault();
+ this.onSpinDown();
+ },
+
+ pageUp: function(e) {
+ e.preventDefault();
+ this.onSpinUpAlternate();
+ },
+
+ pageDown: function(e) {
+ e.preventDefault();
+ this.onSpinDownAlternate();
+ },
+
+ scope: this,
+ });
+
+ this.repeater = new Ext.util.ClickRepeater(this.trigger, {
+ accelerate: this.accelerate,
+ });
+ this.field.mon(this.repeater, 'click', this.onTriggerClick, this, {
+ preventDefault: true,
+ });
+
+ this.field.mon(this.trigger, {
+ mouseover: this.onMouseOver,
+ mouseout: this.onMouseOut,
+ mousemove: this.onMouseMove,
+ mousedown: this.onMouseDown,
+ mouseup: this.onMouseUp,
+ scope: this,
+ preventDefault: true,
+ });
+
+ this.field.mon(this.wrap, 'mousewheel', this.handleMouseWheel, this);
+
+ this.dd.setXConstraint(0, 0, 10);
+ this.dd.setYConstraint(1500, 1500, 10);
+ this.dd.endDrag = this.endDrag.createDelegate(this);
+ this.dd.startDrag = this.startDrag.createDelegate(this);
+ this.dd.onDrag = this.onDrag.createDelegate(this);
+ },
+
+ onMouseOver: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ this.tmpHoverClass =
+ Ext.EventObject.getPageY() < middle
+ ? 'x-form-spinner-overup'
+ : 'x-form-spinner-overdown';
+ this.trigger.addClass(this.tmpHoverClass);
+ },
+
+ //private
+ onMouseOut: function() {
+ this.trigger.removeClass(this.tmpHoverClass);
+ },
+
+ //private
+ onMouseMove: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ if (
+ (Ext.EventObject.getPageY() > middle &&
+ this.tmpHoverClass == 'x-form-spinner-overup') ||
+ (Ext.EventObject.getPageY() < middle &&
+ this.tmpHoverClass == 'x-form-spinner-overdown')
+ ) {
+ }
+ },
+
+ //private
+ onMouseDown: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ this.tmpClickClass =
+ Ext.EventObject.getPageY() < middle
+ ? 'x-form-spinner-clickup'
+ : 'x-form-spinner-clickdown';
+ this.trigger.addClass(this.tmpClickClass);
+ },
+
+ //private
+ onMouseUp: function() {
+ this.trigger.removeClass(this.tmpClickClass);
+ },
+
+ //private
+ onTriggerClick: function() {
+ if (this.disabled || this.el.dom.readOnly) {
+ return;
+ }
+ var middle = this.getMiddle();
+ var ud = Ext.EventObject.getPageY() < middle ? 'Up' : 'Down';
+ this['onSpin' + ud]();
+ },
+
+ //private
+ getMiddle: function() {
+ var t = this.trigger.getTop();
+ var h = this.trigger.getHeight();
+ var middle = t + h / 2;
+ return middle;
+ },
+
+ //private
+ //checks if control is allowed to spin
+ isSpinnable: function() {
+ if (this.disabled || this.el.dom.readOnly) {
+ Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly
+ return false;
+ }
+ return true;
+ },
+
+ handleMouseWheel: function(e) {
+ //disable scrolling when not focused
+ if (this.wrap.hasClass('x-trigger-wrap-focus') == false) {
+ return;
+ }
+
+ var delta = e.getWheelDelta();
+ if (delta > 0) {
+ this.onSpinUp();
+ e.stopEvent();
+ } else if (delta < 0) {
+ this.onSpinDown();
+ e.stopEvent();
+ }
+ },
+
+ //private
+ startDrag: function() {
+ this.proxy.show();
+ this._previousY = Ext.fly(this.dd.getDragEl()).getTop();
+ },
+
+ //private
+ endDrag: function() {
+ this.proxy.hide();
+ },
+
+ //private
+ onDrag: function() {
+ if (this.disabled) {
+ return;
+ }
+ var y = Ext.fly(this.dd.getDragEl()).getTop();
+ var ud = '';
+
+ if (this._previousY > y) {
+ ud = 'Up';
+ } //up
+ if (this._previousY < y) {
+ ud = 'Down';
+ } //down
+ if (ud != '') {
+ this['onSpin' + ud]();
+ }
+
+ this._previousY = y;
+ },
+
+ //private
+ onSpinUp: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ if (Ext.EventObject.shiftKey == true) {
+ this.onSpinUpAlternate();
+ return;
+ } else {
+ this.spin(false, false);
+ }
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spinup', this);
+ },
+
+ //private
+ onSpinDown: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ if (Ext.EventObject.shiftKey == true) {
+ this.onSpinDownAlternate();
+ return;
+ } else {
+ this.spin(true, false);
+ }
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spindown', this);
+ },
+
+ //private
+ onSpinUpAlternate: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ this.spin(false, true);
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spinup', this);
+ },
+
+ //private
+ onSpinDownAlternate: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ this.spin(true, true);
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spindown', this);
+ },
+
+ spin: function(down, alternate) {
+ var v = parseFloat(this.field.getValue());
+ var incr =
+ alternate == true
+ ? this.alternateIncrementValue
+ : this.incrementValue;
+ down == true ? (v -= incr) : (v += incr);
+
+ v = isNaN(v) ? this.defaultValue : v;
+ v = this.fixBoundries(v);
+ this.field.setRawValue(v);
+ },
+
+ fixBoundries: function(value) {
+ var v = value;
+
+ if (this.field.minValue != undefined && v < this.field.minValue) {
+ v = this.field.minValue;
+ }
+ if (this.field.maxValue != undefined && v > this.field.maxValue) {
+ v = this.field.maxValue;
+ }
+
+ return this.fixPrecision(v);
+ },
+
+ // private
+ fixPrecision: function(value) {
+ var nan = isNaN(value);
+ if (
+ !this.field.allowDecimals ||
+ this.field.decimalPrecision == -1 ||
+ nan ||
+ !value
+ ) {
+ return nan ? '' : value;
+ }
+ return parseFloat(
+ parseFloat(value).toFixed(this.field.decimalPrecision)
+ );
+ },
+
+ doDestroy: function() {
+ if (this.trigger) {
+ this.trigger.remove();
+ }
+ if (this.wrap) {
+ this.wrap.remove();
+ delete this.field.wrap;
+ }
+
+ if (this.splitter) {
+ this.splitter.remove();
+ }
+
+ if (this.dd) {
+ this.dd.unreg();
+ this.dd = null;
+ }
+
+ if (this.proxy) {
+ this.proxy.remove();
+ }
+
+ if (this.repeater) {
+ this.repeater.purgeListeners();
+ }
+ if (this.mimicing) {
+ Ext.get(Ext.isIE ? document.body : document).un(
+ 'mousedown',
+ this.mimicBlur,
+ this
+ );
+ }
+ },
+});
+
+//backwards compat
+Ext.form.Spinner = Ext.ux.Spinner;
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.StatusBar
+ * <p>Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}. In addition to
+ * supporting the standard {@link Ext.Toolbar} interface for adding buttons, menus and other items, the StatusBar
+ * provides a greedy status element that can be aligned to either side and has convenient methods for setting the
+ * status text and icon. You can also indicate that something is processing using the {@link #showBusy} method.</p>
+ * <pre><code>
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ id: 'my-status',
+
+ // defaults to use when the status is cleared:
+ defaultText: 'Default status text',
+ defaultIconCls: 'default-icon',
+
+ // values to set initially:
+ text: 'Ready',
+ iconCls: 'ready-icon',
+
+ // any standard Toolbar items:
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// Update the status bar later in code:
+var sb = Ext.getCmp('my-status');
+sb.setStatus({
+ text: 'OK',
+ iconCls: 'ok-icon',
+ clear: true // auto-clear after a set interval
+});
+
+// Set the status bar to show that something is processing:
+sb.showBusy();
+
+// processing....
+
+sb.clearStatus(); // once completeed
+</code></pre>
+ * @extends Ext.Toolbar
+ * @constructor
+ * Creates a new StatusBar
+ * @param {Object/Array} config A config object
+ */
+Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, {
+ /**
+ * @cfg {String} statusAlign
+ * The alignment of the status element within the overall StatusBar layout. When the StatusBar is rendered,
+ * it creates an internal div containing the status text and icon. Any additional Toolbar items added in the
+ * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be
+ * rendered, in added order, to the opposite side. The status element is greedy, so it will automatically
+ * expand to take up all sapce left over by any other items. Example usage:
+ * <pre><code>
+// Create a left-aligned status bar containing a button,
+// separator and text item that will be right-aligned (default):
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// By adding the statusAlign config, this will create the
+// exact same toolbar, except the status and toolbar item
+// layout will be reversed from the previous example:
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ statusAlign: 'right',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+</code></pre>
+ */
+ /**
+ * @cfg {String} defaultText
+ * The default {@link #text} value. This will be used anytime the status bar is cleared with the
+ * <tt>useDefaults:true</tt> option (defaults to '').
+ */
+ /**
+ * @cfg {String} defaultIconCls
+ * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon).
+ * This will be used anytime the status bar is cleared with the <tt>useDefaults:true</tt> option (defaults to '').
+ */
+ /**
+ * @cfg {String} text
+ * A string that will be <b>initially</b> set as the status message. This string
+ * will be set as innerHTML (html tags are accepted) for the toolbar item.
+ * If not specified, the value set for <code>{@link #defaultText}</code>
+ * will be used.
+ */
+ /**
+ * @cfg {String} iconCls
+ * A CSS class that will be <b>initially</b> set as the status bar icon and is
+ * expected to provide a background image (defaults to '').
+ * Example usage:<pre><code>
+// Example CSS rule:
+.x-statusbar .x-status-custom {
+ padding-left: 25px;
+ background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
+}
+
+// Setting a default icon:
+var sb = new Ext.ux.StatusBar({
+ defaultIconCls: 'x-status-custom'
+});
+
+// Changing the icon:
+sb.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom'
+});
+</code></pre>
+ */
+
+ /**
+ * @cfg {String} cls
+ * The base class applied to the containing element for this component on render (defaults to 'x-statusbar')
+ */
+ cls: 'x-statusbar',
+ /**
+ * @cfg {String} busyIconCls
+ * The default <code>{@link #iconCls}</code> applied when calling
+ * <code>{@link #showBusy}</code> (defaults to <tt>'x-status-busy'</tt>).
+ * It can be overridden at any time by passing the <code>iconCls</code>
+ * argument into <code>{@link #showBusy}</code>.
+ */
+ busyIconCls: 'x-status-busy',
+ /**
+ * @cfg {String} busyText
+ * The default <code>{@link #text}</code> applied when calling
+ * <code>{@link #showBusy}</code> (defaults to <tt>'Loading...'</tt>).
+ * It can be overridden at any time by passing the <code>text</code>
+ * argument into <code>{@link #showBusy}</code>.
+ */
+ busyText: 'Loading...',
+ /**
+ * @cfg {Number} autoClear
+ * The number of milliseconds to wait after setting the status via
+ * <code>{@link #setStatus}</code> before automatically clearing the status
+ * text and icon (defaults to <tt>5000</tt>). Note that this only applies
+ * when passing the <tt>clear</tt> argument to <code>{@link #setStatus}</code>
+ * since that is the only way to defer clearing the status. This can
+ * be overridden by specifying a different <tt>wait</tt> value in
+ * <code>{@link #setStatus}</code>. Calls to <code>{@link #clearStatus}</code>
+ * always clear the status bar immediately and ignore this value.
+ */
+ autoClear: 5000,
+
+ /**
+ * @cfg {String} emptyText
+ * The text string to use if no text has been set. Defaults to
+ * <tt>'&nbsp;'</tt>). If there are no other items in the toolbar using
+ * an empty string (<tt>''</tt>) for this value would end up in the toolbar
+ * height collapsing since the empty string will not maintain the toolbar
+ * height. Use <tt>''</tt> if the toolbar should collapse in height
+ * vertically when no text is specified and there are no other items in
+ * the toolbar.
+ */
+ emptyText: '&nbsp;',
+
+ // private
+ activeThreadId: 0,
+
+ // private
+ initComponent: function() {
+ if (this.statusAlign == 'right') {
+ this.cls += ' x-status-right';
+ }
+ Ext.ux.StatusBar.superclass.initComponent.call(this);
+ },
+
+ // private
+ afterRender: function() {
+ Ext.ux.StatusBar.superclass.afterRender.call(this);
+
+ var right = this.statusAlign == 'right';
+ this.currIconCls = this.iconCls || this.defaultIconCls;
+ this.statusEl = new Ext.Toolbar.TextItem({
+ cls: 'x-status-text ' + (this.currIconCls || ''),
+ text: this.text || this.defaultText || '',
+ });
+
+ if (right) {
+ this.add('->');
+ this.add(this.statusEl);
+ } else {
+ this.insert(0, this.statusEl);
+ this.insert(1, '->');
+ }
+ this.doLayout();
+ },
+
+ /**
+ * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the
+ * status that was set after a specified interval.
+ * @param {Object/String} config A config object specifying what status to set, or a string assumed
+ * to be the status text (and all other options are defaulted as explained below). A config
+ * object containing any or all of the following properties can be passed:<ul>
+ * <li><tt>text</tt> {String} : (optional) The status text to display. If not specified, any current
+ * status text will remain unchanged.</li>
+ * <li><tt>iconCls</tt> {String} : (optional) The CSS class used to customize the status icon (see
+ * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.</li>
+ * <li><tt>clear</tt> {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will
+ * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not
+ * specified, the new status will not be auto-cleared and will stay until updated again or cleared using
+ * {@link #clearStatus}. If <tt>true</tt> is passed, the status will be cleared using {@link #autoClear},
+ * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed,
+ * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value.
+ * All other options will be defaulted as with the boolean option. To customize any other options,
+ * you can pass an object in the format:<ul>
+ * <li><tt>wait</tt> {Number} : (optional) The number of milliseconds to wait before clearing
+ * (defaults to {@link #autoClear}).</li>
+ * <li><tt>anim</tt> {Number} : (optional) False to clear the status immediately once the callback
+ * executes (defaults to true which fades the status out).</li>
+ * <li><tt>useDefaults</tt> {Number} : (optional) False to completely clear the status text and iconCls
+ * (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
+ * </ul></li></ul>
+ * Example usage:<pre><code>
+// Simple call to update the text
+statusBar.setStatus('New status');
+
+// Set the status and icon, auto-clearing with default options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: true
+});
+
+// Auto-clear with custom options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: {
+ wait: 8000,
+ anim: false,
+ useDefaults: false
+ }
+});
+</code></pre>
+ * @return {Ext.ux.StatusBar} this
+ */
+ setStatus: function(o) {
+ o = o || {};
+
+ if (typeof o == 'string') {
+ o = { text: o };
+ }
+ if (o.text !== undefined) {
+ this.setText(o.text);
+ }
+ if (o.iconCls !== undefined) {
+ this.setIcon(o.iconCls);
+ }
+
+ if (o.clear) {
+ var c = o.clear,
+ wait = this.autoClear,
+ defaults = { useDefaults: true, anim: true };
+
+ if (typeof c == 'object') {
+ c = Ext.applyIf(c, defaults);
+ if (c.wait) {
+ wait = c.wait;
+ }
+ } else if (typeof c == 'number') {
+ wait = c;
+ c = defaults;
+ } else if (typeof c == 'boolean') {
+ c = defaults;
+ }
+
+ c.threadId = this.activeThreadId;
+ this.clearStatus.defer(wait, this, [c]);
+ }
+ return this;
+ },
+
+ /**
+ * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation.
+ * @param {Object} config (optional) A config object containing any or all of the following properties. If this
+ * object is not specified the status will be cleared using the defaults below:<ul>
+ * <li><tt>anim</tt> {Boolean} : (optional) True to clear the status by fading out the status element (defaults
+ * to false which clears immediately).</li>
+ * <li><tt>useDefaults</tt> {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and
+ * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).</li>
+ * </ul>
+ * @return {Ext.ux.StatusBar} this
+ */
+ clearStatus: function(o) {
+ o = o || {};
+
+ if (o.threadId && o.threadId !== this.activeThreadId) {
+ // this means the current call was made internally, but a newer
+ // thread has set a message since this call was deferred. Since
+ // we don't want to overwrite a newer message just ignore.
+ return this;
+ }
+
+ var text = o.useDefaults ? this.defaultText : this.emptyText,
+ iconCls = o.useDefaults
+ ? this.defaultIconCls
+ ? this.defaultIconCls
+ : ''
+ : '';
+
+ if (o.anim) {
+ // animate the statusEl Ext.Element
+ this.statusEl.el.fadeOut({
+ remove: false,
+ useDisplay: true,
+ scope: this,
+ callback: function() {
+ this.setStatus({
+ text: text,
+ iconCls: iconCls,
+ });
+
+ this.statusEl.el.show();
+ },
+ });
+ } else {
+ // hide/show the el to avoid jumpy text or icon
+ this.statusEl.hide();
+ this.setStatus({
+ text: text,
+ iconCls: iconCls,
+ });
+ this.statusEl.show();
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text directly. For more flexible options see {@link #setStatus}.
+ * @param {String} text (optional) The text to set (defaults to '')
+ * @return {Ext.ux.StatusBar} this
+ */
+ setText: function(text) {
+ this.activeThreadId++;
+ this.text = text || '';
+ if (this.rendered) {
+ this.statusEl.setText(this.text);
+ }
+ return this;
+ },
+
+ /**
+ * Returns the current status text.
+ * @return {String} The status text
+ */
+ getText: function() {
+ return this.text;
+ },
+
+ /**
+ * Convenience method for setting the status icon directly. For more flexible options see {@link #setStatus}.
+ * See {@link #iconCls} for complete details about customizing the icon.
+ * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed)
+ * @return {Ext.ux.StatusBar} this
+ */
+ setIcon: function(cls) {
+ this.activeThreadId++;
+ cls = cls || '';
+
+ if (this.rendered) {
+ if (this.currIconCls) {
+ this.statusEl.removeClass(this.currIconCls);
+ this.currIconCls = null;
+ }
+ if (cls.length > 0) {
+ this.statusEl.addClass(cls);
+ this.currIconCls = cls;
+ }
+ } else {
+ this.currIconCls = cls;
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text and icon to special values that are pre-configured to indicate
+ * a "busy" state, usually for loading or processing activities.
+ * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a
+ * string to use as the status text (in which case all other options for setStatus will be defaulted). Use the
+ * <tt>text</tt> and/or <tt>iconCls</tt> properties on the config to override the default {@link #busyText}
+ * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and
+ * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}.
+ * @return {Ext.ux.StatusBar} this
+ */
+ showBusy: function(o) {
+ if (typeof o == 'string') {
+ o = { text: o };
+ }
+ o = Ext.applyIf(o || {}, {
+ text: this.busyText,
+ iconCls: this.busyIconCls,
+ });
+ return this.setStatus(o);
+ },
+});
+Ext.reg('statusbar', Ext.ux.StatusBar);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/JSLoader.js b/deluge/ui/web/js/extjs/ext-extensions/JSLoader.js
new file mode 100644
index 0000000..9631fd8
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/JSLoader.js
@@ -0,0 +1,40 @@
+Ext.ux.JSLoader = function(options) {
+ Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index] = {
+ url: options.url,
+ success: true,
+ jsLoadObj: null,
+ options: options,
+ onLoad: options.onLoad || Ext.emptyFn,
+ onError: options.onError || Ext.ux.JSLoader.stdError,
+ scope: options.scope || this,
+ };
+
+ Ext.Ajax.request({
+ url: options.url,
+ scriptIndex: Ext.ux.JSLoader.index,
+ success: function(response, options) {
+ var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
+ try {
+ eval(response.responseText);
+ } catch (e) {
+ script.success = false;
+ script.onError(script.options, e);
+ }
+ if (script.success) {
+ script.onLoad.call(script.scope, script.options);
+ }
+ },
+ failure: function(response, options) {
+ var script = Ext.ux.JSLoader.scripts[options.scriptIndex];
+ script.success = false;
+ script.onError(script.options, response.status);
+ },
+ });
+};
+Ext.ux.JSLoader.index = 0;
+Ext.ux.JSLoader.scripts = [];
+Ext.ux.JSLoader.stdError = function(options, e) {
+ window.alert(
+ 'Error loading script:\n\n' + options.url + '\n\nstatus: ' + e
+ );
+};
diff --git a/deluge/ui/web/js/extjs/ext-extensions/Spinner.js b/deluge/ui/web/js/extjs/ext-extensions/Spinner.js
new file mode 100644
index 0000000..ff272d2
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/Spinner.js
@@ -0,0 +1,474 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.Spinner
+ * @extends Ext.util.Observable
+ * Creates a Spinner control utilized by Ext.ux.form.SpinnerField
+ */
+Ext.ux.Spinner = Ext.extend(Ext.util.Observable, {
+ incrementValue: 1,
+ alternateIncrementValue: 5,
+ triggerClass: 'x-form-spinner-trigger',
+ splitterClass: 'x-form-spinner-splitter',
+ alternateKey: Ext.EventObject.shiftKey,
+ defaultValue: 0,
+ accelerate: false,
+
+ constructor: function(config) {
+ Ext.ux.Spinner.superclass.constructor.call(this, config);
+ Ext.apply(this, config);
+ this.mimicing = false;
+ },
+
+ init: function(field) {
+ this.field = field;
+
+ field.afterMethod('onRender', this.doRender, this);
+ field.afterMethod('onEnable', this.doEnable, this);
+ field.afterMethod('onDisable', this.doDisable, this);
+ field.afterMethod('afterRender', this.doAfterRender, this);
+ field.afterMethod('onResize', this.doResize, this);
+ field.afterMethod('onFocus', this.doFocus, this);
+ field.beforeMethod('onDestroy', this.doDestroy, this);
+ },
+
+ doRender: function(ct, position) {
+ var el = (this.el = this.field.getEl());
+ var f = this.field;
+
+ if (!f.wrap) {
+ f.wrap = this.wrap = el.wrap({
+ cls: 'x-form-field-wrap',
+ });
+ } else {
+ this.wrap = f.wrap.addClass('x-form-field-wrap');
+ }
+
+ this.trigger = this.wrap.createChild({
+ tag: 'img',
+ src: Ext.BLANK_IMAGE_URL,
+ cls: 'x-form-trigger ' + this.triggerClass,
+ });
+
+ if (!f.width) {
+ this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
+ }
+
+ this.splitter = this.wrap.createChild({
+ tag: 'div',
+ cls: this.splitterClass,
+ style: 'width:13px; height:2px;',
+ });
+ this.splitter
+ .setRight(Ext.isIE ? 1 : 2)
+ .setTop(10)
+ .show();
+
+ this.proxy = this.trigger.createProxy('', this.splitter, true);
+ this.proxy.addClass('x-form-spinner-proxy');
+ this.proxy.setStyle('left', '0px');
+ this.proxy.setSize(14, 1);
+ this.proxy.hide();
+ this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, 'SpinnerDrag', {
+ dragElId: this.proxy.id,
+ });
+
+ this.initTrigger();
+ this.initSpinner();
+ },
+
+ doAfterRender: function() {
+ var y;
+ if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) {
+ this.el.position();
+ this.el.setY(y);
+ }
+ },
+
+ doEnable: function() {
+ if (this.wrap) {
+ this.disabled = false;
+ this.wrap.removeClass(this.field.disabledClass);
+ }
+ },
+
+ doDisable: function() {
+ if (this.wrap) {
+ this.disabled = true;
+ this.wrap.addClass(this.field.disabledClass);
+ this.el.removeClass(this.field.disabledClass);
+ }
+ },
+
+ doResize: function(w, h) {
+ if (typeof w == 'number') {
+ this.el.setWidth(w - this.trigger.getWidth());
+ }
+ this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth());
+ },
+
+ doFocus: function() {
+ if (!this.mimicing) {
+ this.wrap.addClass('x-trigger-wrap-focus');
+ this.mimicing = true;
+ Ext.get(Ext.isIE ? document.body : document).on(
+ 'mousedown',
+ this.mimicBlur,
+ this,
+ {
+ delay: 10,
+ }
+ );
+ this.el.on('keydown', this.checkTab, this);
+ }
+ },
+
+ // private
+ checkTab: function(e) {
+ if (e.getKey() == e.TAB) {
+ this.triggerBlur();
+ }
+ },
+
+ // private
+ mimicBlur: function(e) {
+ if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) {
+ this.triggerBlur();
+ }
+ },
+
+ // private
+ triggerBlur: function() {
+ this.mimicing = false;
+ Ext.get(Ext.isIE ? document.body : document).un(
+ 'mousedown',
+ this.mimicBlur,
+ this
+ );
+ this.el.un('keydown', this.checkTab, this);
+ this.field.beforeBlur();
+ this.wrap.removeClass('x-trigger-wrap-focus');
+ this.field.onBlur.call(this.field);
+ },
+
+ initTrigger: function() {
+ this.trigger.addClassOnOver('x-form-trigger-over');
+ this.trigger.addClassOnClick('x-form-trigger-click');
+ },
+
+ initSpinner: function() {
+ this.field.addEvents({
+ spin: true,
+ spinup: true,
+ spindown: true,
+ });
+
+ this.keyNav = new Ext.KeyNav(this.el, {
+ up: function(e) {
+ e.preventDefault();
+ this.onSpinUp();
+ },
+
+ down: function(e) {
+ e.preventDefault();
+ this.onSpinDown();
+ },
+
+ pageUp: function(e) {
+ e.preventDefault();
+ this.onSpinUpAlternate();
+ },
+
+ pageDown: function(e) {
+ e.preventDefault();
+ this.onSpinDownAlternate();
+ },
+
+ scope: this,
+ });
+
+ this.repeater = new Ext.util.ClickRepeater(this.trigger, {
+ accelerate: this.accelerate,
+ });
+ this.field.mon(this.repeater, 'click', this.onTriggerClick, this, {
+ preventDefault: true,
+ });
+
+ this.field.mon(this.trigger, {
+ mouseover: this.onMouseOver,
+ mouseout: this.onMouseOut,
+ mousemove: this.onMouseMove,
+ mousedown: this.onMouseDown,
+ mouseup: this.onMouseUp,
+ scope: this,
+ preventDefault: true,
+ });
+
+ this.field.mon(this.wrap, 'mousewheel', this.handleMouseWheel, this);
+
+ this.dd.setXConstraint(0, 0, 10);
+ this.dd.setYConstraint(1500, 1500, 10);
+ this.dd.endDrag = this.endDrag.createDelegate(this);
+ this.dd.startDrag = this.startDrag.createDelegate(this);
+ this.dd.onDrag = this.onDrag.createDelegate(this);
+ },
+
+ onMouseOver: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ this.tmpHoverClass =
+ Ext.EventObject.getPageY() < middle
+ ? 'x-form-spinner-overup'
+ : 'x-form-spinner-overdown';
+ this.trigger.addClass(this.tmpHoverClass);
+ },
+
+ //private
+ onMouseOut: function() {
+ this.trigger.removeClass(this.tmpHoverClass);
+ },
+
+ //private
+ onMouseMove: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ if (
+ (Ext.EventObject.getPageY() > middle &&
+ this.tmpHoverClass == 'x-form-spinner-overup') ||
+ (Ext.EventObject.getPageY() < middle &&
+ this.tmpHoverClass == 'x-form-spinner-overdown')
+ ) {
+ }
+ },
+
+ //private
+ onMouseDown: function() {
+ if (this.disabled) {
+ return;
+ }
+ var middle = this.getMiddle();
+ this.tmpClickClass =
+ Ext.EventObject.getPageY() < middle
+ ? 'x-form-spinner-clickup'
+ : 'x-form-spinner-clickdown';
+ this.trigger.addClass(this.tmpClickClass);
+ },
+
+ //private
+ onMouseUp: function() {
+ this.trigger.removeClass(this.tmpClickClass);
+ },
+
+ //private
+ onTriggerClick: function() {
+ if (this.disabled || this.el.dom.readOnly) {
+ return;
+ }
+ var middle = this.getMiddle();
+ var ud = Ext.EventObject.getPageY() < middle ? 'Up' : 'Down';
+ this['onSpin' + ud]();
+ },
+
+ //private
+ getMiddle: function() {
+ var t = this.trigger.getTop();
+ var h = this.trigger.getHeight();
+ var middle = t + h / 2;
+ return middle;
+ },
+
+ //private
+ //checks if control is allowed to spin
+ isSpinnable: function() {
+ if (this.disabled || this.el.dom.readOnly) {
+ Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly
+ return false;
+ }
+ return true;
+ },
+
+ handleMouseWheel: function(e) {
+ //disable scrolling when not focused
+ if (this.wrap.hasClass('x-trigger-wrap-focus') == false) {
+ return;
+ }
+
+ var delta = e.getWheelDelta();
+ if (delta > 0) {
+ this.onSpinUp();
+ e.stopEvent();
+ } else if (delta < 0) {
+ this.onSpinDown();
+ e.stopEvent();
+ }
+ },
+
+ //private
+ startDrag: function() {
+ this.proxy.show();
+ this._previousY = Ext.fly(this.dd.getDragEl()).getTop();
+ },
+
+ //private
+ endDrag: function() {
+ this.proxy.hide();
+ },
+
+ //private
+ onDrag: function() {
+ if (this.disabled) {
+ return;
+ }
+ var y = Ext.fly(this.dd.getDragEl()).getTop();
+ var ud = '';
+
+ if (this._previousY > y) {
+ ud = 'Up';
+ } //up
+ if (this._previousY < y) {
+ ud = 'Down';
+ } //down
+ if (ud != '') {
+ this['onSpin' + ud]();
+ }
+
+ this._previousY = y;
+ },
+
+ //private
+ onSpinUp: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ if (Ext.EventObject.shiftKey == true) {
+ this.onSpinUpAlternate();
+ return;
+ } else {
+ this.spin(false, false);
+ }
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spinup', this);
+ },
+
+ //private
+ onSpinDown: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ if (Ext.EventObject.shiftKey == true) {
+ this.onSpinDownAlternate();
+ return;
+ } else {
+ this.spin(true, false);
+ }
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spindown', this);
+ },
+
+ //private
+ onSpinUpAlternate: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ this.spin(false, true);
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spinup', this);
+ },
+
+ //private
+ onSpinDownAlternate: function() {
+ if (this.isSpinnable() == false) {
+ return;
+ }
+ this.spin(true, true);
+ this.field.fireEvent('spin', this);
+ this.field.fireEvent('spindown', this);
+ },
+
+ spin: function(down, alternate) {
+ var v = parseFloat(this.field.getValue());
+ var incr =
+ alternate == true
+ ? this.alternateIncrementValue
+ : this.incrementValue;
+ down == true ? (v -= incr) : (v += incr);
+
+ v = isNaN(v) ? this.defaultValue : v;
+ v = this.fixBoundries(v);
+ this.field.setRawValue(v);
+ },
+
+ fixBoundries: function(value) {
+ var v = value;
+
+ if (this.field.minValue != undefined && v < this.field.minValue) {
+ v = this.field.minValue;
+ }
+ if (this.field.maxValue != undefined && v > this.field.maxValue) {
+ v = this.field.maxValue;
+ }
+
+ return this.fixPrecision(v);
+ },
+
+ // private
+ fixPrecision: function(value) {
+ var nan = isNaN(value);
+ if (
+ !this.field.allowDecimals ||
+ this.field.decimalPrecision == -1 ||
+ nan ||
+ !value
+ ) {
+ return nan ? '' : value;
+ }
+ return parseFloat(
+ parseFloat(value).toFixed(this.field.decimalPrecision)
+ );
+ },
+
+ doDestroy: function() {
+ if (this.trigger) {
+ this.trigger.remove();
+ }
+ if (this.wrap) {
+ this.wrap.remove();
+ delete this.field.wrap;
+ }
+
+ if (this.splitter) {
+ this.splitter.remove();
+ }
+
+ if (this.dd) {
+ this.dd.unreg();
+ this.dd = null;
+ }
+
+ if (this.proxy) {
+ this.proxy.remove();
+ }
+
+ if (this.repeater) {
+ this.repeater.purgeListeners();
+ }
+ if (this.mimicing) {
+ Ext.get(Ext.isIE ? document.body : document).un(
+ 'mousedown',
+ this.mimicBlur,
+ this
+ );
+ }
+ },
+});
+
+//backwards compat
+Ext.form.Spinner = Ext.ux.Spinner;
diff --git a/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js b/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js
new file mode 100644
index 0000000..a12b8f9
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/StatusBar.js
@@ -0,0 +1,422 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.StatusBar
+ * <p>Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}. In addition to
+ * supporting the standard {@link Ext.Toolbar} interface for adding buttons, menus and other items, the StatusBar
+ * provides a greedy status element that can be aligned to either side and has convenient methods for setting the
+ * status text and icon. You can also indicate that something is processing using the {@link #showBusy} method.</p>
+ * <pre><code>
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ id: 'my-status',
+
+ // defaults to use when the status is cleared:
+ defaultText: 'Default status text',
+ defaultIconCls: 'default-icon',
+
+ // values to set initially:
+ text: 'Ready',
+ iconCls: 'ready-icon',
+
+ // any standard Toolbar items:
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// Update the status bar later in code:
+var sb = Ext.getCmp('my-status');
+sb.setStatus({
+ text: 'OK',
+ iconCls: 'ok-icon',
+ clear: true // auto-clear after a set interval
+});
+
+// Set the status bar to show that something is processing:
+sb.showBusy();
+
+// processing....
+
+sb.clearStatus(); // once completeed
+</code></pre>
+ * @extends Ext.Toolbar
+ * @constructor
+ * Creates a new StatusBar
+ * @param {Object/Array} config A config object
+ */
+Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, {
+ /**
+ * @cfg {String} statusAlign
+ * The alignment of the status element within the overall StatusBar layout. When the StatusBar is rendered,
+ * it creates an internal div containing the status text and icon. Any additional Toolbar items added in the
+ * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be
+ * rendered, in added order, to the opposite side. The status element is greedy, so it will automatically
+ * expand to take up all sapce left over by any other items. Example usage:
+ * <pre><code>
+// Create a left-aligned status bar containing a button,
+// separator and text item that will be right-aligned (default):
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// By adding the statusAlign config, this will create the
+// exact same toolbar, except the status and toolbar item
+// layout will be reversed from the previous example:
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ statusAlign: 'right',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+</code></pre>
+ */
+ /**
+ * @cfg {String} defaultText
+ * The default {@link #text} value. This will be used anytime the status bar is cleared with the
+ * <tt>useDefaults:true</tt> option (defaults to '').
+ */
+ /**
+ * @cfg {String} defaultIconCls
+ * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon).
+ * This will be used anytime the status bar is cleared with the <tt>useDefaults:true</tt> option (defaults to '').
+ */
+ /**
+ * @cfg {String} text
+ * A string that will be <b>initially</b> set as the status message. This string
+ * will be set as innerHTML (html tags are accepted) for the toolbar item.
+ * If not specified, the value set for <code>{@link #defaultText}</code>
+ * will be used.
+ */
+ /**
+ * @cfg {String} iconCls
+ * A CSS class that will be <b>initially</b> set as the status bar icon and is
+ * expected to provide a background image (defaults to '').
+ * Example usage:<pre><code>
+// Example CSS rule:
+.x-statusbar .x-status-custom {
+ padding-left: 25px;
+ background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
+}
+
+// Setting a default icon:
+var sb = new Ext.ux.StatusBar({
+ defaultIconCls: 'x-status-custom'
+});
+
+// Changing the icon:
+sb.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom'
+});
+</code></pre>
+ */
+
+ /**
+ * @cfg {String} cls
+ * The base class applied to the containing element for this component on render (defaults to 'x-statusbar')
+ */
+ cls: 'x-statusbar',
+ /**
+ * @cfg {String} busyIconCls
+ * The default <code>{@link #iconCls}</code> applied when calling
+ * <code>{@link #showBusy}</code> (defaults to <tt>'x-status-busy'</tt>).
+ * It can be overridden at any time by passing the <code>iconCls</code>
+ * argument into <code>{@link #showBusy}</code>.
+ */
+ busyIconCls: 'x-status-busy',
+ /**
+ * @cfg {String} busyText
+ * The default <code>{@link #text}</code> applied when calling
+ * <code>{@link #showBusy}</code> (defaults to <tt>'Loading...'</tt>).
+ * It can be overridden at any time by passing the <code>text</code>
+ * argument into <code>{@link #showBusy}</code>.
+ */
+ busyText: 'Loading...',
+ /**
+ * @cfg {Number} autoClear
+ * The number of milliseconds to wait after setting the status via
+ * <code>{@link #setStatus}</code> before automatically clearing the status
+ * text and icon (defaults to <tt>5000</tt>). Note that this only applies
+ * when passing the <tt>clear</tt> argument to <code>{@link #setStatus}</code>
+ * since that is the only way to defer clearing the status. This can
+ * be overridden by specifying a different <tt>wait</tt> value in
+ * <code>{@link #setStatus}</code>. Calls to <code>{@link #clearStatus}</code>
+ * always clear the status bar immediately and ignore this value.
+ */
+ autoClear: 5000,
+
+ /**
+ * @cfg {String} emptyText
+ * The text string to use if no text has been set. Defaults to
+ * <tt>'&nbsp;'</tt>). If there are no other items in the toolbar using
+ * an empty string (<tt>''</tt>) for this value would end up in the toolbar
+ * height collapsing since the empty string will not maintain the toolbar
+ * height. Use <tt>''</tt> if the toolbar should collapse in height
+ * vertically when no text is specified and there are no other items in
+ * the toolbar.
+ */
+ emptyText: '&nbsp;',
+
+ // private
+ activeThreadId: 0,
+
+ // private
+ initComponent: function() {
+ if (this.statusAlign == 'right') {
+ this.cls += ' x-status-right';
+ }
+ Ext.ux.StatusBar.superclass.initComponent.call(this);
+ },
+
+ // private
+ afterRender: function() {
+ Ext.ux.StatusBar.superclass.afterRender.call(this);
+
+ var right = this.statusAlign == 'right';
+ this.currIconCls = this.iconCls || this.defaultIconCls;
+ this.statusEl = new Ext.Toolbar.TextItem({
+ cls: 'x-status-text ' + (this.currIconCls || ''),
+ text: this.text || this.defaultText || '',
+ });
+
+ if (right) {
+ this.add('->');
+ this.add(this.statusEl);
+ } else {
+ this.insert(0, this.statusEl);
+ this.insert(1, '->');
+ }
+ this.doLayout();
+ },
+
+ /**
+ * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the
+ * status that was set after a specified interval.
+ * @param {Object/String} config A config object specifying what status to set, or a string assumed
+ * to be the status text (and all other options are defaulted as explained below). A config
+ * object containing any or all of the following properties can be passed:<ul>
+ * <li><tt>text</tt> {String} : (optional) The status text to display. If not specified, any current
+ * status text will remain unchanged.</li>
+ * <li><tt>iconCls</tt> {String} : (optional) The CSS class used to customize the status icon (see
+ * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.</li>
+ * <li><tt>clear</tt> {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will
+ * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not
+ * specified, the new status will not be auto-cleared and will stay until updated again or cleared using
+ * {@link #clearStatus}. If <tt>true</tt> is passed, the status will be cleared using {@link #autoClear},
+ * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed,
+ * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value.
+ * All other options will be defaulted as with the boolean option. To customize any other options,
+ * you can pass an object in the format:<ul>
+ * <li><tt>wait</tt> {Number} : (optional) The number of milliseconds to wait before clearing
+ * (defaults to {@link #autoClear}).</li>
+ * <li><tt>anim</tt> {Number} : (optional) False to clear the status immediately once the callback
+ * executes (defaults to true which fades the status out).</li>
+ * <li><tt>useDefaults</tt> {Number} : (optional) False to completely clear the status text and iconCls
+ * (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
+ * </ul></li></ul>
+ * Example usage:<pre><code>
+// Simple call to update the text
+statusBar.setStatus('New status');
+
+// Set the status and icon, auto-clearing with default options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: true
+});
+
+// Auto-clear with custom options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: {
+ wait: 8000,
+ anim: false,
+ useDefaults: false
+ }
+});
+</code></pre>
+ * @return {Ext.ux.StatusBar} this
+ */
+ setStatus: function(o) {
+ o = o || {};
+
+ if (typeof o == 'string') {
+ o = { text: o };
+ }
+ if (o.text !== undefined) {
+ this.setText(o.text);
+ }
+ if (o.iconCls !== undefined) {
+ this.setIcon(o.iconCls);
+ }
+
+ if (o.clear) {
+ var c = o.clear,
+ wait = this.autoClear,
+ defaults = { useDefaults: true, anim: true };
+
+ if (typeof c == 'object') {
+ c = Ext.applyIf(c, defaults);
+ if (c.wait) {
+ wait = c.wait;
+ }
+ } else if (typeof c == 'number') {
+ wait = c;
+ c = defaults;
+ } else if (typeof c == 'boolean') {
+ c = defaults;
+ }
+
+ c.threadId = this.activeThreadId;
+ this.clearStatus.defer(wait, this, [c]);
+ }
+ return this;
+ },
+
+ /**
+ * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation.
+ * @param {Object} config (optional) A config object containing any or all of the following properties. If this
+ * object is not specified the status will be cleared using the defaults below:<ul>
+ * <li><tt>anim</tt> {Boolean} : (optional) True to clear the status by fading out the status element (defaults
+ * to false which clears immediately).</li>
+ * <li><tt>useDefaults</tt> {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and
+ * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).</li>
+ * </ul>
+ * @return {Ext.ux.StatusBar} this
+ */
+ clearStatus: function(o) {
+ o = o || {};
+
+ if (o.threadId && o.threadId !== this.activeThreadId) {
+ // this means the current call was made internally, but a newer
+ // thread has set a message since this call was deferred. Since
+ // we don't want to overwrite a newer message just ignore.
+ return this;
+ }
+
+ var text = o.useDefaults ? this.defaultText : this.emptyText,
+ iconCls = o.useDefaults
+ ? this.defaultIconCls
+ ? this.defaultIconCls
+ : ''
+ : '';
+
+ if (o.anim) {
+ // animate the statusEl Ext.Element
+ this.statusEl.el.fadeOut({
+ remove: false,
+ useDisplay: true,
+ scope: this,
+ callback: function() {
+ this.setStatus({
+ text: text,
+ iconCls: iconCls,
+ });
+
+ this.statusEl.el.show();
+ },
+ });
+ } else {
+ // hide/show the el to avoid jumpy text or icon
+ this.statusEl.hide();
+ this.setStatus({
+ text: text,
+ iconCls: iconCls,
+ });
+ this.statusEl.show();
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text directly. For more flexible options see {@link #setStatus}.
+ * @param {String} text (optional) The text to set (defaults to '')
+ * @return {Ext.ux.StatusBar} this
+ */
+ setText: function(text) {
+ this.activeThreadId++;
+ this.text = text || '';
+ if (this.rendered) {
+ this.statusEl.setText(this.text);
+ }
+ return this;
+ },
+
+ /**
+ * Returns the current status text.
+ * @return {String} The status text
+ */
+ getText: function() {
+ return this.text;
+ },
+
+ /**
+ * Convenience method for setting the status icon directly. For more flexible options see {@link #setStatus}.
+ * See {@link #iconCls} for complete details about customizing the icon.
+ * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed)
+ * @return {Ext.ux.StatusBar} this
+ */
+ setIcon: function(cls) {
+ this.activeThreadId++;
+ cls = cls || '';
+
+ if (this.rendered) {
+ if (this.currIconCls) {
+ this.statusEl.removeClass(this.currIconCls);
+ this.currIconCls = null;
+ }
+ if (cls.length > 0) {
+ this.statusEl.addClass(cls);
+ this.currIconCls = cls;
+ }
+ } else {
+ this.currIconCls = cls;
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text and icon to special values that are pre-configured to indicate
+ * a "busy" state, usually for loading or processing activities.
+ * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a
+ * string to use as the status text (in which case all other options for setStatus will be defaulted). Use the
+ * <tt>text</tt> and/or <tt>iconCls</tt> properties on the config to override the default {@link #busyText}
+ * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and
+ * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}.
+ * @return {Ext.ux.StatusBar} this
+ */
+ showBusy: function(o) {
+ if (typeof o == 'string') {
+ o = { text: o };
+ }
+ o = Ext.applyIf(o || {}, {
+ text: this.busyText,
+ iconCls: this.busyIconCls,
+ });
+ return this.setStatus(o);
+ },
+});
+Ext.reg('statusbar', Ext.ux.StatusBar);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js b/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js
new file mode 100644
index 0000000..ca15073
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/FileUploadField.js
@@ -0,0 +1,208 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ * @class Ext.ux.form.FileUploadField
+ * @extends Ext.form.TextField
+ * Creates a file upload field.
+ * @xtype fileuploadfield
+ */
+Ext.ux.form.FileUploadField = Ext.extend(Ext.form.TextField, {
+ /**
+ * @cfg {String} buttonText The button text to display on the upload button (defaults to
+ * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text
+ * value will be used instead if available.
+ */
+ buttonText: 'Browse...',
+ /**
+ * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible
+ * text field (defaults to false). If true, all inherited TextField members will still be available.
+ */
+ buttonOnly: false,
+ /**
+ * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field
+ * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false.
+ */
+ buttonOffset: 3,
+
+ /**
+ * @cfg {Boolean} multiple True to select more than one file. (defaults to false).
+ * Note that this only applies if the HTML doc is using HTML5.
+ */
+ multiple: false,
+
+ /**
+ * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object.
+ */
+
+ // private
+ readOnly: true,
+
+ /**
+ * @hide
+ * @method autoSize
+ */
+ autoSize: Ext.emptyFn,
+
+ // private
+ initComponent: function() {
+ Ext.ux.form.FileUploadField.superclass.initComponent.call(this);
+
+ this.addEvents(
+ /**
+ * @event fileselected
+ * Fires when the underlying file input field's value has changed from the user
+ * selecting a new file from the system file selection dialog.
+ * @param {Ext.ux.form.FileUploadField} this
+ * @param {String} value The file value returned by the underlying file input field
+ */
+ 'fileselected'
+ );
+ },
+
+ // private
+ onRender: function(ct, position) {
+ Ext.ux.form.FileUploadField.superclass.onRender.call(
+ this,
+ ct,
+ position
+ );
+
+ this.wrap = this.el.wrap({ cls: 'x-form-field-wrap x-form-file-wrap' });
+ this.el.addClass('x-form-file-text');
+ this.el.dom.removeAttribute('name');
+ this.createFileInput();
+
+ var btnCfg = Ext.applyIf(this.buttonCfg || {}, {
+ text: this.buttonText,
+ });
+ this.button = new Ext.Button(
+ Ext.apply(btnCfg, {
+ renderTo: this.wrap,
+ cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : ''),
+ })
+ );
+
+ if (this.buttonOnly) {
+ this.el.hide();
+ this.wrap.setWidth(this.button.getEl().getWidth());
+ }
+
+ this.bindListeners();
+ this.resizeEl = this.positionEl = this.wrap;
+ },
+
+ bindListeners: function() {
+ this.fileInput.on({
+ scope: this,
+ mouseenter: function() {
+ this.button.addClass(['x-btn-over', 'x-btn-focus']);
+ },
+ mouseleave: function() {
+ this.button.removeClass([
+ 'x-btn-over',
+ 'x-btn-focus',
+ 'x-btn-click',
+ ]);
+ },
+ mousedown: function() {
+ this.button.addClass('x-btn-click');
+ },
+ mouseup: function() {
+ this.button.removeClass([
+ 'x-btn-over',
+ 'x-btn-focus',
+ 'x-btn-click',
+ ]);
+ },
+ change: function() {
+ var value = this.fileInput.dom.files;
+ // Fallback to value.
+ if (!value) value = this.fileInput.dom.value;
+ this.setValue(value);
+ this.fireEvent('fileselected', this, value);
+ },
+ });
+ },
+
+ createFileInput: function() {
+ this.fileInput = this.wrap.createChild({
+ id: this.getFileInputId(),
+ name: this.name || this.getId(),
+ cls: 'x-form-file',
+ tag: 'input',
+ type: 'file',
+ size: 1,
+ });
+ this.fileInput.dom.multiple = this.multiple;
+ },
+
+ reset: function() {
+ if (this.rendered) {
+ this.fileInput.remove();
+ this.createFileInput();
+ this.bindListeners();
+ }
+ Ext.ux.form.FileUploadField.superclass.reset.call(this);
+ },
+
+ // private
+ getFileInputId: function() {
+ return this.id + '-file';
+ },
+
+ // private
+ onResize: function(w, h) {
+ Ext.ux.form.FileUploadField.superclass.onResize.call(this, w, h);
+
+ this.wrap.setWidth(w);
+
+ if (!this.buttonOnly) {
+ var w =
+ this.wrap.getWidth() -
+ this.button.getEl().getWidth() -
+ this.buttonOffset;
+ this.el.setWidth(w);
+ }
+ },
+
+ // private
+ onDestroy: function() {
+ Ext.ux.form.FileUploadField.superclass.onDestroy.call(this);
+ Ext.destroy(this.fileInput, this.button, this.wrap);
+ },
+
+ onDisable: function() {
+ Ext.ux.form.FileUploadField.superclass.onDisable.call(this);
+ this.doDisable(true);
+ },
+
+ onEnable: function() {
+ Ext.ux.form.FileUploadField.superclass.onEnable.call(this);
+ this.doDisable(false);
+ },
+
+ // private
+ doDisable: function(disabled) {
+ this.fileInput.dom.disabled = disabled;
+ this.button.setDisabled(disabled);
+ },
+
+ // private
+ preFocus: Ext.emptyFn,
+
+ // private
+ alignErrorIcon: function() {
+ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
+ },
+});
+
+Ext.reg('fileuploadfield', Ext.ux.form.FileUploadField);
+
+// backwards compat
+Ext.form.FileUploadField = Ext.ux.form.FileUploadField;
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js b/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js
new file mode 100644
index 0000000..134e7a1
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/RadioGroupFix.js
@@ -0,0 +1,50 @@
+/**
+ * Ext.ux.form.RadioGroup.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Allow radiogroups to be treated as a single form element.
+Ext.override(Ext.form.RadioGroup, {
+ afterRender: function() {
+ this.items.each(function(i) {
+ this.relayEvents(i, ['check']);
+ }, this);
+ if (this.lazyValue) {
+ this.setValue(this.value);
+ delete this.value;
+ delete this.lazyValue;
+ }
+ Ext.form.RadioGroup.superclass.afterRender.call(this);
+ },
+
+ getName: function() {
+ return this.items.first().getName();
+ },
+
+ getValue: function() {
+ return this.items.first().getGroupValue();
+ },
+
+ setValue: function(v) {
+ if (!this.items.each) {
+ this.value = v;
+ this.lazyValue = true;
+ return;
+ }
+ this.items.each(function(item) {
+ if (item.rendered) {
+ var checked = item.el.getValue() == String(v);
+ item.el.dom.checked = checked;
+ item.el.dom.defaultChecked = checked;
+ item.wrap[checked ? 'addClass' : 'removeClass'](
+ item.checkedCls
+ );
+ }
+ });
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js
new file mode 100644
index 0000000..d14f320
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerField.js
@@ -0,0 +1,68 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ * @class Ext.ux.form.SpinnerField
+ * @extends Ext.form.NumberField
+ * Creates a field utilizing Ext.ux.Spinner
+ * @xtype spinnerfield
+ */
+Ext.ux.form.SpinnerField = Ext.extend(Ext.form.NumberField, {
+ actionMode: 'wrap',
+ deferHeight: true,
+ autoSize: Ext.emptyFn,
+ onBlur: Ext.emptyFn,
+ adjustSize: Ext.BoxComponent.prototype.adjustSize,
+
+ constructor: function(config) {
+ var spinnerConfig = Ext.copyTo(
+ {},
+ config,
+ 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass'
+ );
+
+ var spl = (this.spinner = new Ext.ux.Spinner(spinnerConfig));
+
+ var plugins = config.plugins
+ ? Ext.isArray(config.plugins)
+ ? config.plugins.push(spl)
+ : [config.plugins, spl]
+ : spl;
+
+ Ext.ux.form.SpinnerField.superclass.constructor.call(
+ this,
+ Ext.apply(config, { plugins: plugins })
+ );
+ },
+
+ // private
+ getResizeEl: function() {
+ return this.wrap;
+ },
+
+ // private
+ getPositionEl: function() {
+ return this.wrap;
+ },
+
+ // private
+ alignErrorIcon: function() {
+ if (this.wrap) {
+ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
+ }
+ },
+
+ validateBlur: function() {
+ return true;
+ },
+});
+
+Ext.reg('spinnerfield', Ext.ux.form.SpinnerField);
+
+//backwards compat
+Ext.form.SpinnerField = Ext.ux.form.SpinnerField;
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js
new file mode 100644
index 0000000..6784ae0
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerFieldFix.js
@@ -0,0 +1,13 @@
+/**
+ * Ext.ux.form.SpinnerField.js
+ *
+ * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.override(Ext.ux.form.SpinnerField, {
+ onBlur: Ext.form.Field.prototype.onBlur,
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js
new file mode 100644
index 0000000..eafc4e1
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/SpinnerGroup.js
@@ -0,0 +1,206 @@
+/**
+ * Ext.ux.form.SpinnerGroup.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.ns('Ext.ux.form');
+
+/**
+ *
+ */
+Ext.ux.form.SpinnerGroup = Ext.extend(Ext.form.CheckboxGroup, {
+ // private
+ defaultType: 'spinnerfield',
+ anchor: '98%',
+
+ // private
+ groupCls: 'x-form-spinner-group',
+
+ colCfg: {},
+
+ // private
+ onRender: function(ct, position) {
+ if (!this.el) {
+ var panelCfg = {
+ cls: this.groupCls,
+ layout: 'column',
+ border: false,
+ renderTo: ct,
+ };
+ var colCfg = Ext.apply(
+ {
+ defaultType: this.defaultType,
+ layout: 'form',
+ border: false,
+ labelWidth: 60,
+ defaults: {
+ hideLabel: true,
+ anchor: '60%',
+ },
+ },
+ this.colCfg
+ );
+
+ if (this.items[0].items) {
+ // The container has standard ColumnLayout configs, so pass them in directly
+
+ Ext.apply(panelCfg, {
+ layoutConfig: { columns: this.items.length },
+ defaults: this.defaults,
+ items: this.items,
+ });
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ Ext.applyIf(this.items[i], colCfg);
+ }
+ } else {
+ // The container has field item configs, so we have to generate the column
+ // panels first then move the items into the columns as needed.
+
+ var numCols,
+ cols = [];
+
+ if (typeof this.columns == 'string') {
+ // 'auto' so create a col per item
+ this.columns = this.items.length;
+ }
+ if (!Ext.isArray(this.columns)) {
+ var cs = [];
+ for (var i = 0; i < this.columns; i++) {
+ cs.push((100 / this.columns) * 0.01); // distribute by even %
+ }
+ this.columns = cs;
+ }
+
+ numCols = this.columns.length;
+
+ // Generate the column configs with the correct width setting
+ for (var i = 0; i < numCols; i++) {
+ var cc = Ext.apply({ items: [] }, colCfg);
+ cc[
+ this.columns[i] <= 1 ? 'columnWidth' : 'width'
+ ] = this.columns[i];
+ if (this.defaults) {
+ cc.defaults = Ext.apply(
+ cc.defaults || {},
+ this.defaults
+ );
+ }
+ cols.push(cc);
+ }
+
+ // Distribute the original items into the columns
+ if (this.vertical) {
+ var rows = Math.ceil(this.items.length / numCols),
+ ri = 0;
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ if (i > 0 && i % rows == 0) {
+ ri++;
+ }
+ if (this.items[i].fieldLabel) {
+ this.items[i].hideLabel = false;
+ }
+ cols[ri].items.push(this.items[i]);
+ }
+ } else {
+ for (var i = 0, len = this.items.length; i < len; i++) {
+ var ci = i % numCols;
+ if (this.items[i].fieldLabel) {
+ this.items[i].hideLabel = false;
+ }
+ cols[ci].items.push(this.items[i]);
+ }
+ }
+
+ Ext.apply(panelCfg, {
+ layoutConfig: { columns: numCols },
+ items: cols,
+ });
+ }
+
+ this.panel = new Ext.Panel(panelCfg);
+ this.el = this.panel.getEl();
+
+ if (this.forId && this.itemCls) {
+ var l = this.el.up(this.itemCls).child('label', true);
+ if (l) {
+ l.setAttribute('htmlFor', this.forId);
+ }
+ }
+
+ var fields = this.panel.findBy(function(c) {
+ return c.isFormField;
+ }, this);
+
+ this.items = new Ext.util.MixedCollection();
+ this.items.addAll(fields);
+
+ this.items.each(function(field) {
+ field.on('spin', this.onFieldChange, this);
+ field.on('change', this.onFieldChange, this);
+ }, this);
+
+ if (this.lazyValueSet) {
+ this.setValue(this.value);
+ delete this.value;
+ delete this.lazyValueSet;
+ }
+
+ if (this.lazyRawValueSet) {
+ this.setRawValue(this.rawValue);
+ delete this.rawValue;
+ delete this.lazyRawValueSet;
+ }
+ }
+
+ Ext.ux.form.SpinnerGroup.superclass.onRender.call(this, ct, position);
+ },
+
+ onFieldChange: function(spinner) {
+ this.fireEvent('change', this, this.getValue());
+ },
+
+ initValue: Ext.emptyFn,
+
+ getValue: function() {
+ var value = [this.items.getCount()];
+ this.items.each(function(item, i) {
+ value[i] = Number(item.getValue());
+ });
+ return value;
+ },
+
+ getRawValue: function() {
+ var value = [this.items.getCount()];
+ this.items.each(function(item, i) {
+ value[i] = Number(item.getRawValue());
+ });
+ return value;
+ },
+
+ setValue: function(value) {
+ if (!this.rendered) {
+ this.value = value;
+ this.lazyValueSet = true;
+ } else {
+ this.items.each(function(item, i) {
+ item.setValue(value[i]);
+ });
+ }
+ },
+
+ setRawValue: function(value) {
+ if (!this.rendered) {
+ this.rawValue = value;
+ this.lazyRawValueSet = true;
+ } else {
+ this.items.each(function(item, i) {
+ item.setRawValue(value[i]);
+ });
+ }
+ },
+});
+Ext.reg('spinnergroup', Ext.ux.form.SpinnerGroup);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js b/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js
new file mode 100644
index 0000000..27eebf3
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/form/ToggleField.js
@@ -0,0 +1,75 @@
+/**
+ * Ext.ux.form.ToggleField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+Ext.namespace('Ext.ux.form');
+
+/**
+ * Ext.ux.form.ToggleField class
+ *
+ * @author Damien Churchill
+ * @version v0.1
+ *
+ * @class Ext.ux.form.ToggleField
+ * @extends Ext.form.TriggerField
+ */
+Ext.ux.form.ToggleField = Ext.extend(Ext.form.Field, {
+ cls: 'x-toggle-field',
+
+ initComponent: function() {
+ Ext.ux.form.ToggleField.superclass.initComponent.call(this);
+
+ this.toggle = new Ext.form.Checkbox();
+ this.toggle.on('check', this.onToggleCheck, this);
+
+ this.input = new Ext.form.TextField({
+ disabled: true,
+ });
+ },
+
+ onRender: function(ct, position) {
+ if (!this.el) {
+ this.panel = new Ext.Panel({
+ cls: this.groupCls,
+ layout: 'table',
+ layoutConfig: {
+ columns: 2,
+ },
+ border: false,
+ renderTo: ct,
+ });
+ this.panel.ownerCt = this;
+ this.el = this.panel.getEl();
+
+ this.panel.add(this.toggle);
+ this.panel.add(this.input);
+ this.panel.doLayout();
+
+ this.toggle
+ .getEl()
+ .parent()
+ .setStyle('padding-right', '10px');
+ }
+ Ext.ux.form.ToggleField.superclass.onRender.call(this, ct, position);
+ },
+
+ // private
+ onResize: function(w, h) {
+ this.panel.setSize(w, h);
+ this.panel.doLayout();
+
+ // we substract 10 for the padding :-)
+ var inputWidth = w - this.toggle.getSize().width - 25;
+ this.input.setSize(inputWidth, h);
+ },
+
+ onToggleCheck: function(toggle, checked) {
+ this.input.setDisabled(!checked);
+ },
+});
+Ext.reg('togglefield', Ext.ux.form.ToggleField);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js b/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js
new file mode 100644
index 0000000..e9f0e0c
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/grid/BufferView.js
@@ -0,0 +1,270 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.grid');
+
+/**
+ * @class Ext.ux.grid.BufferView
+ * @extends Ext.grid.GridView
+ * A custom GridView which renders rows on an as-needed basis.
+ */
+Ext.ux.grid.BufferView = Ext.extend(Ext.grid.GridView, {
+ /**
+ * @cfg {Number} rowHeight
+ * The height of a row in the grid.
+ */
+ rowHeight: 19,
+
+ /**
+ * @cfg {Number} borderHeight
+ * The combined height of border-top and border-bottom of a row.
+ */
+ borderHeight: 2,
+
+ /**
+ * @cfg {Boolean/Number} scrollDelay
+ * The number of milliseconds before rendering rows out of the visible
+ * viewing area. Defaults to 100. Rows will render immediately with a config
+ * of false.
+ */
+ scrollDelay: 100,
+
+ /**
+ * @cfg {Number} cacheSize
+ * The number of rows to look forward and backwards from the currently viewable
+ * area. The cache applies only to rows that have been rendered already.
+ */
+ cacheSize: 20,
+
+ /**
+ * @cfg {Number} cleanDelay
+ * The number of milliseconds to buffer cleaning of extra rows not in the
+ * cache.
+ */
+ cleanDelay: 500,
+
+ initTemplates: function() {
+ Ext.ux.grid.BufferView.superclass.initTemplates.call(this);
+ var ts = this.templates;
+ // empty div to act as a place holder for a row
+ ts.rowHolder = new Ext.Template(
+ '<div class="x-grid3-row {alt}" style="{tstyle}"></div>'
+ );
+ ts.rowHolder.disableFormats = true;
+ ts.rowHolder.compile();
+
+ ts.rowBody = new Ext.Template(
+ '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
+ '<tbody><tr>{cells}</tr>',
+ this.enableRowBody
+ ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>'
+ : '',
+ '</tbody></table>'
+ );
+ ts.rowBody.disableFormats = true;
+ ts.rowBody.compile();
+ },
+
+ getStyleRowHeight: function() {
+ return Ext.isBorderBox
+ ? this.rowHeight + this.borderHeight
+ : this.rowHeight;
+ },
+
+ getCalculatedRowHeight: function() {
+ return this.rowHeight + this.borderHeight;
+ },
+
+ getVisibleRowCount: function() {
+ var rh = this.getCalculatedRowHeight(),
+ visibleHeight = this.scroller.dom.clientHeight;
+ return visibleHeight < 1 ? 0 : Math.ceil(visibleHeight / rh);
+ },
+
+ getVisibleRows: function() {
+ var count = this.getVisibleRowCount(),
+ sc = this.scroller.dom.scrollTop,
+ start =
+ sc === 0
+ ? 0
+ : Math.floor(sc / this.getCalculatedRowHeight()) - 1;
+ return {
+ first: Math.max(start, 0),
+ last: Math.min(start + count + 2, this.ds.getCount() - 1),
+ };
+ },
+
+ doRender: function(cs, rs, ds, startRow, colCount, stripe, onlyBody) {
+ var ts = this.templates,
+ ct = ts.cell,
+ rt = ts.row,
+ rb = ts.rowBody,
+ last = colCount - 1,
+ rh = this.getStyleRowHeight(),
+ vr = this.getVisibleRows(),
+ tstyle = 'width:' + this.getTotalWidth() + ';height:' + rh + 'px;',
+ // buffers
+ buf = [],
+ cb,
+ c,
+ p = {},
+ rp = { tstyle: tstyle },
+ r;
+ for (var j = 0, len = rs.length; j < len; j++) {
+ r = rs[j];
+ cb = [];
+ var rowIndex = j + startRow,
+ visible = rowIndex >= vr.first && rowIndex <= vr.last;
+ if (visible) {
+ for (var i = 0; i < colCount; i++) {
+ c = cs[i];
+ p.id = c.id;
+ p.css =
+ i === 0
+ ? 'x-grid3-cell-first '
+ : i == last
+ ? 'x-grid3-cell-last '
+ : '';
+ p.attr = p.cellAttr = '';
+ p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
+ p.style = c.style;
+ if (p.value === undefined || p.value === '') {
+ p.value = '&#160;';
+ }
+ if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
+ p.css += ' x-grid3-dirty-cell';
+ }
+ cb[cb.length] = ct.apply(p);
+ }
+ }
+ var alt = [];
+ if (stripe && (rowIndex + 1) % 2 === 0) {
+ alt[0] = 'x-grid3-row-alt';
+ }
+ if (r.dirty) {
+ alt[1] = ' x-grid3-dirty-row';
+ }
+ rp.cols = colCount;
+ if (this.getRowClass) {
+ alt[2] = this.getRowClass(r, rowIndex, rp, ds);
+ }
+ rp.alt = alt.join(' ');
+ rp.cells = cb.join('');
+ buf[buf.length] = !visible
+ ? ts.rowHolder.apply(rp)
+ : onlyBody
+ ? rb.apply(rp)
+ : rt.apply(rp);
+ }
+ return buf.join('');
+ },
+
+ isRowRendered: function(index) {
+ var row = this.getRow(index);
+ return row && row.childNodes.length > 0;
+ },
+
+ syncScroll: function() {
+ Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments);
+ this.update();
+ },
+
+ // a (optionally) buffered method to update contents of gridview
+ update: function() {
+ if (this.scrollDelay) {
+ if (!this.renderTask) {
+ this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this);
+ }
+ this.renderTask.delay(this.scrollDelay);
+ } else {
+ this.doUpdate();
+ }
+ },
+
+ onRemove: function(ds, record, index, isUpdate) {
+ Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments);
+ if (isUpdate !== true) {
+ this.update();
+ }
+ },
+
+ doUpdate: function() {
+ if (this.getVisibleRowCount() > 0) {
+ var g = this.grid,
+ cm = g.colModel,
+ ds = g.store,
+ cs = this.getColumnData(),
+ vr = this.getVisibleRows(),
+ row;
+ for (var i = vr.first; i <= vr.last; i++) {
+ // if row is NOT rendered and is visible, render it
+ if (!this.isRowRendered(i) && (row = this.getRow(i))) {
+ var html = this.doRender(
+ cs,
+ [ds.getAt(i)],
+ ds,
+ i,
+ cm.getColumnCount(),
+ g.stripeRows,
+ true
+ );
+ row.innerHTML = html;
+ }
+ }
+ this.clean();
+ }
+ },
+
+ // a buffered method to clean rows
+ clean: function() {
+ if (!this.cleanTask) {
+ this.cleanTask = new Ext.util.DelayedTask(this.doClean, this);
+ }
+ this.cleanTask.delay(this.cleanDelay);
+ },
+
+ doClean: function() {
+ if (this.getVisibleRowCount() > 0) {
+ var vr = this.getVisibleRows();
+ vr.first -= this.cacheSize;
+ vr.last += this.cacheSize;
+
+ var i = 0,
+ rows = this.getRows();
+ // if first is less than 0, all rows have been rendered
+ // so lets clean the end...
+ if (vr.first <= 0) {
+ i = vr.last + 1;
+ }
+ for (var len = this.ds.getCount(); i < len; i++) {
+ // if current row is outside of first and last and
+ // has content, update the innerHTML to nothing
+ if ((i < vr.first || i > vr.last) && rows[i].innerHTML) {
+ rows[i].innerHTML = '';
+ }
+ }
+ }
+ },
+
+ removeTask: function(name) {
+ var task = this[name];
+ if (task && task.cancel) {
+ task.cancel();
+ this[name] = null;
+ }
+ },
+
+ destroy: function() {
+ this.removeTask('cleanTask');
+ this.removeTask('renderTask');
+ Ext.ux.grid.BufferView.superclass.destroy.call(this);
+ },
+
+ layout: function() {
+ Ext.ux.grid.BufferView.superclass.layout.call(this);
+ this.update();
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js b/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js
new file mode 100644
index 0000000..14ac55a
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/layout/FormLayoutFix.js
@@ -0,0 +1,39 @@
+/**
+ * Ext.ux.layout.FormLayoutFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+// Taken from http://extjs.com/forum/showthread.php?t=75273
+// remove spaces for hidden elements and make show(), hide(), enable() and disable() act on
+// the label. don't use hideLabel with this.
+Ext.override(Ext.layout.FormLayout, {
+ renderItem: function(c, position, target) {
+ if (
+ c &&
+ !c.rendered &&
+ (c.isFormField || c.fieldLabel) &&
+ c.inputType != 'hidden'
+ ) {
+ var args = this.getTemplateArgs(c);
+ if (typeof position == 'number') {
+ position = target.dom.childNodes[position] || null;
+ }
+ if (position) {
+ c.formItem = this.fieldTpl.insertBefore(position, args, true);
+ } else {
+ c.formItem = this.fieldTpl.append(target, args, true);
+ }
+ c.actionMode = 'formItem';
+ c.render('x-form-el-' + c.id);
+ c.container = c.formItem;
+ c.actionMode = 'container';
+ } else {
+ Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
+ }
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js b/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js
new file mode 100644
index 0000000..979bd2c
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/MultiSelectionModelFix.js
@@ -0,0 +1,68 @@
+/**
+ * Ext.ux.tree.MultiSelectionModelFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+/**
+ * This enhances the MSM to allow for shift selecting in tree grids etc.
+ * @author Damien Churchill <damoxc@gmail.com>
+ */
+Ext.override(Ext.tree.MultiSelectionModel, {
+ onNodeClick: function(node, e) {
+ if (e.ctrlKey && this.isSelected(node)) {
+ this.unselect(node);
+ } else if (e.shiftKey && !this.isSelected(node)) {
+ var parentNode = node.parentNode;
+ // We can only shift select files in the same node
+ if (this.lastSelNode.parentNode.id != parentNode.id) return;
+
+ // Get the node indexes
+ var fi = parentNode.indexOf(node),
+ li = parentNode.indexOf(this.lastSelNode);
+
+ // Select the last clicked node and wipe old selections
+ this.select(this.lastSelNode, e, false, true);
+
+ // Swap the values if required
+ if (fi > li) {
+ (fi = fi + li), (li = fi - li), (fi = fi - li);
+ }
+
+ // Select all the nodes
+ parentNode.eachChild(function(n) {
+ var i = parentNode.indexOf(n);
+ if (fi < i && i < li) {
+ this.select(n, e, true, true);
+ }
+ }, this);
+
+ // Select the clicked node
+ this.select(node, e, true);
+ } else {
+ this.select(node, e, e.ctrlKey);
+ }
+ },
+
+ select: function(node, e, keepExisting, suppressEvent) {
+ if (keepExisting !== true) {
+ this.clearSelections(true);
+ }
+ if (this.isSelected(node)) {
+ this.lastSelNode = node;
+ return node;
+ }
+ this.selNodes.push(node);
+ this.selMap[node.id] = node;
+ this.lastSelNode = node;
+ node.ui.onSelectedChange(true);
+ if (suppressEvent !== true) {
+ this.fireEvent('selectionchange', this, this.selNodes);
+ }
+ return node;
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js
new file mode 100644
index 0000000..d3d5fc3
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGrid.js
@@ -0,0 +1,468 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.tree');
+
+/**
+ * @class Ext.ux.tree.TreeGrid
+ * @extends Ext.tree.TreePanel
+ *
+ * @xtype treegrid
+ */
+Ext.ux.tree.TreeGrid = Ext.extend(Ext.tree.TreePanel, {
+ rootVisible: false,
+ useArrows: true,
+ lines: false,
+ borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
+ cls: 'x-treegrid',
+
+ columnResize: true,
+ enableSort: true,
+ reserveScrollOffset: true,
+ enableHdMenu: true,
+
+ columnsText: 'Columns',
+
+ initComponent: function() {
+ if (!this.root) {
+ this.root = new Ext.tree.AsyncTreeNode({ text: 'Root' });
+ }
+
+ // initialize the loader
+ var l = this.loader;
+ if (!l) {
+ l = new Ext.ux.tree.TreeGridLoader({
+ dataUrl: this.dataUrl,
+ requestMethod: this.requestMethod,
+ store: this.store,
+ });
+ } else if (Ext.isObject(l) && !l.load) {
+ l = new Ext.ux.tree.TreeGridLoader(l);
+ }
+ this.loader = l;
+
+ Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);
+
+ this.initColumns();
+
+ if (this.enableSort) {
+ this.treeGridSorter = new Ext.ux.tree.TreeGridSorter(
+ this,
+ this.enableSort
+ );
+ }
+
+ if (this.columnResize) {
+ this.colResizer = new Ext.tree.ColumnResizer(this.columnResize);
+ this.colResizer.init(this);
+ }
+
+ var c = this.columns;
+ if (!this.internalTpl) {
+ this.internalTpl = new Ext.XTemplate(
+ '<div class="x-grid3-header">',
+ '<div class="x-treegrid-header-inner">',
+ '<div class="x-grid3-header-offset">',
+ '<table style="table-layout: fixed;" cellspacing="0" cellpadding="0" border="0"><colgroup><tpl for="columns"><col /></tpl></colgroup>',
+ '<thead><tr class="x-grid3-hd-row">',
+ '<tpl for="columns">',
+ '<td class="x-grid3-hd x-grid3-cell x-treegrid-hd" style="text-align: {align};" id="',
+ this.id,
+ '-xlhd-{#}">',
+ '<div class="x-grid3-hd-inner x-treegrid-hd-inner" unselectable="on">',
+ this.enableHdMenu
+ ? '<a class="x-grid3-hd-btn" href="#"></a>'
+ : '',
+ '{header}<img class="x-grid3-sort-icon" src="',
+ Ext.BLANK_IMAGE_URL,
+ '" />',
+ '</div>',
+ '</td></tpl>',
+ '</tr></thead>',
+ '</table>',
+ '</div></div>',
+ '</div>',
+ '<div class="x-treegrid-root-node">',
+ '<table class="x-treegrid-root-table" cellpadding="0" cellspacing="0" style="table-layout: fixed;"></table>',
+ '</div>'
+ );
+ }
+
+ if (!this.colgroupTpl) {
+ this.colgroupTpl = new Ext.XTemplate(
+ '<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>'
+ );
+ }
+ },
+
+ initColumns: function() {
+ var cs = this.columns,
+ len = cs.length,
+ columns = [],
+ i,
+ c;
+
+ for (i = 0; i < len; i++) {
+ c = cs[i];
+ if (!c.isColumn) {
+ c.xtype = c.xtype
+ ? /^tg/.test(c.xtype)
+ ? c.xtype
+ : 'tg' + c.xtype
+ : 'tgcolumn';
+ c = Ext.create(c);
+ }
+ c.init(this);
+ columns.push(c);
+
+ if (this.enableSort !== false && c.sortable !== false) {
+ c.sortable = true;
+ this.enableSort = true;
+ }
+ }
+
+ this.columns = columns;
+ },
+
+ onRender: function() {
+ Ext.tree.TreePanel.superclass.onRender.apply(this, arguments);
+
+ this.el.addClass('x-treegrid');
+
+ this.outerCt = this.body.createChild({
+ cls:
+ 'x-tree-root-ct x-treegrid-ct ' +
+ (this.useArrows
+ ? 'x-tree-arrows'
+ : this.lines
+ ? 'x-tree-lines'
+ : 'x-tree-no-lines'),
+ });
+
+ this.internalTpl.overwrite(this.outerCt, { columns: this.columns });
+
+ this.mainHd = Ext.get(this.outerCt.dom.firstChild);
+ this.innerHd = Ext.get(this.mainHd.dom.firstChild);
+ this.innerBody = Ext.get(this.outerCt.dom.lastChild);
+ this.innerCt = Ext.get(this.innerBody.dom.firstChild);
+
+ this.colgroupTpl.insertFirst(this.innerCt, { columns: this.columns });
+
+ if (this.hideHeaders) {
+ this.el.child('.x-grid3-header').setDisplayed('none');
+ } else if (this.enableHdMenu !== false) {
+ this.hmenu = new Ext.menu.Menu({ id: this.id + '-hctx' });
+ if (this.enableColumnHide !== false) {
+ this.colMenu = new Ext.menu.Menu({
+ id: this.id + '-hcols-menu',
+ });
+ this.colMenu.on({
+ scope: this,
+ beforeshow: this.beforeColMenuShow,
+ itemclick: this.handleHdMenuClick,
+ });
+ this.hmenu.add({
+ itemId: 'columns',
+ hideOnClick: false,
+ text: this.columnsText,
+ menu: this.colMenu,
+ iconCls: 'x-cols-icon',
+ });
+ }
+ this.hmenu.on('itemclick', this.handleHdMenuClick, this);
+ }
+ },
+
+ setRootNode: function(node) {
+ node.attributes.uiProvider = Ext.ux.tree.TreeGridRootNodeUI;
+ node = Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this, node);
+ if (this.innerCt) {
+ this.colgroupTpl.insertFirst(this.innerCt, {
+ columns: this.columns,
+ });
+ }
+ return node;
+ },
+
+ clearInnerCt: function() {
+ if (Ext.isIE) {
+ var dom = this.innerCt.dom;
+ while (dom.firstChild) {
+ dom.removeChild(dom.firstChild);
+ }
+ } else {
+ Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this);
+ }
+ },
+
+ initEvents: function() {
+ Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this, arguments);
+
+ this.mon(this.innerBody, 'scroll', this.syncScroll, this);
+ this.mon(this.innerHd, 'click', this.handleHdDown, this);
+ this.mon(this.mainHd, {
+ scope: this,
+ mouseover: this.handleHdOver,
+ mouseout: this.handleHdOut,
+ });
+ },
+
+ onResize: function(w, h) {
+ Ext.ux.tree.TreeGrid.superclass.onResize.apply(this, arguments);
+
+ var bd = this.innerBody.dom;
+ var hd = this.innerHd.dom;
+
+ if (!bd) {
+ return;
+ }
+
+ if (Ext.isNumber(h)) {
+ bd.style.height =
+ this.body.getHeight(true) - hd.offsetHeight + 'px';
+ }
+
+ if (Ext.isNumber(w)) {
+ var sw = Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
+ if (
+ this.reserveScrollOffset ||
+ bd.offsetWidth - bd.clientWidth > 10
+ ) {
+ this.setScrollOffset(sw);
+ } else {
+ var me = this;
+ setTimeout(function() {
+ me.setScrollOffset(
+ bd.offsetWidth - bd.clientWidth > 10 ? sw : 0
+ );
+ }, 10);
+ }
+ }
+ },
+
+ updateColumnWidths: function() {
+ var cols = this.columns,
+ colCount = cols.length,
+ groups = this.outerCt.query('colgroup'),
+ groupCount = groups.length,
+ c,
+ g,
+ i,
+ j;
+
+ for (i = 0; i < colCount; i++) {
+ c = cols[i];
+ for (j = 0; j < groupCount; j++) {
+ g = groups[j];
+ g.childNodes[i].style.width = (c.hidden ? 0 : c.width) + 'px';
+ }
+ }
+
+ for (
+ i = 0, groups = this.innerHd.query('td'), len = groups.length;
+ i < len;
+ i++
+ ) {
+ c = Ext.fly(groups[i]);
+ if (cols[i] && cols[i].hidden) {
+ c.addClass('x-treegrid-hd-hidden');
+ } else {
+ c.removeClass('x-treegrid-hd-hidden');
+ }
+ }
+
+ var tcw = this.getTotalColumnWidth();
+ Ext.fly(this.innerHd.dom.firstChild).setWidth(
+ tcw + (this.scrollOffset || 0)
+ );
+ this.outerCt.select('table').setWidth(tcw);
+ this.syncHeaderScroll();
+ },
+
+ getVisibleColumns: function() {
+ var columns = [],
+ cs = this.columns,
+ len = cs.length,
+ i;
+
+ for (i = 0; i < len; i++) {
+ if (!cs[i].hidden) {
+ columns.push(cs[i]);
+ }
+ }
+ return columns;
+ },
+
+ getTotalColumnWidth: function() {
+ var total = 0;
+ for (
+ var i = 0, cs = this.getVisibleColumns(), len = cs.length;
+ i < len;
+ i++
+ ) {
+ total += cs[i].width;
+ }
+ return total;
+ },
+
+ setScrollOffset: function(scrollOffset) {
+ this.scrollOffset = scrollOffset;
+ this.updateColumnWidths();
+ },
+
+ // private
+ handleHdDown: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+
+ if (hd && Ext.fly(t).hasClass('x-grid3-hd-btn')) {
+ var ms = this.hmenu.items,
+ cs = this.columns,
+ index = this.findHeaderIndex(hd),
+ c = cs[index],
+ sort = c.sortable;
+
+ e.stopEvent();
+ Ext.fly(hd).addClass('x-grid3-hd-menu-open');
+ this.hdCtxIndex = index;
+
+ this.fireEvent('headerbuttonclick', ms, c, hd, index);
+
+ this.hmenu.on(
+ 'hide',
+ function() {
+ Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
+ },
+ this,
+ { single: true }
+ );
+
+ this.hmenu.show(t, 'tl-bl?');
+ } else if (hd) {
+ var index = this.findHeaderIndex(hd);
+ this.fireEvent('headerclick', this.columns[index], hd, index);
+ }
+ },
+
+ // private
+ handleHdOver: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+ if (hd && !this.headersDisabled) {
+ index = this.findHeaderIndex(hd);
+ this.activeHdRef = t;
+ this.activeHdIndex = index;
+ var el = Ext.get(hd);
+ this.activeHdRegion = el.getRegion();
+ el.addClass('x-grid3-hd-over');
+ this.activeHdBtn = el.child('.x-grid3-hd-btn');
+ if (this.activeHdBtn) {
+ this.activeHdBtn.dom.style.height =
+ hd.firstChild.offsetHeight - 1 + 'px';
+ }
+ }
+ },
+
+ // private
+ handleHdOut: function(e, t) {
+ var hd = e.getTarget('.x-treegrid-hd');
+ if (hd && (!Ext.isIE || !e.within(hd, true))) {
+ this.activeHdRef = null;
+ Ext.fly(hd).removeClass('x-grid3-hd-over');
+ hd.style.cursor = '';
+ }
+ },
+
+ findHeaderIndex: function(hd) {
+ hd = hd.dom || hd;
+ var cs = hd.parentNode.childNodes;
+ for (var i = 0, c; (c = cs[i]); i++) {
+ if (c == hd) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ // private
+ beforeColMenuShow: function() {
+ var cols = this.columns,
+ colCount = cols.length,
+ i,
+ c;
+ this.colMenu.removeAll();
+ for (i = 1; i < colCount; i++) {
+ c = cols[i];
+ if (c.hideable !== false) {
+ this.colMenu.add(
+ new Ext.menu.CheckItem({
+ itemId: 'col-' + i,
+ text: c.header,
+ checked: !c.hidden,
+ hideOnClick: false,
+ disabled: c.hideable === false,
+ })
+ );
+ }
+ }
+ },
+
+ // private
+ handleHdMenuClick: function(item) {
+ var index = this.hdCtxIndex,
+ id = item.getItemId();
+
+ if (
+ this.fireEvent(
+ 'headermenuclick',
+ this.columns[index],
+ id,
+ index
+ ) !== false
+ ) {
+ index = id.substr(4);
+ if (index > 0 && this.columns[index]) {
+ this.setColumnVisible(index, !item.checked);
+ }
+ }
+
+ return true;
+ },
+
+ setColumnVisible: function(index, visible) {
+ this.columns[index].hidden = !visible;
+ this.updateColumnWidths();
+ },
+
+ /**
+ * Scrolls the grid to the top
+ */
+ scrollToTop: function() {
+ this.innerBody.dom.scrollTop = 0;
+ this.innerBody.dom.scrollLeft = 0;
+ },
+
+ // private
+ syncScroll: function() {
+ this.syncHeaderScroll();
+ var mb = this.innerBody.dom;
+ this.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
+ },
+
+ // private
+ syncHeaderScroll: function() {
+ var mb = this.innerBody.dom;
+ this.innerHd.dom.scrollLeft = mb.scrollLeft;
+ this.innerHd.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
+ },
+
+ registerNode: function(n) {
+ Ext.ux.tree.TreeGrid.superclass.registerNode.call(this, n);
+ if (!n.uiProvider && !n.isRoot && !n.ui.isTreeGridNodeUI) {
+ n.ui = new Ext.ux.tree.TreeGridNodeUI(n);
+ }
+ },
+});
+
+Ext.reg('treegrid', Ext.ux.tree.TreeGrid);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js
new file mode 100644
index 0000000..870172e
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumnResizer.js
@@ -0,0 +1,123 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.tree.ColumnResizer
+ * @extends Ext.util.Observable
+ */
+Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, {
+ /**
+ * @cfg {Number} minWidth The minimum width the column can be dragged to.
+ * Defaults to <tt>14</tt>.
+ */
+ minWidth: 14,
+
+ constructor: function(config) {
+ Ext.apply(this, config);
+ Ext.tree.ColumnResizer.superclass.constructor.call(this);
+ },
+
+ init: function(tree) {
+ this.tree = tree;
+ tree.on('render', this.initEvents, this);
+ },
+
+ initEvents: function(tree) {
+ tree.mon(tree.innerHd, 'mousemove', this.handleHdMove, this);
+ this.tracker = new Ext.dd.DragTracker({
+ onBeforeStart: this.onBeforeStart.createDelegate(this),
+ onStart: this.onStart.createDelegate(this),
+ onDrag: this.onDrag.createDelegate(this),
+ onEnd: this.onEnd.createDelegate(this),
+ tolerance: 3,
+ autoStart: 300,
+ });
+ this.tracker.initEl(tree.innerHd);
+ tree.on('beforedestroy', this.tracker.destroy, this.tracker);
+ },
+
+ handleHdMove: function(e, t) {
+ var hw = 5,
+ x = e.getPageX(),
+ hd = e.getTarget('.x-treegrid-hd', 3, true);
+
+ if (hd) {
+ var r = hd.getRegion(),
+ ss = hd.dom.style,
+ pn = hd.dom.parentNode;
+
+ if (x - r.left <= hw && hd.dom !== pn.firstChild) {
+ var ps = hd.dom.previousSibling;
+ while (ps && Ext.fly(ps).hasClass('x-treegrid-hd-hidden')) {
+ ps = ps.previousSibling;
+ }
+ if (ps) {
+ this.activeHd = Ext.get(ps);
+ ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
+ }
+ } else if (r.right - x <= hw) {
+ var ns = hd.dom;
+ while (ns && Ext.fly(ns).hasClass('x-treegrid-hd-hidden')) {
+ ns = ns.previousSibling;
+ }
+ if (ns) {
+ this.activeHd = Ext.get(ns);
+ ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
+ }
+ } else {
+ delete this.activeHd;
+ ss.cursor = '';
+ }
+ }
+ },
+
+ onBeforeStart: function(e) {
+ this.dragHd = this.activeHd;
+ return !!this.dragHd;
+ },
+
+ onStart: function(e) {
+ this.dragHeadersDisabled = this.tree.headersDisabled;
+ this.tree.headersDisabled = true;
+ this.proxy = this.tree.body.createChild({ cls: 'x-treegrid-resizer' });
+ this.proxy.setHeight(this.tree.body.getHeight());
+
+ var x = this.tracker.getXY()[0];
+
+ this.hdX = this.dragHd.getX();
+ this.hdIndex = this.tree.findHeaderIndex(this.dragHd);
+
+ this.proxy.setX(this.hdX);
+ this.proxy.setWidth(x - this.hdX);
+
+ this.maxWidth =
+ this.tree.outerCt.getWidth() -
+ this.tree.innerBody.translatePoints(this.hdX).left;
+ },
+
+ onDrag: function(e) {
+ var cursorX = this.tracker.getXY()[0];
+ this.proxy.setWidth(
+ (cursorX - this.hdX).constrain(this.minWidth, this.maxWidth)
+ );
+ },
+
+ onEnd: function(e) {
+ var nw = this.proxy.getWidth(),
+ tree = this.tree,
+ disabled = this.dragHeadersDisabled;
+
+ this.proxy.remove();
+ delete this.dragHd;
+
+ tree.columns[this.hdIndex].width = nw;
+ tree.updateColumnWidths();
+
+ setTimeout(function() {
+ tree.headersDisabled = disabled;
+ }, 100);
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js
new file mode 100644
index 0000000..312bf21
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridColumns.js
@@ -0,0 +1,40 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+(function() {
+ Ext.override(Ext.list.Column, {
+ init: function() {
+ var types = Ext.data.Types,
+ st = this.sortType;
+
+ if (this.type) {
+ if (Ext.isString(this.type)) {
+ this.type =
+ Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
+ }
+ } else {
+ this.type = types.AUTO;
+ }
+
+ // named sortTypes are supported, here we look them up
+ if (Ext.isString(st)) {
+ this.sortType = Ext.data.SortTypes[st];
+ } else if (Ext.isEmpty(st)) {
+ this.sortType = this.type.sortType;
+ }
+ },
+ });
+
+ Ext.tree.Column = Ext.extend(Ext.list.Column, {});
+ Ext.tree.NumberColumn = Ext.extend(Ext.list.NumberColumn, {});
+ Ext.tree.DateColumn = Ext.extend(Ext.list.DateColumn, {});
+ Ext.tree.BooleanColumn = Ext.extend(Ext.list.BooleanColumn, {});
+
+ Ext.reg('tgcolumn', Ext.tree.Column);
+ Ext.reg('tgnumbercolumn', Ext.tree.NumberColumn);
+ Ext.reg('tgdatecolumn', Ext.tree.DateColumn);
+ Ext.reg('tgbooleancolumn', Ext.tree.BooleanColumn);
+})();
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js
new file mode 100644
index 0000000..eb5156a
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridLoader.js
@@ -0,0 +1,18 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.tree.TreeGridLoader
+ * @extends Ext.tree.TreeLoader
+ */
+Ext.ux.tree.TreeGridLoader = Ext.extend(Ext.tree.TreeLoader, {
+ createNode: function(attr) {
+ if (!attr.uiProvider) {
+ attr.uiProvider = Ext.ux.tree.TreeGridNodeUI;
+ }
+ return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js
new file mode 100644
index 0000000..e58a801
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUI.js
@@ -0,0 +1,149 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+/**
+ * @class Ext.ux.tree.TreeGridNodeUI
+ * @extends Ext.tree.TreeNodeUI
+ */
+Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+ isTreeGridNodeUI: true,
+
+ renderElements: function(n, a, targetNode, bulkRender) {
+ var t = n.getOwnerTree(),
+ cols = t.columns,
+ c = cols[0],
+ i,
+ buf,
+ len;
+
+ this.indentMarkup = n.parentNode
+ ? n.parentNode.ui.getChildIndent()
+ : '';
+
+ buf = [
+ '<tbody class="x-tree-node">',
+ '<tr ext:tree-node-id="',
+ n.id,
+ '" class="x-tree-node-el x-tree-node-leaf ',
+ a.cls,
+ '">',
+ '<td class="x-treegrid-col">',
+ '<span class="x-tree-node-indent">',
+ this.indentMarkup,
+ '</span>',
+ '<img src="',
+ this.emptyIcon,
+ '" class="x-tree-ec-icon x-tree-elbow" />',
+ '<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" class="x-tree-node-anchor" href="',
+ a.href ? a.href : '#',
+ '" tabIndex="1" ',
+ a.hrefTarget ? ' target="' + a.hrefTarget + '"' : '',
+ '>',
+ '<span unselectable="on">',
+ c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text,
+ '</span></a>',
+ '</td>',
+ ];
+
+ for (i = 1, len = cols.length; i < len; i++) {
+ c = cols[i];
+ buf.push(
+ '<td class="x-treegrid-col ',
+ c.cls ? c.cls : '',
+ '">',
+ '<div unselectable="on" class="x-treegrid-text"',
+ c.align ? ' style="text-align: ' + c.align + ';"' : '',
+ '>',
+ c.tpl ? c.tpl.apply(a) : a[c.dataIndex],
+ '</div>',
+ '</td>'
+ );
+ }
+
+ buf.push(
+ '</tr><tr class="x-tree-node-ct"><td colspan="',
+ cols.length,
+ '">',
+ '<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',
+ t.innerCt.getWidth(),
+ 'px;"><colgroup>'
+ );
+ for (i = 0, len = cols.length; i < len; i++) {
+ buf.push(
+ '<col style="width: ',
+ cols[i].hidden ? 0 : cols[i].width,
+ 'px;" />'
+ );
+ }
+ buf.push('</colgroup></table></td></tr></tbody>');
+
+ if (bulkRender !== 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',
+ targetNode,
+ buf.join('')
+ );
+ }
+
+ this.elNode = this.wrap.childNodes[0];
+ this.ctNode = this.wrap.childNodes[1].firstChild.firstChild;
+ var cs = this.elNode.firstChild.childNodes;
+ this.indentNode = cs[0];
+ this.ecNode = cs[1];
+ this.iconNode = cs[2];
+ this.anchor = cs[3];
+ this.textNode = cs[3].firstChild;
+ },
+
+ // private
+ animExpand: function(cb) {
+ this.ctNode.style.display = '';
+ Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb);
+ },
+});
+
+Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+ isTreeGridNodeUI: true,
+
+ // private
+ render: function() {
+ if (!this.rendered) {
+ this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom;
+ this.node.expanded = true;
+ }
+
+ if (Ext.isWebKit) {
+ // weird table-layout: fixed issue in webkit
+ var ct = this.ctNode;
+ ct.style.tableLayout = null;
+ (function() {
+ ct.style.tableLayout = 'fixed';
+ }.defer(1));
+ }
+ },
+
+ destroy: function() {
+ if (this.elNode) {
+ Ext.dd.Registry.unregister(this.elNode.id);
+ }
+ delete this.node;
+ },
+
+ collapse: Ext.emptyFn,
+ expand: Ext.emptyFn,
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js
new file mode 100644
index 0000000..4c21bc3
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridNodeUIFix.js
@@ -0,0 +1,33 @@
+/**
+ * Ext.ux.tree.TreeGridNodeUIFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+ * the additional special exception to link portions of this program with the OpenSSL library.
+ * See LICENSE for more details.
+ */
+
+Ext.override(Ext.ux.tree.TreeGridNodeUI, {
+ updateColumns: function() {
+ if (!this.rendered) return;
+
+ var a = this.node.attributes,
+ t = this.node.getOwnerTree(),
+ cols = t.columns,
+ c = cols[0];
+
+ // Update the first column
+ this.anchor.firstChild.innerHTML = c.tpl
+ ? c.tpl.apply(a)
+ : a[c.dataIndex] || c.text;
+
+ // Update the remaining columns
+ for (i = 1, len = cols.length; i < len; i++) {
+ c = cols[i];
+ this.elNode.childNodes[i].firstChild.innerHTML = c.tpl
+ ? c.tpl.apply(a)
+ : a[c.dataIndex] || c.text;
+ }
+ },
+});
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js
new file mode 100644
index 0000000..20bde8a
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridRenderColumn.js
@@ -0,0 +1,9 @@
+Ext.tree.RenderColumn = Ext.extend(Ext.tree.Column, {
+ constructor: function(c) {
+ c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
+ c.tpl.format = c.renderer;
+ c.tpl.col = this;
+ Ext.tree.RenderColumn.superclass.constructor.call(this, c);
+ },
+});
+Ext.reg('tgrendercolumn', Ext.tree.RenderColumn);
diff --git a/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js
new file mode 100644
index 0000000..376f414
--- /dev/null
+++ b/deluge/ui/web/js/extjs/ext-extensions/tree/TreeGridSorter.js
@@ -0,0 +1,158 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns('Ext.ux.tree');
+
+/**
+ * @class Ext.ux.tree.TreeGridSorter
+ * @extends Ext.tree.TreeSorter
+ * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}. The TreeGridSorter automatically monitors events on the
+ * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
+ * Example usage:<br />
+ * <pre><code>
+ new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
+ folderSort: true,
+ dir: "desc",
+ sortType: function(node) {
+ // sort by a custom, typed attribute:
+ return parseInt(node.id, 10);
+ }
+ });
+ </code></pre>
+ * @constructor
+ * @param {TreeGrid} tree
+ * @param {Object} config
+ */
+Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
+ /**
+ * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>['sort-asc', 'sort-desc']</tt>)
+ */
+ sortClasses: ['sort-asc', 'sort-desc'],
+ /**
+ * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to <tt>'Sort Ascending'</tt>)
+ */
+ sortAscText: 'Sort Ascending',
+ /**
+ * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to <tt>'Sort Descending'</tt>)
+ */
+ sortDescText: 'Sort Descending',
+
+ constructor: function(tree, config) {
+ if (!Ext.isObject(config)) {
+ config = {
+ property: tree.columns[0].dataIndex || 'text',
+ folderSort: true,
+ };
+ }
+
+ Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(
+ this,
+ arguments
+ );
+
+ this.tree = tree;
+ tree.on('headerclick', this.onHeaderClick, this);
+ tree.ddAppendOnly = true;
+
+ var me = this;
+ this.defaultSortFn = function(n1, n2) {
+ var desc = me.dir && me.dir.toLowerCase() == 'desc',
+ prop = me.property || 'text',
+ sortType = me.sortType,
+ caseSensitive = me.caseSensitive === true,
+ leafAttr = me.leafAttr || 'leaf',
+ attr1 = n1.attributes,
+ attr2 = n2.attributes;
+
+ if (me.folderSort) {
+ if (attr1[leafAttr] && !attr2[leafAttr]) {
+ return 1;
+ }
+ if (!attr1[leafAttr] && attr2[leafAttr]) {
+ return -1;
+ }
+ }
+ var prop1 = attr1[prop],
+ prop2 = attr2[prop],
+ v1 = sortType
+ ? sortType(prop1)
+ : caseSensitive
+ ? prop1
+ : prop1.toUpperCase();
+ v2 = sortType
+ ? sortType(prop2)
+ : caseSensitive
+ ? prop2
+ : prop2.toUpperCase();
+
+ if (v1 < v2) {
+ return desc ? +1 : -1;
+ } else if (v1 > v2) {
+ return desc ? -1 : +1;
+ } else {
+ return 0;
+ }
+ };
+
+ tree.on('afterrender', this.onAfterTreeRender, this, { single: true });
+ tree.on('headermenuclick', this.onHeaderMenuClick, this);
+ },
+
+ onAfterTreeRender: function() {
+ if (this.tree.hmenu) {
+ this.tree.hmenu.insert(
+ 0,
+ {
+ itemId: 'asc',
+ text: this.sortAscText,
+ cls: 'xg-hmenu-sort-asc',
+ },
+ {
+ itemId: 'desc',
+ text: this.sortDescText,
+ cls: 'xg-hmenu-sort-desc',
+ }
+ );
+ }
+ this.updateSortIcon(0, 'asc');
+ },
+
+ onHeaderMenuClick: function(c, id, index) {
+ if (id === 'asc' || id === 'desc') {
+ this.onHeaderClick(c, null, index);
+ return false;
+ }
+ },
+
+ onHeaderClick: function(c, el, i) {
+ if (c && !this.tree.headersDisabled) {
+ var me = this;
+
+ me.property = c.dataIndex;
+ me.dir = c.dir = c.dir === 'desc' ? 'asc' : 'desc';
+ me.sortType = c.sortType;
+ me.caseSensitive === Ext.isBoolean(c.caseSensitive)
+ ? c.caseSensitive
+ : this.caseSensitive;
+ me.sortFn = c.sortFn || this.defaultSortFn;
+
+ this.tree.root.cascade(function(n) {
+ if (!n.isLeaf()) {
+ me.updateSort(me.tree, n);
+ }
+ });
+
+ this.updateSortIcon(i, c.dir);
+ }
+ },
+
+ // private
+ updateSortIcon: function(col, dir) {
+ var sc = this.sortClasses,
+ hds = this.tree.innerHd.select('td').removeClass(sc);
+ hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]);
+ },
+});
diff --git a/deluge/ui/web/js/gettext.js b/deluge/ui/web/js/gettext.js
new file mode 100644
index 0000000..9cc1c4f
--- /dev/null
+++ b/deluge/ui/web/js/gettext.js
@@ -0,0 +1,322 @@
+GetText={maps:{},add:function(string,translation){this.maps[string]=translation},get:function(string){if (this.maps[string]){string=this.maps[string]} return string}};function _(string){return GetText.get(string)}GetText.add('10 KiB/s','${escape(_("10 KiB/s"))}')
+GetText.add('30 KiB/s','${escape(_("30 KiB/s"))}')
+GetText.add('300 KiB/s','${escape(_("300 KiB/s"))}')
+GetText.add('5 KiB/s','${escape(_("5 KiB/s"))}')
+GetText.add('80 KiB/s','${escape(_("80 KiB/s"))}')
+GetText.add('<b>IP</b> {0}','${escape(_("<b>IP</b> {0}"))}')
+GetText.add('About Deluge','${escape(_("About Deluge"))}')
+GetText.add('Active','${escape(_("Active"))}')
+GetText.add('Active Torrents','${escape(_("Active Torrents"))}')
+GetText.add('Add','${escape(_("Add"))}')
+GetText.add('Add Connection','${escape(_("Add Connection"))}')
+GetText.add('Add In Paused State','${escape(_("Add In Paused State"))}')
+GetText.add('Add Torrents','${escape(_("Add Torrents"))}')
+GetText.add('Add Tracker','${escape(_("Add Tracker"))}')
+GetText.add('Add from Url','${escape(_("Add from Url"))}')
+GetText.add('Add torrents in Paused state','${escape(_("Add torrents in Paused state"))}')
+GetText.add('Added','${escape(_("Added"))}')
+GetText.add('Address','${escape(_("Address"))}')
+GetText.add('All','${escape(_("All"))}')
+GetText.add('Allocating','${escape(_("Allocating"))}')
+GetText.add('Allow Remote Connections','${escape(_("Allow Remote Connections"))}')
+GetText.add('Allow the use of multiple filters at once','${escape(_("Allow the use of multiple filters at once"))}')
+GetText.add('Announce OK','${escape(_("Announce OK"))}')
+GetText.add('Announce Sent','${escape(_("Announce Sent"))}')
+GetText.add('Apply','${escape(_("Apply"))}')
+GetText.add('Author Email:','${escape(_("Author Email:"))}')
+GetText.add('Author:','${escape(_("Author:"))}')
+GetText.add('Auto Managed','${escape(_("Auto Managed"))}')
+GetText.add('Avail','${escape(_("Avail"))}')
+GetText.add('Back','${escape(_("Back"))}')
+GetText.add('Bandwidth','${escape(_("Bandwidth"))}')
+GetText.add('Be alerted about new releases','${escape(_("Be alerted about new releases"))}')
+GetText.add('Bottom','${escape(_("Bottom"))}')
+GetText.add('Browse','${escape(_("Browse"))}')
+GetText.add('Browse...','${escape(_("Browse..."))}')
+GetText.add('Cache','${escape(_("Cache"))}')
+GetText.add('Cache Expiry (seconds):','${escape(_("Cache Expiry (seconds):"))}')
+GetText.add('Cache Size (16 KiB Blocks):','${escape(_("Cache Size (16 KiB Blocks):"))}')
+GetText.add('Cancel','${escape(_("Cancel"))}')
+GetText.add('Certificate:','${escape(_("Certificate:"))}')
+GetText.add('Change Default Password','${escape(_("Change Default Password"))}')
+GetText.add('Change Successful','${escape(_("Change Successful"))}')
+GetText.add('Checking','${escape(_("Checking"))}')
+GetText.add('Client','${escape(_("Client"))}')
+GetText.add('Client:','${escape(_("Client:"))}')
+GetText.add('Close','${escape(_("Close"))}')
+GetText.add('Comment:','${escape(_("Comment:"))}')
+GetText.add('Complete Seen','${escape(_("Complete Seen"))}')
+GetText.add('Completed','${escape(_("Completed"))}')
+GetText.add('Confirm:','${escape(_("Confirm:"))}')
+GetText.add('Connect','${escape(_("Connect"))}')
+GetText.add('Connected','${escape(_("Connected"))}')
+GetText.add('Connection Limit','${escape(_("Connection Limit"))}')
+GetText.add('Connection Manager','${escape(_("Connection Manager"))}')
+GetText.add('Connection restored','${escape(_("Connection restored"))}')
+GetText.add('Connections','${escape(_("Connections"))}')
+GetText.add('Cookies','${escape(_("Cookies"))}')
+GetText.add('Copy of .torrent files to:','${escape(_("Copy of .torrent files to:"))}')
+GetText.add('Copyright 2007-2018 Deluge Team','${escape(_("Copyright 2007-2018 Deluge Team"))}')
+GetText.add('Create','${escape(_("Create"))}')
+GetText.add('Created By:','${escape(_("Created By:"))}')
+GetText.add('D/L Speed Limit','${escape(_("D/L Speed Limit"))}')
+GetText.add('DHT','${escape(_("DHT"))}')
+GetText.add('DHT Nodes','${escape(_("DHT Nodes"))}')
+GetText.add('Daemon','${escape(_("Daemon"))}')
+GetText.add('Daemon port:','${escape(_("Daemon port:"))}')
+GetText.add('Deluge','${escape(_("Deluge"))}')
+GetText.add('Details','${escape(_("Details"))}')
+GetText.add('Details:','${escape(_("Details:"))}')
+GetText.add('Disabled','${escape(_("Disabled"))}')
+GetText.add('Disconnect','${escape(_("Disconnect"))}')
+GetText.add('Down','${escape(_("Down"))}')
+GetText.add('Down Limit','${escape(_("Down Limit"))}')
+GetText.add('Down Speed','${escape(_("Down Speed"))}')
+GetText.add('Download','${escape(_("Download"))}')
+GetText.add('Download Folder','${escape(_("Download Folder"))}')
+GetText.add('Download Folder:','${escape(_("Download Folder:"))}')
+GetText.add('Download Speed','${escape(_("Download Speed"))}')
+GetText.add('Download to:','${escape(_("Download to:"))}')
+GetText.add('Downloaded','${escape(_("Downloaded"))}')
+GetText.add('Downloading','${escape(_("Downloading"))}')
+GetText.add('Downloading:','${escape(_("Downloading:"))}')
+GetText.add('Downloads','${escape(_("Downloads"))}')
+GetText.add('ETA','${escape(_("ETA"))}')
+GetText.add('Edit','${escape(_("Edit"))}')
+GetText.add('Edit Connection','${escape(_("Edit Connection"))}')
+GetText.add('Edit Tracker','${escape(_("Edit Tracker"))}')
+GetText.add('Edit Trackers','${escape(_("Edit Trackers"))}')
+GetText.add('Either','${escape(_("Either"))}')
+GetText.add('Enabled','${escape(_("Enabled"))}')
+GetText.add('Encryption','${escape(_("Encryption"))}')
+GetText.add('Error','${escape(_("Error"))}')
+GetText.add('Expand All','${escape(_("Expand All"))}')
+GetText.add('External IP Address','${escape(_("External IP Address"))}')
+GetText.add('File','${escape(_("File"))}')
+GetText.add('File Browser','${escape(_("File Browser"))}')
+GetText.add('Filename','${escape(_("Filename"))}')
+GetText.add('Files','${escape(_("Files"))}')
+GetText.add('Filters','${escape(_("Filters"))}')
+GetText.add('Find More','${escape(_("Find More"))}')
+GetText.add('Folders','${escape(_("Folders"))}')
+GetText.add('Force Proxy','${escape(_("Force Proxy"))}')
+GetText.add('Force Recheck','${escape(_("Force Recheck"))}')
+GetText.add('Force Use of Proxy','${escape(_("Force Use of Proxy"))}')
+GetText.add('Forced','${escape(_("Forced"))}')
+GetText.add('Forward','${escape(_("Forward"))}')
+GetText.add('Freespace in download folder','${escape(_("Freespace in download folder"))}')
+GetText.add('From:','${escape(_("From:"))}')
+GetText.add('Full Stream','${escape(_("Full Stream"))}')
+GetText.add('General','${escape(_("General"))}')
+GetText.add('GeoIP Database','${escape(_("GeoIP Database"))}')
+GetText.add('Global Bandwidth Usage','${escape(_("Global Bandwidth Usage"))}')
+GetText.add('HTTP','${escape(_("HTTP"))}')
+GetText.add('HTTP Auth','${escape(_("HTTP Auth"))}')
+GetText.add('Handshake','${escape(_("Handshake"))}')
+GetText.add('Hash:','${escape(_("Hash:"))}')
+GetText.add('Help','${escape(_("Help"))}')
+GetText.add('Hide Client Identity','${escape(_("Hide Client Identity"))}')
+GetText.add('High','${escape(_("High"))}')
+GetText.add('Home','${escape(_("Home"))}')
+GetText.add('Homepage:','${escape(_("Homepage:"))}')
+GetText.add('Host','${escape(_("Host"))}')
+GetText.add('Host:','${escape(_("Host:"))}')
+GetText.add('I2P','${escape(_("I2P"))}')
+GetText.add('Ignore limits on local network','${escape(_("Ignore limits on local network"))}')
+GetText.add('Ignore slow torrents','${escape(_("Ignore slow torrents"))}')
+GetText.add('Incoming Address','${escape(_("Incoming Address"))}')
+GetText.add('Incoming Port','${escape(_("Incoming Port"))}')
+GetText.add('Incoming:','${escape(_("Incoming:"))}')
+GetText.add('Infohash','${escape(_("Infohash"))}')
+GetText.add('Install','${escape(_("Install"))}')
+GetText.add('Install Plugin','${escape(_("Install Plugin"))}')
+GetText.add('Interface','${escape(_("Interface"))}')
+GetText.add('Invalid Password','${escape(_("Invalid Password"))}')
+GetText.add('KiB/s','${escape(_("KiB/s"))}')
+GetText.add('LSD','${escape(_("LSD"))}')
+GetText.add('Labels','${escape(_("Labels"))}')
+GetText.add('Language','${escape(_("Language"))}')
+GetText.add('Last Transfer','${escape(_("Last Transfer"))}')
+GetText.add('Level:','${escape(_("Level:"))}')
+GetText.add('Loading','${escape(_("Loading"))}')
+GetText.add('Login','${escape(_("Login"))}')
+GetText.add('Login Failed','${escape(_("Login Failed"))}')
+GetText.add('Logout','${escape(_("Logout"))}')
+GetText.add('Lost Connection','${escape(_("Lost Connection"))}')
+GetText.add('Lost connection to webserver','${escape(_("Lost connection to webserver"))}')
+GetText.add('Low','${escape(_("Low"))}')
+GetText.add('Max Connections','${escape(_("Max Connections"))}')
+GetText.add('Max Connections:','${escape(_("Max Connections:"))}')
+GetText.add('Max Down Speed','${escape(_("Max Down Speed"))}')
+GetText.add('Max Download Speed:','${escape(_("Max Download Speed:"))}')
+GetText.add('Max Up Speed','${escape(_("Max Up Speed"))}')
+GetText.add('Max Upload Slots','${escape(_("Max Upload Slots"))}')
+GetText.add('Max Upload Slots:','${escape(_("Max Upload Slots:"))}')
+GetText.add('Max Upload Speed:','${escape(_("Max Upload Speed:"))}')
+GetText.add('Maximum Connection Attempts per Second:','${escape(_("Maximum Connection Attempts per Second:"))}')
+GetText.add('Maximum Connections:','${escape(_("Maximum Connections:"))}')
+GetText.add('Maximum Download Speed (KiB/s):','${escape(_("Maximum Download Speed (KiB/s):"))}')
+GetText.add('Maximum Half-Open Connections:','${escape(_("Maximum Half-Open Connections:"))}')
+GetText.add('Maximum Upload Slots','${escape(_("Maximum Upload Slots"))}')
+GetText.add('Maximum Upload Slots:','${escape(_("Maximum Upload Slots:"))}')
+GetText.add('Maximum Upload Speed (KiB/s):','${escape(_("Maximum Upload Speed (KiB/s):"))}')
+GetText.add('Mixed','${escape(_("Mixed"))}')
+GetText.add('Move','${escape(_("Move"))}')
+GetText.add('Move Completed Folder','${escape(_("Move Completed Folder"))}')
+GetText.add('Move Completed:','${escape(_("Move Completed:"))}')
+GetText.add('Move Download Folder','${escape(_("Move Download Folder"))}')
+GetText.add('Move completed to:','${escape(_("Move completed to:"))}')
+GetText.add('NAT-PMP','${escape(_("NAT-PMP"))}')
+GetText.add('Name','${escape(_("Name"))}')
+GetText.add('Name:','${escape(_("Name:"))}')
+GetText.add('Network','${escape(_("Network"))}')
+GetText.add('Network Extras','${escape(_("Network Extras"))}')
+GetText.add('Never','${escape(_("Never"))}')
+GetText.add('New Torrents','${escape(_("New Torrents"))}')
+GetText.add('New:','${escape(_("New:"))}')
+GetText.add('None','${escape(_("None"))}')
+GetText.add('Normal','${escape(_("Normal"))}')
+GetText.add('Not Connected','${escape(_("Not Connected"))}')
+GetText.add('Not a valid torrent','${escape(_("Not a valid torrent"))}')
+GetText.add('OK','${escape(_("OK"))}')
+GetText.add('Off','${escape(_("Off"))}')
+GetText.add('Offline','${escape(_("Offline"))}')
+GetText.add('Old:','${escape(_("Old:"))}')
+GetText.add('On','${escape(_("On"))}')
+GetText.add('Online','${escape(_("Online"))}')
+GetText.add('Options','${escape(_("Options"))}')
+GetText.add('Other','${escape(_("Other"))}')
+GetText.add('Outgoing Interface','${escape(_("Outgoing Interface"))}')
+GetText.add('Outgoing Ports','${escape(_("Outgoing Ports"))}')
+GetText.add('Outgoing:','${escape(_("Outgoing:"))}')
+GetText.add('Owner','${escape(_("Owner"))}')
+GetText.add('Password','${escape(_("Password"))}')
+GetText.add('Password:','${escape(_("Password:"))}')
+GetText.add('Path:','${escape(_("Path:"))}')
+GetText.add('Pause','${escape(_("Pause"))}')
+GetText.add('Pause torrent','${escape(_("Pause torrent"))}')
+GetText.add('Paused','${escape(_("Paused"))}')
+GetText.add('Peer Exchange','${escape(_("Peer Exchange"))}')
+GetText.add('Peer TOS Byte:','${escape(_("Peer TOS Byte:"))}')
+GetText.add('Peers','${escape(_("Peers"))}')
+GetText.add('Per Torrent Bandwidth Usage','${escape(_("Per Torrent Bandwidth Usage"))}')
+GetText.add('Periodically check the website for new releases','${escape(_("Periodically check the website for new releases"))}')
+GetText.add('Plugin','${escape(_("Plugin"))}')
+GetText.add('Plugin Egg','${escape(_("Plugin Egg"))}')
+GetText.add('Plugins','${escape(_("Plugins"))}')
+GetText.add('Port','${escape(_("Port"))}')
+GetText.add('Port:','${escape(_("Port:"))}')
+GetText.add('Pre-allocate disk space','${escape(_("Pre-allocate disk space"))}')
+GetText.add('Preallocate Disk Space','${escape(_("Preallocate Disk Space"))}')
+GetText.add('Prefer seeding torrents','${escape(_("Prefer seeding torrents"))}')
+GetText.add('Preferences','${escape(_("Preferences"))}')
+GetText.add('Prioritize First/Last','${escape(_("Prioritize First/Last"))}')
+GetText.add('Prioritize First/Last Pieces','${escape(_("Prioritize First/Last Pieces"))}')
+GetText.add('Prioritize first and last pieces of torrent','${escape(_("Prioritize first and last pieces of torrent"))}')
+GetText.add('Priority','${escape(_("Priority"))}')
+GetText.add('Private','${escape(_("Private"))}')
+GetText.add('Private Key:','${escape(_("Private Key:"))}')
+GetText.add('Progress','${escape(_("Progress"))}')
+GetText.add('Protocol Traffic Download/Upload','${escape(_("Protocol Traffic Download/Upload"))}')
+GetText.add('Proxy','${escape(_("Proxy"))}')
+GetText.add('Proxy Hostnames','${escape(_("Proxy Hostnames"))}')
+GetText.add('Proxy Peers','${escape(_("Proxy Peers"))}')
+GetText.add('Proxy Trackers','${escape(_("Proxy Trackers"))}')
+GetText.add('Public','${escape(_("Public"))}')
+GetText.add('Queue','${escape(_("Queue"))}')
+GetText.add('Queue to top','${escape(_("Queue to top"))}')
+GetText.add('Queued','${escape(_("Queued"))}')
+GetText.add('Rate limit IP overhead','${escape(_("Rate limit IP overhead"))}')
+GetText.add('Ratio','${escape(_("Ratio"))}')
+GetText.add('Refresh','${escape(_("Refresh"))}')
+GetText.add('Remaining','${escape(_("Remaining"))}')
+GetText.add('Remove','${escape(_("Remove"))}')
+GetText.add('Remove Torrent','${escape(_("Remove Torrent"))}')
+GetText.add('Remove With Data','${escape(_("Remove With Data"))}')
+GetText.add('Remove at ratio','${escape(_("Remove at ratio"))}')
+GetText.add('Remove torrent','${escape(_("Remove torrent"))}')
+GetText.add('Resume','${escape(_("Resume"))}')
+GetText.add('Save','${escape(_("Save"))}')
+GetText.add('Seeding','${escape(_("Seeding"))}')
+GetText.add('Seeding Rotation','${escape(_("Seeding Rotation"))}')
+GetText.add('Seeding:','${escape(_("Seeding:"))}')
+GetText.add('Seeds','${escape(_("Seeds"))}')
+GetText.add('Seeds:Peers','${escape(_("Seeds:Peers"))}')
+GetText.add('Select an egg','${escape(_("Select an egg"))}')
+GetText.add('Sequential Download','${escape(_("Sequential Download"))}')
+GetText.add('Sequential download','${escape(_("Sequential download"))}')
+GetText.add('Server','${escape(_("Server"))}')
+GetText.add('Server:','${escape(_("Server:"))}')
+GetText.add('Session Timeout:','${escape(_("Session Timeout:"))}')
+GetText.add('Set Maximum Connections','${escape(_("Set Maximum Connections"))}')
+GetText.add('Set Maximum Download Speed','${escape(_("Set Maximum Download Speed"))}')
+GetText.add('Set Maximum Upload Speed','${escape(_("Set Maximum Upload Speed"))}')
+GetText.add('Settings','${escape(_("Settings"))}')
+GetText.add('Share Ratio Reached','${escape(_("Share Ratio Reached"))}')
+GetText.add('Share Ratio:','${escape(_("Share Ratio:"))}')
+GetText.add('Shared','${escape(_("Shared"))}')
+GetText.add('Show filters with zero torrents','${escape(_("Show filters with zero torrents"))}')
+GetText.add('Show session speed in titlebar','${escape(_("Show session speed in titlebar"))}')
+GetText.add('Size','${escape(_("Size"))}')
+GetText.add('Skip','${escape(_("Skip"))}')
+GetText.add('Skip File Hash Check','${escape(_("Skip File Hash Check"))}')
+GetText.add('Socks4','${escape(_("Socks4"))}')
+GetText.add('Socks5','${escape(_("Socks5"))}')
+GetText.add('Socks5 Auth','${escape(_("Socks5 Auth"))}')
+GetText.add('Start Daemon','${escape(_("Start Daemon"))}')
+GetText.add('State','${escape(_("State"))}')
+GetText.add('States','${escape(_("States"))}')
+GetText.add('Status','${escape(_("Status"))}')
+GetText.add('Status:','${escape(_("Status:"))}')
+GetText.add('Stop Daemon','${escape(_("Stop Daemon"))}')
+GetText.add('Stop seed at ratio:','${escape(_("Stop seed at ratio:"))}')
+GetText.add('Super Seed','${escape(_("Super Seed"))}')
+GetText.add('Super Seeding','${escape(_("Super Seeding"))}')
+GetText.add('System Default','${escape(_("System Default"))}')
+GetText.add('System Information','${escape(_("System Information"))}')
+GetText.add('The connection to the webserver has been lost!','${escape(_("The connection to the webserver has been lost!"))}')
+GetText.add('Tier','${escape(_("Tier"))}')
+GetText.add('Time (m):','${escape(_("Time (m):"))}')
+GetText.add('Time Ratio:','${escape(_("Time Ratio:"))}')
+GetText.add('To:','${escape(_("To:"))}')
+GetText.add('Top','${escape(_("Top"))}')
+GetText.add('Total Files:','${escape(_("Total Files:"))}')
+GetText.add('Total Size:','${escape(_("Total Size:"))}')
+GetText.add('Total:','${escape(_("Total:"))}')
+GetText.add('Tracker','${escape(_("Tracker"))}')
+GetText.add('Tracker Host','${escape(_("Tracker Host"))}')
+GetText.add('Tracker:','${escape(_("Tracker:"))}')
+GetText.add('Trackers','${escape(_("Trackers"))}')
+GetText.add('Trackers:','${escape(_("Trackers:"))}')
+GetText.add('Type Of Service','${escape(_("Type Of Service"))}')
+GetText.add('Type:','${escape(_("Type:"))}')
+GetText.add('U/L Speed Limit','${escape(_("U/L Speed Limit"))}')
+GetText.add('UPnP','${escape(_("UPnP"))}')
+GetText.add('Unable to add host: {0}','${escape(_("Unable to add host: {0}"))}')
+GetText.add('Unable to edit host','${escape(_("Unable to edit host"))}')
+GetText.add('Unlimited','${escape(_("Unlimited"))}')
+GetText.add('Up','${escape(_("Up"))}')
+GetText.add('Up Limit','${escape(_("Up Limit"))}')
+GetText.add('Up Speed','${escape(_("Up Speed"))}')
+GetText.add('Update Tracker','${escape(_("Update Tracker"))}')
+GetText.add('Updates','${escape(_("Updates"))}')
+GetText.add('Upload Slot Limit','${escape(_("Upload Slot Limit"))}')
+GetText.add('Upload Speed','${escape(_("Upload Speed"))}')
+GetText.add('Uploaded','${escape(_("Uploaded"))}')
+GetText.add('Uploading your plugin...','${escape(_("Uploading your plugin..."))}')
+GetText.add('Uploading your torrent...','${escape(_("Uploading your torrent..."))}')
+GetText.add('Url','${escape(_("Url"))}')
+GetText.add('Use Random Port','${escape(_("Use Random Port"))}')
+GetText.add('Use Random Ports','${escape(_("Use Random Ports"))}')
+GetText.add('Username:','${escape(_("Username:"))}')
+GetText.add('Version','${escape(_("Version"))}')
+GetText.add('Version:','${escape(_("Version:"))}')
+GetText.add('Warning','${escape(_("Warning"))}')
+GetText.add('WebUI Language Changed','${escape(_("WebUI Language Changed"))}')
+GetText.add('WebUI Password','${escape(_("WebUI Password"))}')
+GetText.add('Yes, please send anonymous statistics','${escape(_("Yes, please send anonymous statistics"))}')
+GetText.add('You entered an incorrect password','${escape(_("You entered an incorrect password"))}')
+GetText.add('Your old password was incorrect!','${escape(_("Your old password was incorrect!"))}')
+GetText.add('Your password was successfully changed!','${escape(_("Your password was successfully changed!"))}')
+GetText.add('libtorrent:','${escape(_("libtorrent:"))}')
+GetText.add('n/a','${escape(_("n/a"))}')
diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py
new file mode 100644
index 0000000..bfacb58
--- /dev/null
+++ b/deluge/ui/web/json_api.py
@@ -0,0 +1,1019 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009-2010 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import division, unicode_literals
+
+import json
+import logging
+import os
+import shutil
+import tempfile
+from base64 import b64encode
+from types import FunctionType
+from xml.sax.saxutils import escape as xml_escape
+
+from twisted.internet import defer, reactor
+from twisted.internet.defer import Deferred, DeferredList
+from twisted.web import http, resource, server
+
+from deluge import component, httpdownloader
+from deluge.common import AUTH_LEVEL_DEFAULT, get_magnet_info, is_magnet
+from deluge.configmanager import get_config_dir
+from deluge.error import NotAuthorizedError
+from deluge.i18n import get_languages
+from deluge.ui.client import Client, client
+from deluge.ui.common import FileTree2, TorrentInfo
+from deluge.ui.coreconfig import CoreConfig
+from deluge.ui.hostlist import HostList
+from deluge.ui.sessionproxy import SessionProxy
+from deluge.ui.web.common import _
+
+log = logging.getLogger(__name__)
+
+
+class JSONComponent(component.Component):
+ def __init__(self, name, interval=1, depend=None):
+ super(JSONComponent, self).__init__(name, interval, depend)
+ self._json = component.get('JSON')
+ self._json.register_object(self, name)
+
+
+def export(auth_level=AUTH_LEVEL_DEFAULT):
+ """
+ Decorator function to register an object's method as a RPC. The object
+ will need to be registered with a `:class:JSON` to be effective.
+
+ :param func: the function to export
+ :type func: function
+ :param auth_level: the auth level required to call this method
+ :type auth_level: int
+
+ """
+
+ def wrap(func, *args, **kwargs):
+ func._json_export = True
+ func._json_auth_level = auth_level
+ return func
+
+ if isinstance(auth_level, FunctionType):
+ func = auth_level
+ auth_level = AUTH_LEVEL_DEFAULT
+ return wrap(func)
+ else:
+ return wrap
+
+
+class JSONException(Exception):
+ def __init__(self, inner_exception):
+ self.inner_exception = inner_exception
+ Exception.__init__(self, str(inner_exception))
+
+
+class JSON(resource.Resource, component.Component):
+ """
+ A Twisted Web resource that exposes a JSON-RPC interface for web clients \
+ to use.
+ """
+
+ def __init__(self):
+ resource.Resource.__init__(self)
+ component.Component.__init__(self, 'JSON')
+ self._remote_methods = []
+ self._local_methods = {}
+ if client.is_standalone():
+ self.get_remote_methods()
+
+ def get_remote_methods(self, result=None):
+ """
+ Updates remote methods from the daemon.
+
+ Returns:
+ t.i.d.Deferred: A deferred returning the available remote methods
+ """
+
+ def on_get_methods(methods):
+ self._remote_methods = methods
+ return methods
+
+ return client.daemon.get_method_list().addCallback(on_get_methods)
+
+ def _exec_local(self, method, params, request):
+ """
+ Handles executing all local methods.
+ """
+ if method == 'system.listMethods':
+ d = Deferred()
+ methods = list(self._remote_methods)
+ methods.extend(self._local_methods)
+ d.callback(methods)
+ return d
+ elif method in self._local_methods:
+ # This will eventually process methods that the server adds
+ # and any plugins.
+ meth = self._local_methods[method]
+ meth.__globals__['__request__'] = request
+ component.get('Auth').check_request(request, meth)
+ return meth(*params)
+ raise JSONException('Unknown system method')
+
+ def _exec_remote(self, method, params, request):
+ """
+ Executes methods using the Deluge client.
+ """
+ component.get('Auth').check_request(request, level=AUTH_LEVEL_DEFAULT)
+ core_component, method = method.split('.')
+ return getattr(getattr(client, core_component), method)(*params)
+
+ def _handle_request(self, request):
+ """
+ Takes some json data as a string and attempts to decode it, and process
+ the rpc object that should be contained, returning a deferred for all
+ procedure calls and the request id.
+ """
+ try:
+ request_data = json.loads(request.json.decode())
+ except (ValueError, TypeError):
+ raise JSONException('JSON not decodable')
+
+ try:
+ method = request_data['method']
+ params = request_data['params']
+ request_id = request_data['id']
+ except KeyError as ex:
+ message = 'Invalid JSON request, missing param %s in %s' % (
+ ex,
+ request_data,
+ )
+ raise JSONException(message)
+
+ result = None
+ error = None
+
+ try:
+ if method.startswith('system.') or method in self._local_methods:
+ result = self._exec_local(method, params, request)
+ elif method in self._remote_methods:
+ result = self._exec_remote(method, params, request)
+ else:
+ error = {'message': 'Unknown method', 'code': 2}
+ except NotAuthorizedError:
+ error = {'message': 'Not authenticated', 'code': 1}
+ except Exception as ex:
+ log.error('Error calling method `%s`: %s', method, ex)
+ log.exception(ex)
+ error = {'message': '%s: %s' % (ex.__class__.__name__, str(ex)), 'code': 3}
+
+ return request_id, result, error
+
+ def _on_rpc_request_finished(self, result, response, request):
+ """
+ Sends the response of any rpc calls back to the json-rpc client.
+ """
+ response['result'] = result
+ return self._send_response(request, response)
+
+ def _on_rpc_request_failed(self, reason, response, request):
+ """
+ Handles any failures that occurred while making an rpc call.
+ """
+ log.error(reason)
+ response['error'] = {
+ 'message': '%s: %s' % (reason.__class__.__name__, str(reason)),
+ 'code': 4,
+ }
+ return self._send_response(request, response)
+
+ def _on_json_request(self, request):
+ """
+ Handler to take the json data as a string and pass it on to the
+ _handle_request method for further processing.
+ """
+ content_type = request.getHeader(b'content-type').decode()
+ if content_type != 'application/json':
+ message = 'Invalid JSON request content-type: %s' % content_type
+ raise JSONException(message)
+
+ log.debug('json-request: %s', request.json)
+ response = {'result': None, 'error': None, 'id': None}
+ response['id'], d, response['error'] = self._handle_request(request)
+
+ if isinstance(d, Deferred):
+ d.addCallback(self._on_rpc_request_finished, response, request)
+ d.addErrback(self._on_rpc_request_failed, response, request)
+ return d
+ else:
+ response['result'] = d
+ return self._send_response(request, response)
+
+ def _on_json_request_failed(self, reason, request):
+ """
+ Returns the error in json response.
+ """
+ log.error(reason)
+ response = {
+ 'result': None,
+ 'id': None,
+ 'error': {
+ 'code': 5,
+ 'message': '%s: %s' % (reason.__class__.__name__, str(reason)),
+ },
+ }
+ return self._send_response(request, response)
+
+ def _send_response(self, request, response):
+ if request._disconnected:
+ return ''
+ response = json.dumps(response)
+ request.setHeader(b'content-type', b'application/json')
+ request.write(response.encode())
+ request.finish()
+ return server.NOT_DONE_YET
+
+ def render(self, request):
+ """
+ Handles all the POST requests made to the /json controller.
+ """
+ if request.method != b'POST':
+ request.setResponseCode(http.NOT_ALLOWED)
+ request.finish()
+ return server.NOT_DONE_YET
+
+ try:
+ request.content.seek(0)
+ request.json = request.content.read()
+ self._on_json_request(request)
+ return server.NOT_DONE_YET
+ except Exception as ex:
+ return self._on_json_request_failed(ex, request)
+
+ def register_object(self, obj, name=None):
+ """Registers an object to export it's rpc methods.
+
+ These methods should be exported with the export decorator prior
+ to registering the object.
+
+ Args:
+ obj (object): The object that we want to export.
+ name (str): The name to use. If None, uses the object class name.
+
+ """
+ name = name or obj.__class__.__name__
+ name = name.lower()
+
+ for d in dir(obj):
+ if d[0] == '_':
+ continue
+ if getattr(getattr(obj, d), '_json_export', False):
+ log.debug('Registering method: %s', name + '.' + d)
+ self._local_methods[name + '.' + d] = getattr(obj, d)
+
+ def deregister_object(self, obj):
+ """Deregisters an objects exported rpc methods.
+
+ Args:
+ obj (object): The object that was previously registered.
+
+ """
+ for key, value in self._local_methods.items():
+ if value.__self__ == obj:
+ del self._local_methods[key]
+
+
+FILES_KEYS = ['files', 'file_progress', 'file_priorities']
+
+
+class EventQueue(object):
+ """
+ This class subscribes to events from the core and stores them until all
+ the subscribed listeners have received the events.
+ """
+
+ def __init__(self):
+ self.__events = {}
+ self.__handlers = {}
+ self.__queue = {}
+ self.__requests = {}
+
+ def add_listener(self, listener_id, event):
+ """
+ Add a listener to the event queue.
+
+ :param listener_id: A unique id for the listener
+ :type listener_id: string
+ :param event: The event name
+ :type event: string
+ """
+ if event not in self.__events:
+
+ def on_event(*args):
+ for listener in self.__events[event]:
+ if listener not in self.__queue:
+ self.__queue[listener] = []
+ self.__queue[listener].append((event, args))
+
+ client.register_event_handler(event, on_event)
+ self.__handlers[event] = on_event
+ self.__events[event] = [listener_id]
+ elif listener_id not in self.__events[event]:
+ self.__events[event].append(listener_id)
+
+ def get_events(self, listener_id):
+ """
+ Retrieve the pending events for the listener.
+
+ :param listener_id: A unique id for the listener
+ :type listener_id: string
+ """
+
+ # Check to see if we have anything to return immediately
+ if listener_id in self.__queue:
+ queue = self.__queue[listener_id]
+ del self.__queue[listener_id]
+ return queue
+
+ # Create a deferred to and check again in 100ms
+ d = Deferred()
+ reactor.callLater(0.1, self._get_events, listener_id, 0, d)
+ return d
+
+ def _get_events(self, listener_id, count, d):
+ if listener_id in self.__queue:
+ queue = self.__queue[listener_id]
+ del self.__queue[listener_id]
+ d.callback(queue)
+ else:
+ # Prevent this loop going on indefinitely incase a client leaves
+ # the page or disconnects uncleanly.
+ if count >= 50:
+ d.callback(None)
+ else:
+ reactor.callLater(0.1, self._get_events, listener_id, count + 1, d)
+
+ def remove_listener(self, listener_id, event):
+ """
+ Remove a listener from the event queue.
+
+ :param listener_id: The unique id for the listener
+ :type listener_id: string
+ :param event: The event name
+ :type event: string
+ """
+ self.__events[event].remove(listener_id)
+ if not self.__events[event]:
+ client.deregister_event_handler(event, self.__handlers[event])
+ del self.__events[event]
+ del self.__handlers[event]
+
+
+class WebApi(JSONComponent):
+ """
+ The component that implements all the methods required for managing
+ the web interface. The complete web json interface also exposes all the
+ methods available from the core RPC.
+ """
+
+ XSS_VULN_KEYS = ['name', 'message', 'comment', 'tracker_status', 'peers']
+
+ def __init__(self):
+ super(WebApi, self).__init__('Web', depend=['SessionProxy'])
+ self.hostlist = HostList()
+ self.core_config = CoreConfig()
+ self.event_queue = EventQueue()
+ try:
+ self.sessionproxy = component.get('SessionProxy')
+ except KeyError:
+ self.sessionproxy = SessionProxy()
+
+ def disable(self):
+ client.deregister_event_handler(
+ 'PluginEnabledEvent', self._json.get_remote_methods
+ )
+ client.deregister_event_handler(
+ 'PluginDisabledEvent', self._json.get_remote_methods
+ )
+
+ if client.is_standalone():
+ component.get('Web.PluginManager').stop()
+ else:
+ client.disconnect()
+ client.set_disconnect_callback(None)
+
+ def enable(self):
+ client.register_event_handler(
+ 'PluginEnabledEvent', self._json.get_remote_methods
+ )
+ client.register_event_handler(
+ 'PluginDisabledEvent', self._json.get_remote_methods
+ )
+
+ if client.is_standalone():
+ component.get('Web.PluginManager').start()
+ else:
+ client.set_disconnect_callback(self._on_client_disconnect)
+ default_host_id = component.get('DelugeWeb').config['default_daemon']
+ if default_host_id:
+ return self.connect(default_host_id)
+
+ return defer.succeed(True)
+
+ def _on_client_connect(self, *args):
+ """Handles client successfully connecting to the daemon.
+
+ Invokes retrieving the method names and starts webapi and plugins.
+
+ """
+ d_methods = self._json.get_remote_methods()
+ component.get('Web.PluginManager').start()
+ self.start()
+ return d_methods
+
+ def _on_client_connect_fail(self, result, host_id):
+ log.error(
+ 'Unable to connect to daemon, check host_id "%s" is correct.', host_id
+ )
+
+ def _on_client_disconnect(self, *args):
+ component.get('Web.PluginManager').stop()
+ return self.stop()
+
+ def start(self):
+ self.core_config.start()
+ return self.sessionproxy.start()
+
+ def stop(self):
+ self.core_config.stop()
+ self.sessionproxy.stop()
+ return defer.succeed(True)
+
+ @export
+ def connect(self, host_id):
+ """Connect the web client to a daemon.
+
+ Args:
+ host_id (str): The id of the daemon in the host list.
+
+ Returns:
+ Deferred: List of methods the daemon supports.
+ """
+ d = self.hostlist.connect_host(host_id)
+ d.addCallback(self._on_client_connect)
+ d.addErrback(self._on_client_connect_fail, host_id)
+ return d
+
+ @export
+ def connected(self):
+ """
+ The current connection state.
+
+ :returns: True if the client is connected
+ :rtype: booleon
+ """
+ return client.connected()
+
+ @export
+ def disconnect(self):
+ """
+ Disconnect the web interface from the connected daemon.
+ """
+ d = client.disconnect()
+
+ def on_disconnect(reason):
+ return str(reason)
+
+ d.addCallback(on_disconnect)
+ return d
+
+ @export
+ def update_ui(self, keys, filter_dict):
+ """
+ Gather the information required for updating the web interface.
+
+ :param keys: the information about the torrents to gather
+ :type keys: list
+ :param filter_dict: the filters to apply when selecting torrents.
+ :type filter_dict: dictionary
+ :returns: The torrent and ui information.
+ :rtype: dictionary
+ """
+ d = Deferred()
+ ui_info = {
+ 'connected': client.connected(),
+ 'torrents': None,
+ 'filters': None,
+ 'stats': {
+ 'max_download': self.core_config.get('max_download_speed'),
+ 'max_upload': self.core_config.get('max_upload_speed'),
+ 'max_num_connections': self.core_config.get('max_connections_global'),
+ },
+ }
+
+ if not client.connected():
+ d.callback(ui_info)
+ return d
+
+ def got_stats(stats):
+ ui_info['stats']['num_connections'] = stats['num_peers']
+ ui_info['stats']['upload_rate'] = stats['payload_upload_rate']
+ ui_info['stats']['download_rate'] = stats['payload_download_rate']
+ ui_info['stats']['download_protocol_rate'] = (
+ stats['download_rate'] - stats['payload_download_rate']
+ )
+ ui_info['stats']['upload_protocol_rate'] = (
+ stats['upload_rate'] - stats['payload_upload_rate']
+ )
+ ui_info['stats']['dht_nodes'] = stats['dht_nodes']
+ ui_info['stats']['has_incoming_connections'] = stats[
+ 'has_incoming_connections'
+ ]
+
+ def got_filters(filters):
+ ui_info['filters'] = filters
+
+ def got_free_space(free_space):
+ ui_info['stats']['free_space'] = free_space
+
+ def got_external_ip(external_ip):
+ ui_info['stats']['external_ip'] = external_ip
+
+ def got_torrents(torrents):
+ ui_info['torrents'] = torrents
+
+ def on_complete(result):
+ d.callback(ui_info)
+
+ d1 = component.get('SessionProxy').get_torrents_status(filter_dict, keys)
+ d1.addCallback(got_torrents)
+
+ d2 = client.core.get_filter_tree()
+ d2.addCallback(got_filters)
+
+ d3 = client.core.get_session_status(
+ [
+ 'num_peers',
+ 'payload_download_rate',
+ 'payload_upload_rate',
+ 'download_rate',
+ 'upload_rate',
+ 'dht_nodes',
+ 'has_incoming_connections',
+ ]
+ )
+ d3.addCallback(got_stats)
+
+ d4 = client.core.get_free_space(self.core_config.get('download_location'))
+ d4.addCallback(got_free_space)
+
+ d5 = client.core.get_external_ip()
+ d5.addCallback(got_external_ip)
+
+ dl = DeferredList([d1, d2, d3, d4, d5], consumeErrors=True)
+ dl.addCallback(on_complete)
+ return d
+
+ def _on_got_files(self, torrent, d):
+ files = torrent.get('files')
+ file_progress = torrent.get('file_progress')
+ file_priorities = torrent.get('file_priorities')
+
+ paths = []
+ info = {}
+ for index, torrent_file in enumerate(files):
+ path = xml_escape(torrent_file['path'])
+ paths.append(path)
+ torrent_file['progress'] = file_progress[index]
+ torrent_file['priority'] = file_priorities[index]
+ torrent_file['index'] = index
+ torrent_file['path'] = path
+ info[path] = torrent_file
+
+ # update the directory info
+ dirname = os.path.dirname(path)
+ while dirname:
+ dirinfo = info.setdefault(dirname, {})
+ dirinfo['size'] = dirinfo.get('size', 0) + torrent_file['size']
+ if 'priority' not in dirinfo:
+ dirinfo['priority'] = torrent_file['priority']
+ else:
+ if dirinfo['priority'] != torrent_file['priority']:
+ dirinfo['priority'] = 9
+
+ progresses = dirinfo.setdefault('progresses', [])
+ progresses.append(torrent_file['size'] * torrent_file['progress'] / 100)
+ dirinfo['progress'] = sum(progresses) / dirinfo['size'] * 100
+ dirinfo['path'] = dirname
+ dirname = os.path.dirname(dirname)
+
+ def walk(path, item):
+ if item['type'] == 'dir':
+ item.update(info[path])
+ return item
+ else:
+ item.update(info[path])
+ return item
+
+ file_tree = FileTree2(paths)
+ file_tree.walk(walk)
+ d.callback(file_tree.get_tree())
+
+ def _on_torrent_status(self, torrent, d):
+ for key in self.XSS_VULN_KEYS:
+ try:
+ if key == 'peers':
+ for peer in torrent[key]:
+ peer['client'] = xml_escape(peer['client'])
+ else:
+ torrent[key] = xml_escape(torrent[key])
+ except KeyError:
+ pass
+ d.callback(torrent)
+
+ @export
+ def get_torrent_status(self, torrent_id, keys):
+ """Get the status for a torrent, filtered by status keys."""
+ main_deferred = Deferred()
+ d = component.get('SessionProxy').get_torrent_status(torrent_id, keys)
+ d.addCallback(self._on_torrent_status, main_deferred)
+ return main_deferred
+
+ @export
+ def get_torrent_files(self, torrent_id):
+ """
+ Gets the files for a torrent in tree format
+
+ :param torrent_id: the id of the torrent to retrieve.
+ :type torrent_id: string
+ :returns: The torrents files in a tree
+ :rtype: dictionary
+ """
+ main_deferred = Deferred()
+ d = component.get('SessionProxy').get_torrent_status(torrent_id, FILES_KEYS)
+ d.addCallback(self._on_got_files, main_deferred)
+ return main_deferred
+
+ @export
+ def download_torrent_from_url(self, url, cookie=None):
+ """
+ Download a torrent file from a url to a temporary directory.
+
+ :param url: the url of the torrent
+ :type url: string
+ :returns: the temporary file name of the torrent file
+ :rtype: string
+ """
+
+ def on_download_success(result):
+ log.debug('Successfully downloaded %s to %s', url, result)
+ return result
+
+ def on_download_fail(result):
+ log.error('Failed to add torrent from url %s', url)
+ return result
+
+ tempdir = tempfile.mkdtemp(prefix='delugeweb-')
+ tmp_file = os.path.join(tempdir, url.split('/')[-1])
+ log.debug('filename: %s', tmp_file)
+ headers = {}
+ if cookie:
+ headers['Cookie'] = cookie
+ log.debug('cookie: %s', cookie)
+ d = httpdownloader.download_file(url, tmp_file, headers=headers)
+ d.addCallbacks(on_download_success, on_download_fail)
+ return d
+
+ @export
+ def get_torrent_info(self, filename):
+ """
+ Return information about a torrent on the filesystem.
+
+ :param filename: the path to the torrent
+ :type filename: string
+
+ :returns: information about the torrent:
+
+ ::
+
+ {
+ "name": the torrent name,
+ "files_tree": the files the torrent contains,
+ "info_hash" the torrents info_hash
+ }
+
+ :rtype: dictionary
+ """
+ try:
+ torrent_info = TorrentInfo(filename.strip(), 2)
+ return torrent_info.as_dict('name', 'info_hash', 'files_tree')
+ except Exception as ex:
+ log.error(ex)
+ return False
+
+ @export
+ def get_magnet_info(self, uri):
+ """Parse a magnet URI for hash and name."""
+ return get_magnet_info(uri)
+
+ @export
+ def add_torrents(self, torrents):
+ """
+ Add torrents by file
+
+ :param torrents: A list of dictionaries containing the torrent \
+ path and torrent options to add with.
+ :type torrents: list
+
+ ::
+
+ json_api.web.add_torrents([{
+ "path": "/tmp/deluge-web/some-torrent-file.torrent",
+ "options": {"download_location": "/home/deluge/"}
+ }])
+
+ """
+ deferreds = []
+
+ for torrent in torrents:
+ if is_magnet(torrent['path']):
+ log.info(
+ 'Adding torrent from magnet uri `%s` with options `%r`',
+ torrent['path'],
+ torrent['options'],
+ )
+ d = client.core.add_torrent_magnet(torrent['path'], torrent['options'])
+ deferreds.append(d)
+ else:
+ filename = os.path.basename(torrent['path'])
+ with open(torrent['path'], 'rb') as _file:
+ fdump = b64encode(_file.read())
+ log.info(
+ 'Adding torrent from file `%s` with options `%r`',
+ filename,
+ torrent['options'],
+ )
+ d = client.core.add_torrent_file_async(
+ filename, fdump, torrent['options']
+ )
+ deferreds.append(d)
+ return DeferredList(deferreds, consumeErrors=False)
+
+ def _get_host(self, host_id):
+ """Information about a host from supplied host id.
+
+ Args:
+ host_id (str): The id of the host.
+
+ Returns:
+ list: The host information, empty list if not found.
+
+ """
+ return list(self.hostlist.get_host_info(host_id))
+
+ @export
+ def get_hosts(self):
+ """
+ Return the hosts in the hostlist.
+ """
+ log.debug('get_hosts called')
+ return self.hostlist.get_hosts_info()
+
+ @export
+ def get_host_status(self, host_id):
+ """
+ Returns the current status for the specified host.
+
+ :param host_id: the hash id of the host
+ :type host_id: string
+
+ """
+
+ def response(result):
+ return result
+
+ return self.hostlist.get_host_status(host_id).addCallback(response)
+
+ @export
+ def add_host(self, host, port, username='', password=''):
+ """Adds a host to the list.
+
+ Args:
+ host (str): The IP or hostname of the deluge daemon.
+ port (int): The port of the deluge daemon.
+ username (str): The username to login to the daemon with.
+ password (str): The password to login to the daemon with.
+
+ Returns:
+ tuple: A tuple of (bool, str). If True will contain the host_id, otherwise
+ if False will contain the error message.
+ """
+ try:
+ host_id = self.hostlist.add_host(host, port, username, password)
+ except ValueError as ex:
+ return False, str(ex)
+ else:
+ return True, host_id
+
+ @export
+ def edit_host(self, host_id, host, port, username='', password=''):
+ """Edit host details in the hostlist.
+
+ Args:
+ host_id (str): The host identifying hash.
+ host (str): The IP or hostname of the deluge daemon.
+ port (int): The port of the deluge daemon.
+ username (str): The username to login to the daemon with.
+ password (str): The password to login to the daemon with.
+
+ Returns:
+ bool: True if succesful, False otherwise.
+
+ """
+ return self.hostlist.update_host(host_id, host, port, username, password)
+
+ @export
+ def remove_host(self, host_id):
+ """Removes a host from the hostlist.
+
+ Args:
+ host_id (str): The host identifying hash.
+
+ Returns:
+ bool: True if succesful, False otherwise.
+
+ """
+ return self.hostlist.remove_host(host_id)
+
+ @export
+ def start_daemon(self, port):
+ """
+ Starts a local daemon.
+ """
+ client.start_daemon(port, get_config_dir())
+
+ @export
+ def stop_daemon(self, host_id):
+ """
+ Stops a running daemon.
+
+ :param host_id: the hash id of the host
+ :type host_id: string
+ """
+ main_deferred = Deferred()
+ host = self._get_host(host_id)
+ if not host:
+ main_deferred.callback((False, _('Daemon does not exist')))
+ return main_deferred
+
+ try:
+
+ def on_connect(connected, c):
+ if not connected:
+ main_deferred.callback((False, _('Daemon not running')))
+ return
+ c.daemon.shutdown()
+ main_deferred.callback((True,))
+
+ def on_connect_failed(reason):
+ main_deferred.callback((False, reason))
+
+ host, port, user, password = host[1:5]
+ c = Client()
+ d = c.connect(host, port, user, password)
+ d.addCallback(on_connect, c)
+ d.addErrback(on_connect_failed)
+ except Exception:
+ main_deferred.callback((False, 'An error occurred'))
+ return main_deferred
+
+ @export
+ def get_config(self):
+ """
+ Get the configuration dictionary for the web interface.
+
+ :rtype: dictionary
+ :returns: the configuration
+ """
+ config = component.get('DelugeWeb').config.config.copy()
+ del config['sessions']
+ del config['pwd_salt']
+ del config['pwd_sha1']
+ return config
+
+ @export
+ def set_config(self, config):
+ """
+ Sets the configuration dictionary for the web interface.
+
+ :param config: The configuration options to update
+ :type config: dictionary
+ """
+ web_config = component.get('DelugeWeb').config
+ for key in config:
+ if key in ['sessions', 'pwd_salt', 'pwd_sha1']:
+ log.warning('Ignored attempt to overwrite web config key: %s', key)
+ continue
+ web_config[key] = config[key]
+
+ @export
+ def get_plugins(self):
+ """All available and enabled plugins within WebUI.
+
+ Note:
+ This does not represent all plugins from deluge.client.core.
+
+ Returns:
+ dict: A dict containing 'available_plugins' and 'enabled_plugins' lists.
+
+ """
+
+ return {
+ 'enabled_plugins': list(component.get('Web.PluginManager').plugins),
+ 'available_plugins': component.get('Web.PluginManager').available_plugins,
+ }
+
+ @export
+ def get_plugin_info(self, name):
+ """Get the details for a plugin."""
+ return component.get('Web.PluginManager').get_plugin_info(name)
+
+ @export
+ def get_plugin_resources(self, name):
+ """Get the resource data files for a plugin."""
+ return component.get('Web.PluginManager').get_plugin_resources(name)
+
+ @export
+ def upload_plugin(self, filename, path):
+ """Upload a plugin to config."""
+ main_deferred = Deferred()
+
+ shutil.copyfile(path, os.path.join(get_config_dir(), 'plugins', filename))
+ component.get('Web.PluginManager').scan_for_plugins()
+
+ if client.is_localhost():
+ client.core.rescan_plugins()
+ return True
+ with open(path, 'rb') as _file:
+ plugin_data = b64encode(_file.read())
+
+ def on_upload_complete(*args):
+ client.core.rescan_plugins()
+ component.get('Web.PluginManager').scan_for_plugins()
+ main_deferred.callback(True)
+
+ def on_upload_error(*args):
+ main_deferred.callback(False)
+
+ d = client.core.upload_plugin(filename, plugin_data)
+ d.addCallback(on_upload_complete)
+ d.addErrback(on_upload_error)
+ return main_deferred
+
+ @export
+ def register_event_listener(self, event):
+ """
+ Add a listener to the event queue.
+
+ :param event: The event name
+ :type event: string
+ """
+ self.event_queue.add_listener(__request__.session_id, event)
+
+ @export
+ def deregister_event_listener(self, event):
+ """
+ Remove an event listener from the event queue.
+
+ :param event: The event name
+ :type event: string
+ """
+ self.event_queue.remove_listener(__request__.session_id, event)
+
+ @export
+ def get_events(self):
+ """
+ Retrieve the pending events for the session.
+ """
+ return self.event_queue.get_events(__request__.session_id)
+
+
+class WebUtils(JSONComponent):
+ """
+ Utility functions for the webui that do not fit in the WebApi.
+ """
+
+ def __init__(self):
+ super(WebUtils, self).__init__('WebUtils')
+
+ @export
+ def get_languages(self):
+ """
+ Get the available translated languages
+
+ Returns:
+ list: of tuples [(lang-id, language-name), ...]
+ """
+ return get_languages()
diff --git a/deluge/ui/web/pluginmanager.py b/deluge/ui/web/pluginmanager.py
new file mode 100644
index 0000000..24f20ce
--- /dev/null
+++ b/deluge/ui/web/pluginmanager.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import unicode_literals
+
+import logging
+import os
+
+from deluge import component
+from deluge.configmanager import ConfigManager
+from deluge.pluginmanagerbase import PluginManagerBase
+from deluge.ui.client import client
+
+log = logging.getLogger(__name__)
+
+
+def gather_info(plugin):
+ # Get the scripts for the plugin
+ scripts = getattr(plugin, 'scripts', ())
+ debug_scripts = getattr(plugin, 'debug_scripts') or scripts
+
+ directories = []
+ for script in scripts + debug_scripts:
+ if os.path.dirname(script) not in directories:
+ directories.append(os.path.dirname(script))
+
+ return {
+ 'scripts': scripts,
+ 'debug_scripts': debug_scripts,
+ 'script_directories': directories,
+ }
+
+
+class PluginManager(PluginManagerBase, component.Component):
+ def __init__(self):
+ component.Component.__init__(self, 'Web.PluginManager')
+ self.config = ConfigManager('web.conf')
+ PluginManagerBase.__init__(self, 'web.conf', 'deluge.plugin.web')
+
+ client.register_event_handler(
+ 'PluginEnabledEvent', self._on_plugin_enabled_event
+ )
+ client.register_event_handler(
+ 'PluginDisabledEvent', self._on_plugin_disabled_event
+ )
+
+ def _on_get_enabled_plugins(self, plugins):
+ for plugin in plugins:
+ self.enable_plugin(plugin)
+
+ def _on_plugin_enabled_event(self, name):
+ self.enable_plugin(name)
+
+ def _on_plugin_disabled_event(self, name):
+ self.disable_plugin(name)
+
+ def disable_plugin(self, name):
+ # Get the plugin instance
+ try:
+ plugin = component.get('WebPlugin.' + name)
+ except KeyError:
+ log.debug(
+ '%s plugin contains no WebUI code, ignoring WebUI disable call.', name
+ )
+ return
+
+ info = gather_info(plugin)
+
+ scripts = component.get('Scripts')
+ for script in info['scripts']:
+ scripts.remove_script(
+ '%s/%s' % (name.lower(), os.path.basename(script).lower())
+ )
+
+ for script in info['debug_scripts']:
+ scripts.remove_script(
+ '%s/%s' % (name.lower(), os.path.basename(script).lower()), 'debug'
+ )
+ scripts.remove_script(
+ '%s/%s' % (name.lower(), os.path.basename(script).lower()), 'dev'
+ )
+
+ super(PluginManager, self).disable_plugin(name)
+
+ def enable_plugin(self, name):
+ super(PluginManager, self).enable_plugin(name)
+
+ # Get the plugin instance
+ try:
+ plugin = component.get('WebPlugin.' + name)
+ except KeyError:
+ log.info(
+ '%s plugin contains no WebUI code, ignoring WebUI enable call.', name
+ )
+ return
+
+ info = gather_info(plugin)
+
+ scripts = component.get('Scripts')
+ for script in info['scripts']:
+ log.debug('adding script %s for %s', name, os.path.basename(script))
+ scripts.add_script(
+ '%s/%s' % (name.lower(), os.path.basename(script)), script
+ )
+
+ for script in info['debug_scripts']:
+ log.debug('adding debug script %s for %s', name, os.path.basename(script))
+ scripts.add_script(
+ '%s/%s' % (name.lower(), os.path.basename(script)), script, 'debug'
+ )
+ scripts.add_script(
+ '%s/%s' % (name.lower(), os.path.basename(script)), script, 'dev'
+ )
+
+ def start(self):
+ """
+ Start up the plugin manager
+ """
+ # Update the enabled plugins from the core
+ d = client.core.get_enabled_plugins()
+ d.addCallback(self._on_get_enabled_plugins)
+
+ def stop(self):
+ """
+ Stop the plugin manager
+ """
+ self.disable_plugins()
+ client.deregister_event_handler(
+ 'PluginEnabledEvent', self._on_plugin_enabled_event
+ )
+ client.deregister_event_handler(
+ 'PluginDisabledEvent', self._on_plugin_disabled_event
+ )
+
+ def update(self):
+ pass
+
+ def get_plugin_resources(self, name):
+ # Get the plugin instance
+ try:
+ plugin = component.get('WebPlugin.' + name)
+ except KeyError:
+ log.info('Plugin has no web ui')
+ return
+ info = gather_info(plugin)
+ info['name'] = name
+ info['scripts'] = [
+ 'js/%s/%s' % (name.lower(), os.path.basename(s)) for s in info['scripts']
+ ]
+ info['debug_scripts'] = [
+ 'js/%s/%s' % (name.lower(), os.path.basename(s))
+ for s in info['debug_scripts']
+ ]
+ del info['script_directories']
+ return info
diff --git a/deluge/ui/web/render/404.html b/deluge/ui/web/render/404.html
new file mode 100644
index 0000000..8624de4
--- /dev/null
+++ b/deluge/ui/web/render/404.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Deluge: Web UI ${version}</title>
+ </head>
+ <body>
+ <h1>Error 404 - Page Not Found</h1>
+ <b>The requested template file was not found.</b>
+ </body>
+</html>
diff --git a/deluge/ui/web/render/tab_status.html b/deluge/ui/web/render/tab_status.html
new file mode 100644
index 0000000..deed7d6
--- /dev/null
+++ b/deluge/ui/web/render/tab_status.html
@@ -0,0 +1,29 @@
+<dl>
+ <dt class="downloaded">${_("Downloaded:")}</dt><dd class="downloaded"/>
+ <dt class="uploaded">${_("Uploaded:")}</dt><dd class="uploaded"/>
+ <dt class="share">${_("Share Ratio:")}</dt><dd class="share"/>
+ <dt class="announce">${_("Next Announce:")}</dt><dd class="announce"/>
+ <dt class="tracker">${_("Tracker Status:")}</dt><dd class="tracker_status"/>
+</dl>
+<dl>
+ <dt class="downspeed">${_("Down Speed:")}</dt><dd class="downspeed"/>
+ <dt class="upspeed">${_("Up Speed:")}</dt><dd class="upspeed"/>
+ <dt class="eta">${_("ETA:")}</dt><dd class="eta"/>
+ <dt class="pieces">${_("Pieces:")}</dt><dd class="pieces"/>
+ <dt class="time_since_transfer">${_("Last Transfer:")}</dt><dd class="time_since_transfer"/>
+</dl>
+<dl>
+ <dt class="seeds">${_("Seeds:")}</dt><dd class="seeds"/>
+ <dt class="peers">${_("Peers:")}</dt><dd class="peers"/>
+ <dt class="avail">${_("Availability:")}</dt><dd class="avail"/>
+ <dt class="auto_managed">${_("Auto Managed:")}</dt><dd class="auto_managed"/>
+ <dt class="last_seen_complete">${_("Complete Seen:")}</dt><dd class="last_seen_complete"/>
+</dl>
+<dl>
+ <dt class="active_time">${_("Active Time:")}</dt><dd class="active_time"/>
+ <dt class="seeding_time">${_("Seeding Time:")}</dt><dd class="seeding_time"/>
+ <dt class="seed_rank">${_("Seed Rank:")}</dt><dd class="seed_rank"/>
+ <dt class="time_rank">${_("Date Added:")}</dt><dd class="time_added"/>
+ <dt class="completed_time">${_("Completed:")}</dt><dd class="completed_time"/>
+</dl>
+<br style="clear: both;" />
diff --git a/deluge/ui/web/server.py b/deluge/ui/web/server.py
new file mode 100644
index 0000000..192c2b7
--- /dev/null
+++ b/deluge/ui/web/server.py
@@ -0,0 +1,806 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009-2010 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import unicode_literals
+
+import fnmatch
+import json
+import logging
+import mimetypes
+import os
+import tempfile
+
+from twisted.application import internet, service
+from twisted.internet import defer, reactor
+from twisted.web import http, resource, server, static
+from twisted.web.resource import EncodingResourceWrapper
+
+from deluge import common, component, configmanager
+from deluge.common import is_ipv6
+from deluge.core.rpcserver import check_ssl_keys
+from deluge.crypto_utils import get_context_factory
+from deluge.i18n import set_language, setup_translation
+from deluge.ui.tracker_icons import TrackerIcons
+from deluge.ui.web.auth import Auth
+from deluge.ui.web.common import Template
+from deluge.ui.web.json_api import JSON, WebApi, WebUtils
+from deluge.ui.web.pluginmanager import PluginManager
+
+log = logging.getLogger(__name__)
+
+CONFIG_DEFAULTS = {
+ # Misc Settings
+ 'enabled_plugins': [],
+ 'default_daemon': '',
+ # Auth Settings
+ 'pwd_salt': 'c26ab3bbd8b137f99cd83c2c1c0963bcc1a35cad',
+ 'pwd_sha1': '2ce1a410bcdcc53064129b6d950f2e9fee4edc1e',
+ 'session_timeout': 3600,
+ 'sessions': {},
+ # UI Settings
+ 'sidebar_show_zero': False,
+ 'sidebar_multiple_filters': True,
+ 'show_session_speed': False,
+ 'show_sidebar': True,
+ 'theme': 'gray',
+ 'first_login': True,
+ 'language': '',
+ # Server Settings
+ 'base': '/',
+ 'interface': '0.0.0.0',
+ 'port': 8112,
+ 'https': False,
+ 'pkey': 'ssl/daemon.pkey',
+ 'cert': 'ssl/daemon.cert',
+}
+
+UI_CONFIG_KEYS = (
+ 'theme',
+ 'sidebar_show_zero',
+ 'sidebar_multiple_filters',
+ 'show_session_speed',
+ 'base',
+ 'first_login',
+)
+
+
+def rpath(*paths):
+ """Convert a relative path into an absolute path relative to the location
+ of this script.
+ """
+ return common.resource_filename('deluge.ui.web', os.path.join(*paths))
+
+
+class GetText(resource.Resource):
+ def render(self, request):
+ request.setHeader(b'content-type', b'text/javascript; encoding=utf-8')
+ template = Template(filename=rpath('js', 'gettext.js'))
+ return template.render()
+
+
+class MockGetText(resource.Resource):
+ """GetText Mocking class
+
+ This class will mock the file `gettext.js` in case it does not exists.
+ It will be used to define the `_` (underscore) function for translations,
+ and will return the string to translate, as is.
+ """
+
+ def render(self, request):
+ request.setHeader(b'content-type', b'text/javascript; encoding=utf-8')
+ return b'function _(string) { return string; }'
+
+
+class Upload(resource.Resource):
+ """
+ Twisted Web resource to handle file uploads
+ """
+
+ def render(self, request):
+ """
+ Saves all uploaded files to the disk and returns a list of filenames,
+ each on a new line.
+ """
+
+ # Block all other HTTP methods.
+ if request.method != b'POST':
+ request.setResponseCode(http.NOT_ALLOWED)
+ request.finish()
+ return server.NOT_DONE_YET
+
+ files = request.args.get(b'file', [])
+ filenames = []
+
+ if files:
+ tempdir = tempfile.mkdtemp(prefix='delugeweb-')
+ log.debug('uploading files to %s', tempdir)
+
+ for upload in files:
+ fd, fn = tempfile.mkstemp('.torrent', dir=tempdir)
+ os.write(fd, upload)
+ os.close(fd)
+ filenames.append(fn)
+
+ log.debug('uploaded %d file(s)', len(filenames))
+
+ request.setHeader(b'content-type', b'text/html')
+ request.setResponseCode(http.OK)
+ return json.dumps({'success': bool(filenames), 'files': filenames}).encode(
+ 'utf8'
+ )
+
+
+class Render(resource.Resource):
+ def __init__(self):
+ resource.Resource.__init__(self)
+ # Make a list of all the template files to check requests against.
+ self.template_files = fnmatch.filter(os.listdir(rpath('render')), '*.html')
+
+ def getChild(self, path, request): # NOQA: N802
+ request.render_file = path
+ return EncodingResourceWrapper(self, [server.GzipEncoderFactory()])
+
+ def render(self, request):
+ log.debug('Render template file: %s', request.render_file)
+ if not hasattr(request, 'render_file'):
+ request.setResponseCode(http.INTERNAL_SERVER_ERROR)
+ return ''
+
+ request.setHeader(b'content-type', b'text/html')
+
+ tpl_file = request.render_file.decode()
+ if tpl_file in self.template_files:
+ request.setResponseCode(http.OK)
+ else:
+ request.setResponseCode(http.NOT_FOUND)
+ tpl_file = '404.html'
+
+ template = Template(filename=rpath(os.path.join('render', tpl_file)))
+ return template.render()
+
+
+class Tracker(resource.Resource):
+ def __init__(self):
+ resource.Resource.__init__(self)
+ try:
+ self.tracker_icons = component.get('TrackerIcons')
+ except KeyError:
+ self.tracker_icons = TrackerIcons()
+
+ def getChild(self, path, request): # NOQA: N802
+ request.tracker_name = path
+ return self
+
+ def on_got_icon(self, icon, request):
+ if icon:
+ request.setHeader(
+ b'cache-control', b'public, must-revalidate, max-age=86400'
+ )
+ request.setHeader(b'content-type', icon.get_mimetype().encode('utf8'))
+ request.setResponseCode(http.OK)
+ request.write(icon.get_data())
+ request.finish()
+ else:
+ request.setResponseCode(http.NOT_FOUND)
+ request.finish()
+
+ def render(self, request):
+ d = self.tracker_icons.fetch(request.tracker_name)
+ d.addCallback(self.on_got_icon, request)
+ return server.NOT_DONE_YET
+
+
+class Flag(resource.Resource):
+ def getChild(self, path, request): # NOQA: N802
+ request.country = path
+ return self
+
+ def render(self, request):
+ flag = request.country.decode('utf-8').lower() + '.png'
+ path = ('ui', 'data', 'pixmaps', 'flags', flag)
+ filename = common.resource_filename('deluge', os.path.join(*path))
+ if os.path.exists(filename):
+ request.setHeader(
+ b'cache-control', b'public, must-revalidate, max-age=86400'
+ )
+ request.setHeader(b'content-type', b'image/png')
+ with open(filename, 'rb') as _file:
+ data = _file.read()
+ request.setResponseCode(http.OK)
+ return data
+ else:
+ request.setResponseCode(http.NOT_FOUND)
+ return ''
+
+
+class LookupResource(resource.Resource, component.Component):
+ def __init__(self, name, *directories):
+ resource.Resource.__init__(self)
+ component.Component.__init__(self, name)
+
+ self.__paths = {}
+ for directory in directories:
+ self.add_directory(directory)
+
+ def add_directory(self, directory, path=''):
+ log.debug('Adding directory `%s` with path `%s`', directory, path)
+ paths = self.__paths.setdefault(path, [])
+ paths.append(directory)
+
+ def remove_directory(self, directory, path=''):
+ log.debug('Removing directory `%s`', directory)
+ self.__paths[path].remove(directory)
+
+ def getChild(self, path, request): # NOQA: N802
+ if hasattr(request, 'lookup_path'):
+ request.lookup_path = os.path.join(request.lookup_path, path)
+ else:
+ request.lookup_path = path
+
+ if request.uri.endswith(b'css'):
+ return EncodingResourceWrapper(self, [server.GzipEncoderFactory()])
+ else:
+ return self
+
+ def render(self, request):
+ log.debug('Requested path: %s', request.lookup_path)
+ path = os.path.dirname(request.lookup_path).decode()
+
+ if path in self.__paths:
+ filename = os.path.basename(request.path).decode()
+ for directory in self.__paths[path]:
+ path = os.path.join(directory, filename)
+ if os.path.isfile(path):
+ log.debug('Serving path: %s', path)
+ mime_type = mimetypes.guess_type(path)
+ request.setHeader(b'content-type', mime_type[0].encode())
+ with open(path, 'rb') as _file:
+ data = _file.read()
+ return data
+
+ request.setResponseCode(http.NOT_FOUND)
+ request.setHeader(b'content-type', b'text/html')
+ template = Template(filename=rpath(os.path.join('render', '404.html')))
+ return template.render()
+
+
+class ScriptResource(resource.Resource, component.Component):
+ def __init__(self):
+ resource.Resource.__init__(self)
+ component.Component.__init__(self, 'Scripts')
+ self.__scripts = {}
+ for script_type in ['normal', 'debug', 'dev']:
+ self.__scripts[script_type] = {
+ 'scripts': {},
+ 'order': [],
+ 'files_exist': True,
+ }
+
+ def has_script_type_files(self, script_type):
+ """Returns whether all the script files exist for this script type.
+
+ Args:
+ script_type (str): The script type to check (normal, debug, dev).
+
+ Returns:
+ bool: True if the files for this script type exist, otherwise False.
+
+ """
+ return self.__scripts[script_type]['files_exist']
+
+ def add_script(self, path, filepath, script_type=None):
+ """
+ Adds a script or scripts to the script resource.
+
+ :param path: The path of the script (this supports globbing)
+ :type path: string
+ :param filepath: The physical location of the script
+ :type filepath: string
+ :param script_type: The type of script to add (normal, debug, dev)
+ :param script_type: string
+ """
+ if script_type not in ('dev', 'debug', 'normal'):
+ script_type = 'normal'
+
+ self.__scripts[script_type]['scripts'][path] = filepath
+ self.__scripts[script_type]['order'].append(path)
+ if not os.path.isfile(filepath):
+ self.__scripts[script_type]['files_exist'] = False
+
+ def add_script_folder(self, path, filepath, script_type=None, recurse=True):
+ """
+ Adds a folder of scripts to the script resource.
+
+ :param path: The path of the folder
+ :type path: string
+ :param filepath: The physical location of the script
+ :type filepath: string
+ :param script_type: The type of script to add (normal, debug, dev)
+ :param script_type: string
+ :param recurse: Whether or not to recurse into other folders
+ :param recurse: bool
+ """
+ if script_type not in ('dev', 'debug', 'normal'):
+ script_type = 'normal'
+
+ self.__scripts[script_type]['scripts'][path] = (filepath, recurse)
+ self.__scripts[script_type]['order'].append(path)
+ if not os.path.isdir(filepath):
+ self.__scripts[script_type]['files_exist'] = False
+
+ def remove_script(self, path, script_type=None):
+ """
+ Removes a script or folder of scripts from the script resource.
+
+ :param path: The path of the folder
+ :type path: string
+ :param script_type: The type of script to add (normal, debug, dev)
+ :param script_type: string
+ """
+ if script_type not in ('dev', 'debug', 'normal'):
+ script_type = 'normal'
+
+ del self.__scripts[script_type]['scripts'][path]
+ self.__scripts[script_type]['order'].remove(path)
+
+ def get_scripts(self, script_type=None):
+ """
+ Returns a list of the scripts that can be used for producing
+ script tags.
+
+ :param script_type: The type of scripts to get (normal, debug, dev)
+ :param script_type: string
+ """
+ if script_type not in ('dev', 'debug', 'normal'):
+ script_type = 'normal'
+
+ _scripts = self.__scripts[script_type]['scripts']
+ _order = self.__scripts[script_type]['order']
+
+ scripts = []
+ for path in _order:
+ # Index for grouping the scripts when inserting.
+ script_idx = len(scripts)
+ # A folder resource is enclosed in a tuple.
+ if isinstance(_scripts[path], tuple):
+ filepath, recurse = _scripts[path]
+ for root, dirnames, filenames in os.walk(filepath):
+ dirnames.sort(reverse=True)
+ files = sorted(fnmatch.filter(filenames, '*.js'))
+
+ order_file = os.path.join(root, '.order')
+ if os.path.isfile(order_file):
+ with open(order_file, 'r') as _file:
+ for line in _file:
+ if line.startswith('+ '):
+ order_filename = line.split()[1]
+ files.pop(files.index(order_filename))
+ files.insert(0, order_filename)
+
+ # Ensure sub-directory scripts are top of list with root directory scripts bottom.
+ if dirnames:
+ scripts.extend(
+ ['js/' + os.path.basename(root) + '/' + f for f in files]
+ )
+ else:
+ dirpath = (
+ os.path.basename(os.path.dirname(root))
+ + '/'
+ + os.path.basename(root)
+ )
+ for filename in reversed(files):
+ scripts.insert(script_idx, 'js/' + dirpath + '/' + filename)
+
+ if not recurse:
+ break
+ else:
+ scripts.append('js/' + path)
+ return scripts
+
+ def getChild(self, path, request): # NOQA: N802
+ if hasattr(request, 'lookup_path'):
+ request.lookup_path += b'/' + path
+ else:
+ request.lookup_path = path
+ return EncodingResourceWrapper(self, [server.GzipEncoderFactory()])
+
+ def render(self, request):
+ log.debug('Requested path: %s', request.lookup_path)
+ lookup_path = request.lookup_path.decode()
+ for script_type in ('dev', 'debug', 'normal'):
+ scripts = self.__scripts[script_type]['scripts']
+ for pattern in scripts:
+ if not lookup_path.startswith(pattern):
+ continue
+
+ filepath = scripts[pattern]
+ if isinstance(filepath, tuple):
+ filepath = filepath[0]
+
+ path = filepath + lookup_path[len(pattern) :]
+
+ if not os.path.isfile(path):
+ continue
+
+ log.debug('Serving path: %s', path)
+ mime_type = mimetypes.guess_type(path)
+ request.setHeader(b'content-type', mime_type[0].encode())
+ with open(path, 'rb') as _file:
+ data = _file.read()
+ return data
+
+ request.setResponseCode(http.NOT_FOUND)
+ request.setHeader(b'content-type', b'text/html')
+ template = Template(filename=rpath(os.path.join('render', '404.html')))
+ return template.render()
+
+
+class Themes(static.File):
+ def getChild(self, path, request): # NOQA: N802
+ child = static.File.getChild(self, path, request)
+ if request.uri.endswith(b'css'):
+ return EncodingResourceWrapper(child, [server.GzipEncoderFactory()])
+ else:
+ return child
+
+
+class TopLevel(resource.Resource):
+
+ __stylesheets = [
+ 'css/ext-all-notheme.css',
+ 'css/ext-extensions.css',
+ 'css/deluge.css',
+ ]
+
+ def __init__(self):
+ resource.Resource.__init__(self)
+
+ self.putChild(b'css', LookupResource('Css', rpath('css')))
+ if os.path.isfile(rpath('js', 'gettext.js')):
+ self.putChild(
+ b'gettext.js',
+ EncodingResourceWrapper(GetText(), [server.GzipEncoderFactory()]),
+ )
+ else:
+ log.warning(
+ 'Cannot find "gettext.js" translation file!'
+ ' Text will only be available in English.'
+ )
+ self.putChild(b'gettext.js', MockGetText())
+ self.putChild(b'flag', Flag())
+ self.putChild(b'icons', LookupResource('Icons', rpath('icons')))
+ self.putChild(b'images', LookupResource('Images', rpath('images')))
+ self.putChild(
+ b'ui_images',
+ LookupResource(
+ 'UI_Images', common.resource_filename('deluge.ui.data', 'pixmaps')
+ ),
+ )
+
+ js = ScriptResource()
+
+ # configure the dev scripts
+ js.add_script(
+ 'ext-base-debug.js', rpath('js', 'extjs', 'ext-base-debug.js'), 'dev'
+ )
+ js.add_script(
+ 'ext-all-debug.js', rpath('js', 'extjs', 'ext-all-debug.js'), 'dev'
+ )
+ js.add_script_folder(
+ 'ext-extensions', rpath('js', 'extjs', 'ext-extensions'), 'dev'
+ )
+ js.add_script_folder('deluge-all', rpath('js', 'deluge-all'), 'dev')
+
+ # configure the debug scripts
+ js.add_script(
+ 'ext-base-debug.js', rpath('js', 'extjs', 'ext-base-debug.js'), 'debug'
+ )
+ js.add_script(
+ 'ext-all-debug.js', rpath('js', 'extjs', 'ext-all-debug.js'), 'debug'
+ )
+ js.add_script(
+ 'ext-extensions-debug.js',
+ rpath('js', 'extjs', 'ext-extensions-debug.js'),
+ 'debug',
+ )
+ js.add_script(
+ 'deluge-all-debug.js', rpath('js', 'deluge-all-debug.js'), 'debug'
+ )
+
+ # configure the normal scripts
+ js.add_script('ext-base.js', rpath('js', 'extjs', 'ext-base.js'))
+ js.add_script('ext-all.js', rpath('js', 'extjs', 'ext-all.js'))
+ js.add_script('ext-extensions.js', rpath('js', 'extjs', 'ext-extensions.js'))
+ js.add_script('deluge-all.js', rpath('js', 'deluge-all.js'))
+
+ self.js = js
+ self.putChild(b'js', js)
+ self.putChild(
+ b'json', EncodingResourceWrapper(JSON(), [server.GzipEncoderFactory()])
+ )
+ self.putChild(
+ b'upload', EncodingResourceWrapper(Upload(), [server.GzipEncoderFactory()])
+ )
+ self.putChild(b'render', Render())
+ self.putChild(b'themes', Themes(rpath('themes')))
+ self.putChild(b'tracker', Tracker())
+
+ theme = component.get('DelugeWeb').config['theme']
+ if not os.path.isfile(rpath('themes', 'css', 'xtheme-%s.css' % theme)):
+ theme = CONFIG_DEFAULTS.get('theme')
+ self.__stylesheets.insert(1, 'themes/css/xtheme-%s.css' % theme)
+
+ @property
+ def stylesheets(self):
+ return self.__stylesheets
+
+ def add_script(self, script):
+ """
+ Adds a script to the server so it is included in the <head> element
+ of the index page.
+
+ :param script: The path to the script
+ :type script: string
+ """
+
+ self.__scripts.append(script)
+ self.__debug_scripts.append(script)
+
+ def remove_script(self, script):
+ """
+ Removes a script from the server.
+
+ :param script: The path to the script
+ :type script: string
+ """
+ self.__scripts.remove(script)
+ self.__debug_scripts.remove(script)
+
+ def getChild(self, path, request): # NOQA: N802
+ if not path:
+ return self
+ else:
+ return resource.Resource.getChild(self, path, request)
+
+ def getChildWithDefault(self, path, request): # NOQA: N802
+ # Calculate the request base
+ header = request.getHeader(b'x-deluge-base')
+ base = header.decode('utf-8') if header else component.get('DelugeWeb').base
+
+ # validate the base parameter
+ if not base:
+ base = '/'
+
+ if base[0] != '/':
+ base = '/' + base
+
+ if base[-1] != '/':
+ base += '/'
+
+ request.base = base.encode('utf-8')
+
+ return resource.Resource.getChildWithDefault(self, path, request)
+
+ def render(self, request):
+ uri_true = ('true', 'yes', 'on', '1')
+ uri_false = ('false', 'no', 'off', '0')
+
+ debug_arg = None
+ req_dbg_arg = request.args.get('debug', [b''])[-1].decode().lower()
+ if req_dbg_arg in uri_true:
+ debug_arg = True
+ elif req_dbg_arg in uri_false:
+ debug_arg = False
+
+ dev_arg = request.args.get('dev', [b''])[-1].decode().lower() in uri_true
+ dev_ver = 'dev' in common.get_version()
+
+ script_type = 'normal'
+ if debug_arg is not None:
+ # Use debug arg to force switching to normal script type.
+ script_type = 'debug' if debug_arg else 'normal'
+ elif dev_arg or dev_ver:
+ # Also use dev files if development version.
+ script_type = 'dev'
+
+ if not self.js.has_script_type_files(script_type):
+ if not dev_ver:
+ log.warning(
+ 'Failed to enable WebUI "%s" mode, script files are missing!',
+ script_type,
+ )
+ # Fallback to checking other types in order and selecting first with
+ # files available. Ordered to start with dev files lookup.
+ for alt_script_type in [
+ x for x in ['dev', 'debug', 'normal'] if x != script_type
+ ]:
+ if self.js.has_script_type_files(alt_script_type):
+ script_type = alt_script_type
+ if not dev_ver:
+ log.warning('WebUI falling back to "%s" mode.', script_type)
+ break
+
+ scripts = component.get('Scripts').get_scripts(script_type)
+ scripts.insert(0, 'gettext.js')
+
+ template = Template(filename=rpath('index.html'))
+ request.setHeader(b'content-type', b'text/html; charset=utf-8')
+
+ web_config = component.get('Web').get_config()
+ web_config['base'] = request.base.decode()
+ config = {key: web_config[key] for key in UI_CONFIG_KEYS}
+ js_config = json.dumps(config)
+ # Insert the values into 'index.html' and return.
+ return template.render(
+ scripts=scripts,
+ stylesheets=self.stylesheets,
+ debug=str(bool(debug_arg)).lower(),
+ base=web_config['base'],
+ js_config=js_config,
+ )
+
+
+class DelugeWeb(component.Component):
+ def __init__(self, options=None, daemon=True):
+ """
+ Setup the DelugeWeb server.
+
+ Args:
+ options (argparse.Namespace): The web server options.
+ daemon (bool): If True run web server as a seperate daemon process (starts a twisted
+ reactor). If False shares the process and twisted reactor from WebUI plugin or tests.
+
+ """
+ component.Component.__init__(self, 'DelugeWeb', depend=['Web'])
+ self.config = configmanager.ConfigManager(
+ 'web.conf', defaults=CONFIG_DEFAULTS, file_version=2
+ )
+ self.config.run_converter((0, 1), 2, self._migrate_config_1_to_2)
+ self.config.register_set_function('language', self._on_language_changed)
+ self.socket = None
+ self.top_level = TopLevel()
+
+ self.interface = self.config['interface']
+ self.port = self.config['port']
+ self.https = self.config['https']
+ self.pkey = self.config['pkey']
+ self.cert = self.config['cert']
+ self.base = self.config['base']
+
+ if options:
+ self.interface = (
+ options.interface if options.interface is not None else self.interface
+ )
+ self.port = options.port if options.port else self.port
+ self.base = options.base if options.base else self.base
+ if options.ssl:
+ self.https = True
+ elif options.no_ssl:
+ self.https = False
+
+ if self.base != '/':
+ # Strip away slashes and serve on the base path as well as root path
+ self.top_level.putChild(self.base.strip('/'), self.top_level)
+
+ setup_translation()
+
+ # Remove twisted version number from 'server' http-header for security reasons
+ server.version = 'TwistedWeb'
+ self.site = server.Site(self.top_level)
+ self.web_api = WebApi()
+ self.web_utils = WebUtils()
+
+ self.auth = Auth(self.config)
+ self.daemon = daemon
+ # Initalize the plugins
+ self.plugins = PluginManager()
+
+ def _on_language_changed(self, key, value):
+ log.debug('Setting UI language %s', value)
+ set_language(value)
+
+ def install_signal_handlers(self):
+ # Since twisted assigns itself all the signals may as well make
+ # use of it.
+ reactor.addSystemEventTrigger('after', 'shutdown', self.shutdown)
+
+ # Twisted doesn't handle windows specific signals so we still
+ # need to attach to those to handle the close correctly.
+ if common.windows_check():
+ from win32api import SetConsoleCtrlHandler
+ from win32con import CTRL_CLOSE_EVENT, CTRL_SHUTDOWN_EVENT
+
+ def win_handler(ctrl_type):
+ log.debug('ctrl type: %s', ctrl_type)
+ if ctrl_type == CTRL_CLOSE_EVENT or ctrl_type == CTRL_SHUTDOWN_EVENT:
+ self.shutdown()
+ return 1
+
+ SetConsoleCtrlHandler(win_handler)
+
+ def start(self):
+ """
+ Start the DelugeWeb server
+ """
+ if self.socket:
+ log.warning('DelugeWeb is already running and cannot be started')
+ return
+
+ log.info('Starting webui server at PID %s', os.getpid())
+ if self.https:
+ self.start_ssl()
+ else:
+ self.start_normal()
+
+ component.get('Web').enable()
+
+ if self.daemon:
+ reactor.run()
+
+ def start_normal(self):
+ self.socket = reactor.listenTCP(self.port, self.site, interface=self.interface)
+ ip = self.socket.getHost().host
+ ip = '[%s]' % ip if is_ipv6(ip) else ip
+ log.info('Serving at http://%s:%s%s', ip, self.port, self.base)
+
+ def start_ssl(self):
+ check_ssl_keys()
+ log.debug('Enabling SSL with PKey: %s, Cert: %s', self.pkey, self.cert)
+
+ cert = configmanager.get_config_dir(self.cert)
+ pkey = configmanager.get_config_dir(self.pkey)
+
+ self.socket = reactor.listenSSL(
+ self.port,
+ self.site,
+ get_context_factory(cert, pkey),
+ interface=self.interface,
+ )
+ ip = self.socket.getHost().host
+ ip = '[%s]' % ip if is_ipv6(ip) else ip
+ log.info('Serving at https://%s:%s%s', ip, self.port, self.base)
+
+ def stop(self):
+ log.info('Shutting down webserver')
+ try:
+ component.get('Web').disable()
+ except KeyError:
+ pass
+
+ self.plugins.disable_plugins()
+ log.debug('Saving configuration file')
+ self.config.save()
+
+ if self.socket:
+ d = self.socket.stopListening()
+ self.socket = None
+ else:
+ d = defer.Deferred()
+ d.callback(False)
+ return d
+
+ def shutdown(self, *args):
+ self.stop()
+ if self.daemon and reactor.running:
+ reactor.stop()
+
+ def _migrate_config_1_to_2(self, config):
+ config['language'] = CONFIG_DEFAULTS['language']
+ return config
+
+
+if __name__ == '__builtin__':
+ deluge_web = DelugeWeb()
+ application = service.Application('DelugeWeb')
+ sc = service.IServiceCollection(application)
+ i = internet.TCPServer(deluge_web.port, deluge_web.site)
+ i.setServiceParent(sc)
+elif __name__ == '__main__':
+ deluge_web = DelugeWeb()
+ deluge_web.start()
diff --git a/deluge/ui/web/themes/css/xtheme-access.css b/deluge/ui/web/themes/css/xtheme-access.css
new file mode 100644
index 0000000..4ade3d9
--- /dev/null
+++ b/deluge/ui/web/themes/css/xtheme-access.css
@@ -0,0 +1,1933 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+body {
+ background-color: #16181a;
+ color: #fcfcfc;
+}
+
+.ext-el-mask {
+ background-color: #ccc;
+}
+
+.ext-el-mask-msg {
+ border-color: #223;
+ background-color: #3f4757;
+ background-image: url(../images/access/box/tb-blue.gif);
+}
+.ext-el-mask-msg div {
+ background-color: #232d38;
+ border-color: #556;
+ color: #fff;
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-mask-loading div {
+ background-color: #232d38;
+ background-image: url(../images/access/grid/loading.gif);
+}
+
+.x-item-disabled {
+ color: #ddd;
+}
+
+.x-item-disabled * {
+ color: #ddd !important;
+}
+
+.x-splitbar-proxy {
+ background-color: #aaa;
+}
+
+.x-color-palette a {
+ border-color: #fff;
+}
+
+.x-color-palette a:hover,
+.x-color-palette a.x-color-palette-sel {
+ border-color: #8bb8f3;
+ background-color: #deecfd;
+}
+
+.x-color-palette em {
+ border-color: #aca899;
+}
+
+.x-ie-shadow {
+ background-color: #777;
+}
+
+.x-shadow .xsmc {
+ background-image: url(../images/default/shadow-c.png);
+}
+
+.x-shadow .xsml,
+.x-shadow .xsmr {
+ background-image: url(../images/default/shadow-lr.png);
+}
+
+.x-shadow .xstl,
+.x-shadow .xstc,
+.x-shadow .xstr,
+.x-shadow .xsbl,
+.x-shadow .xsbc,
+.x-shadow .xsbr {
+ background-image: url(../images/default/shadow.png);
+}
+
+.loading-indicator {
+ font-size: 14px;
+ background-image: url(../images/access/grid/loading.gif);
+}
+
+.x-spotlight {
+ background-color: #ccc;
+}
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ background-color: #e18325;
+ border-color: #8db2e3;
+ overflow: hidden;
+ zoom: 1;
+}
+
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ border-color: #222;
+}
+
+ul.x-tab-strip-top {
+ background-color: #343843;
+ background-image: url(../images/access/tabs/tab-strip-bg.gif);
+ border-bottom-color: #343d4e;
+}
+
+ul.x-tab-strip-bottom {
+ background-color: #343843;
+ background-image: url(../images/access/tabs/tab-strip-btm-bg.gif);
+ border-top-color: #343843;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+ border-color: #222;
+ background-color: #e18325;
+}
+
+.x-tab-strip span.x-tab-strip-text {
+ font: normal 14px tahoma, arial, helvetica;
+ color: #fff;
+}
+
+.x-tab-strip-over span.x-tab-strip-text {
+ color: #fff;
+}
+
+.x-tab-strip-active span.x-tab-strip-text {
+ color: #fff;
+ font-weight: bold;
+}
+
+.x-tab-strip-disabled .x-tabs-text {
+ color: #aaaaaa;
+}
+
+.x-tab-strip-top .x-tab-right,
+.x-tab-strip-top .x-tab-left,
+.x-tab-strip-top .x-tab-strip-inner {
+ background-image: url(../images/access/tabs/tabs-sprite.gif);
+}
+
+.x-tab-strip-bottom .x-tab-right {
+ background-image: url(../images/access/tabs/tab-btm-inactive-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-left {
+ background-image: url(../images/access/tabs/tab-btm-inactive-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+ background-image: url(../images/access/tabs/tab-btm-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+ background-image: url(../images/access/tabs/tab-btm-left-bg.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ background-image: url(../images/access/tabs/tab-close.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover {
+ background-image: url(../images/access/tabs/tab-close.gif);
+}
+
+.x-tab-panel-body {
+ border-color: #18181a;
+ background-color: #fff;
+}
+
+.x-tab-panel-body-top {
+ border-top: 0 none;
+}
+
+.x-tab-panel-body-bottom {
+ border-bottom: 0 none;
+}
+
+.x-tab-scroller-left {
+ background-image: url(../images/access/tabs/scroll-left.gif);
+ border-bottom-color: #8db2e3;
+}
+
+.x-tab-scroller-left-over {
+ background-position: 0 0;
+}
+
+.x-tab-scroller-left-disabled {
+ background-position: -18px 0;
+ opacity: 0.5;
+ -moz-opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: default;
+}
+
+.x-tab-scroller-right {
+ background-image: url(../images/access/tabs/scroll-right.gif);
+ border-bottom-color: #8db2e3;
+}
+
+.x-tab-panel-bbar .x-toolbar,
+.x-tab-panel-tbar .x-toolbar {
+ border-color: #99bbe8;
+}
+.x-form-field {
+ font: normal 15px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-text,
+textarea.x-form-field {
+ color: #ffffff;
+ background-color: #33373d;
+ background-image: url(../images/access/form/text-bg.gif);
+ border-color: #737b8c;
+ border-width: 2px;
+}
+
+.ext-webkit .x-form-text,
+.ext-webkit textarea.x-form-field {
+ border-width: 2px;
+}
+
+.x-form-text,
+.ext-ie .x-form-file {
+ height: 26px;
+}
+
+.ext-strict .x-form-text {
+ height: 20px;
+}
+
+.x-form-select-one {
+ background-color: #fff;
+ border-color: #b5b8c8;
+}
+
+.x-form-check-group-label {
+ border-bottom: 1px solid #99bbe8;
+ color: #fff;
+}
+
+.x-editor .x-form-check-wrap {
+ background-color: #fff;
+}
+
+.x-form-field-wrap .x-form-trigger {
+ background-image: url(../images/access/form/trigger.gif);
+ border-bottom-color: #737b8c;
+ border-bottom-width: 2px;
+ height: 24px;
+ width: 20px;
+}
+
+.x-form-field-wrap .x-form-trigger.x-form-trigger-over {
+ border-bottom-color: #d97e27;
+}
+
+.x-form-field-wrap .x-form-trigger.x-form-trigger-click {
+ border-bottom-color: #c86e19;
+}
+
+.x-small-editor .x-form-field-wrap .x-form-trigger {
+ height: 24px;
+}
+
+.x-form-field-wrap .x-form-trigger-over {
+ background-position: -20px 0;
+}
+
+.x-form-field-wrap .x-form-trigger-click {
+ background-position: -40px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger {
+ background-position: -60px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger-over {
+ background-position: -80px 0;
+}
+
+.x-trigger-wrap-focus .x-form-trigger-click {
+ background-position: -100px 0;
+}
+
+.x-form-field-wrap .x-form-date-trigger {
+ background-image: url(../images/access/form/date-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-clear-trigger {
+ background-image: url(../images/access/form/clear-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-search-trigger {
+ background-image: url(../images/access/form/search-trigger.gif);
+}
+
+.x-trigger-wrap-focus .x-form-trigger {
+ border-bottom-color: #737b8c;
+}
+
+.x-item-disabled .x-form-trigger-over {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-item-disabled .x-form-trigger-click {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-form-focus,
+textarea.x-form-focus {
+ border-color: #ff9c33;
+}
+
+.x-form-invalid,
+textarea.x-form-invalid,
+.ext-webkit .x-form-invalid,
+.ext-webkit textarea.x-form-invalid {
+ background-color: #15171a;
+ background-image: url(../images/access/grid/invalid_line.gif);
+ border-color: #c30;
+}
+
+/*
+.ext-safari .x-form-invalid{
+ background-color:#fee;
+ border-color:#ff7870;
+}
+*/
+
+.x-form-inner-invalid,
+textarea.x-form-inner-invalid {
+ background-color: #fff;
+ background-image: url(../images/access/grid/invalid_line.gif);
+}
+
+.x-form-grow-sizer {
+ font: normal 15px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-item {
+ font: normal 15px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-invalid-msg {
+ color: #c0272b;
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+ background-image: url(../images/default/shared/warning.gif);
+}
+
+.x-form-empty-field {
+ color: #dadadd;
+}
+
+.x-small-editor .x-form-text {
+ height: 26px;
+}
+
+.x-small-editor .x-form-field {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.ext-safari .x-small-editor .x-form-field {
+ font: normal 15px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-form-invalid-icon {
+ background-image: url(../images/access/form/exclamation.gif);
+ height: 25px;
+ width: 19px;
+ background-position: center right;
+}
+
+.x-fieldset {
+ border-color: #737b8c;
+}
+
+.x-fieldset legend {
+ font: bold 14px tahoma, arial, helvetica, sans-serif;
+ color: #fff;
+}
+.x-btn {
+ font: normal 14px tahoma, verdana, helvetica;
+}
+
+.x-btn button {
+ font: normal 14px arial, tahoma, verdana, helvetica;
+ color: #fffffa;
+ padding-left: 6px !important;
+ padding-right: 6px !important;
+}
+
+.x-btn-over .x-btn button {
+ color: #fff;
+}
+
+.x-btn-noicon .x-btn-small .x-btn-text,
+.x-btn-text-icon .x-btn-icon-small-left .x-btn-text,
+.x-btn-icon .x-btn-small .x-btn-text,
+.x-btn-text-icon .x-btn-icon-small-right .x-btn-text {
+ height: 18px;
+}
+
+.x-btn-icon .x-btn-small .x-btn-text {
+ width: 18px;
+}
+
+.x-btn-text-icon .x-btn-icon-small-left .x-btn-text {
+ padding-left: 21px !important;
+}
+
+.x-btn-text-icon .x-btn-icon-small-right .x-btn-text {
+ padding-right: 21px !important;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text {
+ padding-left: 29px !important;
+}
+
+.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text {
+ padding-right: 29px !important;
+}
+
+.x-btn-text-icon .x-btn-icon-large-left .x-btn-text {
+ padding-left: 37px !important;
+}
+
+.x-btn-text-icon .x-btn-icon-large-right .x-btn-text {
+ padding-right: 37px !important;
+}
+
+.x-btn em {
+ font-style: normal;
+ font-weight: normal;
+}
+
+.x-btn-tl,
+.x-btn-tr,
+.x-btn-tc,
+.x-btn-ml,
+.x-btn-mr,
+.x-btn-mc,
+.x-btn-bl,
+.x-btn-br,
+.x-btn-bc {
+ background-image: url(../images/access/button/btn.gif);
+}
+
+.x-btn-click .x-btn-text,
+.x-btn-menu-active .x-btn-text,
+.x-btn-pressed .x-btn-text {
+ color: #fff;
+}
+
+.x-btn-disabled * {
+ color: #eee !important;
+}
+
+.x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/access/button/arrow.gif);
+ padding-right: 13px;
+}
+
+.x-btn-mc em.x-btn-split {
+ background-image: url(../images/access/button/s-arrow.gif);
+ padding-right: 20px;
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split,
+.x-btn-click .x-btn-mc em.x-btn-split,
+.x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/access/button/s-arrow-o.gif);
+}
+
+.x-btn-mc em.x-btn-arrow-bottom {
+ background-image: url(../images/access/button/s-arrow-b-noline.gif);
+}
+
+.x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/access/button/s-arrow-b.gif);
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/access/button/s-arrow-bo.gif);
+}
+
+.x-btn-group-header {
+ color: #d2d2d2;
+}
+
+.x-btn-group-tc {
+ background-image: url(../images/access/button/group-tb.gif);
+}
+
+.x-btn-group-tl {
+ background-image: url(../images/access/button/group-cs.gif);
+}
+
+.x-btn-group-tr {
+ background-image: url(../images/access/button/group-cs.gif);
+}
+
+.x-btn-group-bc {
+ background-image: url(../images/access/button/group-tb.gif);
+}
+
+.x-btn-group-bl {
+ background-image: url(../images/access/button/group-cs.gif);
+}
+
+.x-btn-group-br {
+ background-image: url(../images/access/button/group-cs.gif);
+}
+
+.x-btn-group-ml {
+ background-image: url(../images/access/button/group-lr.gif);
+}
+
+.x-btn-group-mr {
+ background-image: url(../images/access/button/group-lr.gif);
+}
+
+.x-btn-group-notitle .x-btn-group-tc {
+ background-image: url(../images/access/button/group-tb.gif);
+}
+.x-toolbar {
+ border-color: #18181a;
+ background-color: #393d4e;
+ background-image: url(../images/access/toolbar/bg.gif);
+}
+
+.x-toolbar td,
+.x-toolbar span,
+.x-toolbar input,
+.x-toolbar div,
+.x-toolbar select,
+.x-toolbar label {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-toolbar .x-item-disabled {
+ color: gray;
+}
+
+.x-toolbar .x-item-disabled * {
+ color: gray;
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split {
+ background-image: url(../images/access/button/s-arrow-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/access/button/s-arrow-o.gif);
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/access/button/s-arrow-b-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/access/button/s-arrow-bo.gif);
+}
+
+.x-toolbar .xtb-sep {
+ background-image: url(../images/access/grid/grid-blue-split.gif);
+}
+
+.x-toolbar .x-btn {
+ padding-left: 3px;
+ padding-right: 3px;
+}
+
+.x-toolbar .x-btn-mc em.x-btn-arrow {
+ padding-right: 10px;
+}
+
+.x-toolbar .x-btn-text-icon .x-btn-icon-small-left .x-btn-text {
+ padding-left: 18px !important;
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split {
+ padding-right: 14px;
+}
+
+.x-tbar-page-first {
+ background-image: url(../images/access/grid/page-first.gif) !important;
+}
+
+.x-tbar-loading {
+ background-image: url(../images/access/grid/refresh.gif) !important;
+}
+
+.x-tbar-page-last {
+ background-image: url(../images/access/grid/page-last.gif) !important;
+}
+
+.x-tbar-page-next {
+ background-image: url(../images/access/grid/page-next.gif) !important;
+}
+
+.x-tbar-page-prev {
+ background-image: url(../images/access/grid/page-prev.gif) !important;
+}
+
+.x-item-disabled .x-tbar-loading {
+ background-image: url(../images/access/grid/loading.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-first {
+ background-image: url(../images/access/grid/page-first-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-last {
+ background-image: url(../images/access/grid/page-last-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-next {
+ background-image: url(../images/access/grid/page-next-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-prev {
+ background-image: url(../images/access/grid/page-prev-disabled.gif) !important;
+}
+
+.x-paging-info {
+ color: #444;
+}
+
+.x-toolbar-more-icon {
+ background-image: url(../images/access/toolbar/more.gif) !important;
+}
+
+.x-statusbar .x-status-busy {
+ background-image: url(../images/access/grid/loading.gif);
+}
+
+.x-statusbar .x-status-text-panel {
+ border-color: #99bbe8 #fff #fff #99bbe8;
+}
+.x-resizable-handle {
+ background-color: #fff;
+ color: #000;
+}
+
+.x-resizable-over .x-resizable-handle-east,
+.x-resizable-pinned .x-resizable-handle-east,
+.x-resizable-over .x-resizable-handle-west,
+.x-resizable-pinned .x-resizable-handle-west {
+ background-image: url(../images/access/sizer/e-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-south,
+.x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/access/sizer/s-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/access/sizer/s-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southeast,
+.x-resizable-pinned .x-resizable-handle-southeast {
+ background-image: url(../images/access/sizer/se-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northwest,
+.x-resizable-pinned .x-resizable-handle-northwest {
+ background-image: url(../images/access/sizer/nw-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northeast,
+.x-resizable-pinned .x-resizable-handle-northeast {
+ background-image: url(../images/access/sizer/ne-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southwest,
+.x-resizable-pinned .x-resizable-handle-southwest {
+ background-image: url(../images/access/sizer/sw-handle.gif);
+}
+.x-resizable-proxy {
+ border-color: #3b5a82;
+}
+.x-resizable-overlay {
+ background-color: #fff;
+}
+.x-grid3 {
+ background-color: #1f2933;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+ border-color: #223;
+}
+
+.x-grid3-hd-row td,
+.x-grid3-row td,
+.x-grid3-summary-row td {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-hd-row td {
+ border-left-color: #556;
+ border-right-color: #223;
+}
+
+.x-grid-row-loading {
+ background-color: #fff;
+ background-image: url(../images/default/shared/loading-balls.gif);
+}
+
+.x-grid3-row {
+ border: 0 none;
+ border-bottom: 1px solid #111;
+ border-right: 1px solid #1a1a1c;
+}
+
+.x-grid3-row-alt {
+ background-color: #1b232b;
+}
+
+.x-grid3-row-over {
+ background-color: #7e5530;
+}
+
+.x-grid3-resize-proxy {
+ background-color: #777;
+}
+
+.x-grid3-resize-marker {
+ background-color: #777;
+}
+
+.x-grid3-header {
+ background-color: #3b3f50;
+ background-image: url(../images/access/grid/grid3-hrow.gif);
+}
+
+.x-grid3-header-pop {
+ border-left-color: #d0d0d0;
+}
+
+.x-grid3-header-pop-inner {
+ border-left-color: #eee;
+ background-image: url(../images/default/grid/hd-pop.gif);
+}
+
+td.x-grid3-hd-over,
+td.sort-desc,
+td.sort-asc,
+td.x-grid3-hd-menu-open {
+ border-left-color: #889;
+ border-right-color: #445;
+}
+
+td.x-grid3-hd-over .x-grid3-hd-inner,
+td.sort-desc .x-grid3-hd-inner,
+td.sort-asc .x-grid3-hd-inner,
+td.x-grid3-hd-menu-open .x-grid3-hd-inner {
+ background-color: #4e628a;
+ background-image: url(../images/access/grid/grid3-hrow-over.gif);
+}
+
+.x-grid3-cell-inner,
+.x-grid3-hd-inner {
+ color: #fff;
+}
+
+.sort-asc .x-grid3-sort-icon {
+ background-image: url(../images/access/grid/sort_asc.gif);
+ width: 15px;
+ height: 9px;
+ margin-left: 5px;
+}
+
+.sort-desc .x-grid3-sort-icon {
+ background-image: url(../images/access/grid/sort_desc.gif);
+ width: 15px;
+ height: 9px;
+ margin-left: 5px;
+}
+
+.x-grid3-cell-text,
+.x-grid3-hd-text {
+ color: #fff;
+}
+
+.x-grid3-split {
+ background-image: url(../images/default/grid/grid-split.gif);
+}
+
+.x-grid3-hd-text {
+ color: #fff;
+}
+
+.x-dd-drag-proxy .x-grid3-hd-inner {
+ background-color: #ebf3fd;
+ background-image: url(../images/access/grid/grid3-hrow-over.gif);
+ border-color: #aaccf6;
+}
+
+.col-move-top {
+ background-image: url(../images/default/grid/col-move-top.gif);
+}
+
+.col-move-bottom {
+ background-image: url(../images/default/grid/col-move-bottom.gif);
+}
+
+.x-grid3-row-selected {
+ background-color: #e5872c !important;
+ background-image: none;
+ border-style: solid;
+}
+
+.x-grid3-row-selected .x-grid3-cell {
+ color: #fff;
+}
+
+.x-grid3-cell-selected {
+ background-color: #ffa340 !important;
+ color: #fff;
+}
+
+.x-grid3-cell-selected span {
+ color: #fff !important;
+}
+
+.x-grid3-cell-selected .x-grid3-cell-text {
+ color: #fff;
+}
+
+.x-grid3-locked td.x-grid3-row-marker,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker {
+ background-color: #ebeadb !important;
+ background-image: url(../images/default/grid/grid-hrow.gif) !important;
+ color: #fff;
+ border-top-color: #fff;
+ border-right-color: #6fa0df !important;
+}
+
+.x-grid3-locked td.x-grid3-row-marker div,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div {
+ color: #fff !important;
+}
+
+.x-grid3-dirty-cell {
+ background-image: url(../images/access/grid/dirty.gif);
+}
+
+.x-grid3-topbar,
+.x-grid3-bottombar {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-bottombar .x-toolbar {
+ border-top-color: #a9bfd3;
+}
+
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner {
+ background-image: url(../images/access/grid/grid3-special-col-bg.gif) !important;
+ color: #fff !important;
+}
+.x-props-grid .x-grid3-td-value {
+ color: #fff !important;
+}
+
+.x-props-grid .x-grid3-body .x-grid3-td-name {
+ background-color: #263240 !important;
+ border-right-color: #223;
+}
+
+.xg-hmenu-sort-asc .x-menu-item-icon {
+ background-image: url(../images/access/grid/hmenu-asc.gif);
+}
+
+.xg-hmenu-sort-desc .x-menu-item-icon {
+ background-image: url(../images/access/grid/hmenu-desc.gif);
+}
+
+.xg-hmenu-lock .x-menu-item-icon {
+ background-image: url(../images/access/grid/hmenu-lock.gif);
+}
+
+.xg-hmenu-unlock .x-menu-item-icon {
+ background-image: url(../images/access/grid/hmenu-unlock.gif);
+}
+
+.x-grid3-hd-btn {
+ background-color: #c2c9d0;
+ background-image: url(../images/access/grid/grid3-hd-btn.gif);
+}
+
+.x-grid3-body .x-grid3-td-expander {
+ background-image: url(../images/access/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-expander {
+ background-image: url(../images/access/grid/row-expand-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-checker {
+ background-image: url(../images/access/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-checker,
+.x-grid3-hd-checker {
+ background-image: url(../images/default/grid/row-check-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer {
+ background-image: url(../images/access/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+ color: #fff;
+}
+
+.x-grid3-body .x-grid3-td-row-icon {
+ background-image: url(../images/access/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
+ background-image: url(../images/access/grid/grid3-special-col-sel-bg.gif);
+}
+
+.x-grid3-check-col {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-grid3-check-col-on {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-grid-group,
+.x-grid-group-body,
+.x-grid-group-hd {
+ zoom: 1;
+}
+
+.x-grid-group-hd {
+ border-bottom-color: #4e628a;
+}
+
+.x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/access/grid/group-collapse.gif);
+ background-position: 3px 6px;
+ color: #ffd;
+ font: bold 14px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/access/grid/group-expand.gif);
+}
+
+.x-group-by-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-cols-icon {
+ background-image: url(../images/default/grid/columns.gif);
+}
+
+.x-show-groups-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-grid-empty {
+ color: gray;
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+ border-right-color: #ededed;
+}
+
+.x-grid-with-col-lines .x-grid3-row {
+ border-top-color: #ededed;
+}
+
+.x-grid-with-col-lines .x-grid3-row-selected {
+ border-top-color: #a3bae9;
+}
+.x-dd-drag-ghost {
+ color: #000;
+ font: normal 14px arial, helvetica, sans-serif;
+ border-color: #ddd #bbb #bbb #ddd;
+ background-color: #fff;
+}
+
+.x-dd-drop-nodrop .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-no.gif);
+}
+
+.x-dd-drop-ok .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-yes.gif);
+}
+
+.x-dd-drop-ok-add .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-add.gif);
+}
+
+.x-view-selector {
+ background-color: #c3daf9;
+ border-color: #3399bb;
+}
+.x-tree-node-expanded .x-tree-node-icon {
+ background-image: url(../images/access/tree/folder-open.gif);
+}
+
+.x-tree-node-leaf .x-tree-node-icon {
+ background-image: url(../images/default/tree/leaf.gif);
+}
+
+.x-tree-node-collapsed .x-tree-node-icon {
+ background-image: url(../images/access/tree/folder.gif);
+}
+
+.x-tree-node-loading .x-tree-node-icon {
+ background-image: url(../images/default/tree/loading.gif) !important;
+}
+
+.x-tree-node .x-tree-node-inline-icon {
+ background-image: none;
+}
+
+.x-tree-node-loading a span {
+ font-style: italic;
+ color: #444444;
+}
+
+.ext-ie .x-tree-node-el input {
+ width: 14px;
+ height: 14px;
+}
+
+.x-tree-lines .x-tree-elbow {
+ background-image: url(../images/access/tree/elbow.gif);
+}
+
+.x-tree-lines .x-tree-elbow-plus {
+ background-image: url(../images/access/tree/elbow-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-minus {
+ background-image: url(../images/access/tree/elbow-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end {
+ background-image: url(../images/access/tree/elbow-end.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/access/tree/elbow-end-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/access/tree/elbow-end-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-line {
+ background-image: url(../images/access/tree/elbow-line.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-plus {
+ background-image: url(../images/access/tree/elbow-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-minus {
+ background-image: url(../images/access/tree/elbow-minus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/access/tree/elbow-end-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/access/tree/elbow-end-minus-nl.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-plus {
+ background-image: url(../images/access/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-minus {
+ background-image: url(../images/access/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-plus {
+ background-image: url(../images/access/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-minus {
+ background-image: url(../images/access/tree/arrows.gif);
+}
+
+.x-tree-node {
+ color: #000;
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-tree-node a,
+.x-dd-drag-ghost a {
+ color: #fff;
+}
+
+.x-tree-node a span,
+.x-dd-drag-ghost a span {
+ color: #fff;
+}
+
+.x-tree-node .x-tree-selected a,
+.x-dd-drag-ghost a {
+ color: #fff;
+}
+
+.x-tree-node .x-tree-selected a span,
+.x-dd-drag-ghost a span {
+ color: #fff;
+}
+
+.x-tree-node .x-tree-node-disabled a span {
+ color: gray !important;
+}
+
+.x-tree-node div.x-tree-drag-insert-below {
+ border-bottom-color: #36c;
+}
+
+.x-tree-node div.x-tree-drag-insert-above {
+ border-top-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a {
+ border-bottom-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a {
+ border-top-color: #36c;
+}
+
+.x-tree-node .x-tree-drag-append a span {
+ background-color: #ddd;
+ border-color: gray;
+}
+
+.x-tree-node .x-tree-node-over {
+ background-color: #7e5530;
+}
+
+.x-tree-node .x-tree-selected {
+ background-color: #e5872c;
+}
+
+.x-tree-drop-ok-append .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-add.gif);
+}
+
+.x-tree-drop-ok-above .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-over.gif);
+}
+
+.x-tree-drop-ok-below .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-under.gif);
+}
+
+.x-tree-drop-ok-between .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-between.gif);
+}
+.x-date-picker {
+ border-color: #737b8c;
+ background-color: #21252e;
+}
+
+.x-date-middle,
+.x-date-left,
+.x-date-right {
+ background-image: url(../images/access/shared/hd-sprite.gif);
+ color: #fff;
+ font: bold 14px 'sans serif', tahoma, verdana, helvetica;
+}
+
+.x-date-middle .x-btn .x-btn-text {
+ color: #fff;
+}
+
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/access/toolbar/btn-arrow-light.gif);
+}
+
+.x-date-right a {
+ background-image: url(../images/access/shared/right-btn.gif);
+}
+
+.x-date-left a {
+ background-image: url(../images/access/shared/left-btn.gif);
+}
+
+.x-date-inner th {
+ background-color: #363d4a;
+ background-image: url(../images/access/toolbar/bg.gif);
+ border-bottom-color: #535b5c;
+ font: normal 13px arial, helvetica, tahoma, sans-serif;
+ color: #fff;
+}
+
+.x-date-inner td {
+ border-color: #112;
+}
+
+.x-date-inner a {
+ font: normal 14px arial, helvetica, tahoma, sans-serif;
+ color: #fff;
+ padding: 2px 7px 1px 3px; /* Structure to account for larger, bolder fonts in Access theme. */
+}
+
+.x-date-inner .x-date-active {
+ color: #000;
+}
+
+.x-date-inner .x-date-selected a {
+ background-color: #e5872c;
+ background-image: none;
+ border-color: #864900;
+ padding: 1px 6px 1px 2px; /* Structure to account for larger, bolder fonts in Access theme. */
+}
+
+.x-date-inner .x-date-today a {
+ border-color: #99a;
+}
+
+.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: #aaa;
+}
+
+.x-date-bottom {
+ border-top-color: #737b8c;
+ background-color: #464d5a;
+ background-image: url(../images/access/shared/glass-bg.gif);
+}
+
+.x-date-inner a:hover,
+.x-date-inner .x-date-disabled a:hover {
+ color: #fff;
+ background-color: #7e5530;
+}
+
+.x-date-inner .x-date-disabled a {
+ background-color: #eee;
+ color: #bbb;
+}
+
+.x-date-mmenu {
+ background-color: #eee !important;
+}
+
+.x-date-mmenu .x-menu-item {
+ font-size: 13px;
+ color: #000;
+}
+
+.x-date-mp {
+ background-color: #21252e;
+}
+
+.x-date-mp td {
+ font: normal 14px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns button {
+ background-color: #083772;
+ color: #fff;
+ border-color: #3366cc #000055 #000055 #3366cc;
+ font: normal 14px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns {
+ background-color: #dfecfb;
+ background-image: url(../images/access/shared/glass-bg.gif);
+}
+
+.x-date-mp-btns td {
+ border-top-color: #c5d2df;
+}
+
+td.x-date-mp-month a,
+td.x-date-mp-year a {
+ color: #fff;
+}
+
+td.x-date-mp-month a:hover,
+td.x-date-mp-year a:hover {
+ color: #fff;
+ background-color: #7e5530;
+}
+
+td.x-date-mp-sel a {
+ background-color: #e5872c;
+ background-image: none;
+ border-color: #864900;
+}
+
+.x-date-mp-ybtn a {
+ background-image: url(../images/access/panel/tool-sprites.gif);
+}
+
+td.x-date-mp-sep {
+ border-right-color: #c5d2df;
+}
+.x-tip .x-tip-close {
+ background-image: url(../images/access/qtip/close.gif);
+}
+
+.x-tip .x-tip-tc,
+.x-tip .x-tip-tl,
+.x-tip .x-tip-tr,
+.x-tip .x-tip-bc,
+.x-tip .x-tip-bl,
+.x-tip .x-tip-br,
+.x-tip .x-tip-ml,
+.x-tip .x-tip-mr {
+ background-image: url(../images/access/qtip/tip-sprite.gif);
+}
+
+.x-tip .x-tip-mc {
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+}
+.x-tip .x-tip-ml {
+ background-color: #fff;
+}
+
+.x-tip .x-tip-header-text {
+ font: bold 14px tahoma, arial, helvetica, sans-serif;
+ color: #ffd;
+}
+
+.x-tip .x-tip-body {
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+ color: #000;
+}
+
+.x-form-invalid-tip .x-tip-tc,
+.x-form-invalid-tip .x-tip-tl,
+.x-form-invalid-tip .x-tip-tr,
+.x-form-invalid-tip .x-tip-bc,
+.x-form-invalid-tip .x-tip-bl,
+.x-form-invalid-tip .x-tip-br,
+.x-form-invalid-tip .x-tip-ml,
+.x-form-invalid-tip .x-tip-mr {
+ background-image: url(../images/default/form/error-tip-corners.gif);
+}
+
+.x-form-invalid-tip .x-tip-body {
+ background-image: url(../images/access/form/exclamation.gif);
+}
+
+.x-tip-anchor {
+ background-image: url(../images/access/qtip/tip-anchor-sprite.gif);
+}
+.x-menu {
+ border-color: #222;
+ background-color: #414551;
+ background-image: url(../images/access/menu/menu.gif);
+}
+
+.x-menu-nosep {
+ background-image: none;
+}
+
+.x-menu-list-item {
+ font: normal 14px tahoma, arial, sans-serif;
+}
+
+.x-menu-item-arrow {
+ background-image: url(../images/access/menu/menu-parent.gif);
+}
+
+.x-menu-sep {
+ background-color: #223;
+ border-bottom-color: #666;
+}
+
+a.x-menu-item {
+ color: #fffff6;
+}
+
+.x-menu-item-active {
+ background-color: #f09134;
+ background-image: none;
+ border-color: #b36427;
+}
+
+.x-menu-item-active a.x-menu-item {
+ border-color: #b36427;
+}
+
+.x-menu-check-item .x-menu-item-icon {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-menu-item-checked .x-menu-item-icon {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon {
+ background-image: url(../images/access/menu/group-checked.gif);
+}
+
+.x-menu-group-item .x-menu-item-icon {
+ background-image: none;
+}
+
+.x-menu-plain {
+ background-color: #fff !important;
+}
+
+.x-menu .x-date-picker {
+ border-color: #a3bad9;
+}
+
+.x-cycle-menu .x-menu-item-checked {
+ border-color: #a3bae9 !important;
+ background-color: #def8f6;
+}
+
+.x-menu-scroller-top {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+
+.x-menu-scroller-bottom {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+.x-box-tl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-tc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-tr {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-ml {
+ background-image: url(../images/default/box/l.gif);
+}
+
+.x-box-mc {
+ background-color: #eee;
+ background-image: url(../images/default/box/tb.gif);
+ font-family: 'Myriad Pro', 'Myriad Web', 'Tahoma', 'Helvetica', 'Arial',
+ sans-serif;
+ color: #393939;
+ font-size: 15px;
+}
+
+.x-box-mc h3 {
+ font-size: 18px;
+ font-weight: bold;
+}
+
+.x-box-mr {
+ background-image: url(../images/default/box/r.gif);
+}
+
+.x-box-bl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-bc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-br {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.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(../images/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(../images/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(../images/default/box/l-blue.gif);
+}
+
+.x-box-blue .x-box-mr {
+ background-image: url(../images/default/box/r-blue.gif);
+}
+.x-combo-list {
+ border: 2px solid #232732;
+ background-color: #555566;
+ font: normal 15px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-combo-list-inner {
+ background-color: #414551;
+}
+
+.x-combo-list-hd {
+ font: bold 14px tahoma, arial, helvetica, sans-serif;
+ color: #fff;
+ background-image: url(../images/default/layout/panel-title-light-bg.gif);
+ border-bottom-color: #98c0f4;
+}
+
+.x-resizable-pinned .x-combo-list-inner {
+ border-bottom-color: #98c0f4;
+}
+
+.x-combo-list-item {
+ border-color: #556;
+}
+
+.x-combo-list .x-combo-selected {
+ border-color: #e5872c !important;
+ background-color: #e5872c;
+}
+
+.x-combo-list .x-toolbar {
+ border-top-color: #98c0f4;
+}
+
+.x-combo-list-small {
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+}
+.x-panel {
+ border-color: #18181a;
+ font-size: 14px;
+}
+
+.x-panel-header {
+ color: #fff;
+ font-weight: bold;
+ font-size: 14px;
+ font-family: tahoma, arial, verdana, sans-serif;
+ border-color: #18181a;
+ background-image: url(../images/access/panel/white-top-bottom.gif);
+}
+
+.x-panel-body {
+ color: #fffff6;
+ border-color: #18181a;
+ background-color: #232d38;
+}
+
+.x-tab-panel .x-panel-body {
+ color: #fffff6;
+ border-color: #18181a;
+ background-color: #1f2730;
+}
+
+.x-panel-bbar .x-toolbar,
+.x-panel-tbar .x-toolbar {
+ border-color: #223;
+}
+
+.x-panel-tbar-noheader .x-toolbar,
+.x-panel-mc .x-panel-tbar .x-toolbar {
+ border-top-color: #223;
+}
+
+.x-panel-body-noheader,
+.x-panel-mc .x-panel-body {
+ border-top-color: #223;
+}
+
+.x-panel-tl .x-panel-header {
+ color: #fff;
+ font: bold 14px tahoma, arial, verdana, sans-serif;
+}
+
+.x-panel-tc {
+ background-image: url(../images/access/panel/top-bottom.gif);
+}
+
+.x-panel-tl,
+.x-panel-tr,
+.x-panel-bl,
+.x-panel-br {
+ background-image: url(../images/access/panel/corners-sprite.gif);
+ border-bottom-color: #222224;
+}
+
+.x-panel-bc {
+ background-image: url(../images/access/panel/top-bottom.gif);
+}
+
+.x-panel-mc {
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+ background-color: #3f4757;
+}
+
+.x-panel-ml {
+ background-image: url(../images/access/panel/left-right.gif);
+}
+
+.x-panel-mr {
+ background-image: url(../images/access/panel/left-right.gif);
+}
+
+.x-tool {
+ background-image: url(../images/access/panel/tool-sprites.gif);
+}
+
+.x-panel-ghost {
+ background-color: #3f4757;
+}
+
+.x-panel-ghost ul {
+ border-color: #18181a;
+}
+
+.x-panel-dd-spacer {
+ border-color: #18181a;
+}
+
+.x-panel-fbar td,
+.x-panel-fbar span,
+.x-panel-fbar input,
+.x-panel-fbar div,
+.x-panel-fbar select,
+.x-panel-fbar label {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+.x-window-proxy {
+ background-color: #1f2833;
+ border-color: #18181a;
+}
+
+.x-window-tl .x-window-header {
+ color: #fff;
+ font: bold 14px tahoma, arial, verdana, sans-serif;
+}
+
+.x-window-tc {
+ background-image: url(../images/access/window/top-bottom.png);
+}
+
+.x-window-tl {
+ background-image: url(../images/access/window/left-corners.png);
+}
+
+.x-window-tr {
+ background-image: url(../images/access/window/right-corners.png);
+}
+
+.x-window-bc {
+ background-image: url(../images/access/window/top-bottom.png);
+}
+
+.x-window-bl {
+ background-image: url(../images/access/window/left-corners.png);
+}
+
+.x-window-br {
+ background-image: url(../images/access/window/right-corners.png);
+}
+
+.x-window-mc {
+ border-color: #18181a;
+ font: normal 14px tahoma, arial, helvetica, sans-serif;
+ background-color: #1f2833;
+}
+
+.x-window-ml {
+ background-image: url(../images/access/window/left-right.png);
+}
+
+.x-window-mr {
+ background-image: url(../images/access/window/left-right.png);
+}
+
+.x-window-maximized .x-window-tc {
+ background-color: #fff;
+}
+
+.x-window-bbar .x-toolbar {
+ border-top-color: #323945;
+}
+
+.x-panel-ghost .x-window-tl {
+ border-bottom-color: #323945;
+}
+
+.x-panel-collapsed .x-window-tl {
+ border-bottom-color: #323945;
+}
+
+.x-dlg-mask {
+ background-color: #ccc;
+}
+
+.x-window-plain .x-window-mc {
+ background-color: #464f61;
+ border-color: #636778;
+}
+
+.x-window-plain .x-window-body {
+ color: #fffff6;
+ border-color: #464f61;
+}
+
+body.x-body-masked .x-window-plain .x-window-mc {
+ background-color: #464f61;
+}
+.x-html-editor-wrap {
+ border-color: #737b8c;
+ background-color: #fff;
+}
+.x-html-editor-wrap iframe {
+ background-color: #fff;
+}
+.x-html-editor-tb .x-btn-text {
+ background-image: url(../images/access/editor/tb-sprite.gif);
+}
+.x-panel-noborder .x-panel-header-noborder {
+ border-bottom-color: #343d4e;
+}
+
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #343d4e;
+}
+
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+ border-top-color: #343d4e;
+}
+
+.x-tab-panel-bbar-noborder .x-toolbar {
+ border-top-color: #343d4e;
+}
+
+.x-tab-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #343d4e;
+}
+.x-border-layout-ct {
+ background-color: #3f4757;
+}
+
+.x-accordion-hd {
+ color: #fff;
+ font-weight: normal;
+ background-image: url(../images/access/panel/light-hd.gif);
+}
+
+.x-layout-collapsed {
+ background-color: #323845;
+ border-color: #1a1a1c;
+}
+
+.x-layout-collapsed-over {
+ background-color: #2d3440;
+}
+
+.x-layout-split-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+
+.x-layout-split-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+
+.x-layout-split-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+
+.x-layout-split-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+
+.x-layout-cmini-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+
+.x-layout-cmini-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+.x-progress-wrap {
+ border-color: #18181a;
+}
+
+.x-progress-inner {
+ background-color: #232d38;
+ background-image: none;
+}
+
+.x-progress-bar {
+ background-color: #f39a00;
+ background-image: url(../images/access/progress/progress-bg.gif);
+ border-top-color: #a66900;
+ border-bottom-color: #a66900;
+ border-right-color: #ffb941;
+ height: 20px !important; /* structural override for Accessibility Theme */
+}
+
+.x-progress-text {
+ font-size: 14px;
+ font-weight: bold;
+ color: #fff;
+ padding: 0 5px !important; /* structural override for Accessibility Theme */
+}
+
+.x-progress-text-back {
+ color: #aaa;
+ line-height: 19px;
+}
+.x-list-header {
+ background-color: #393d4e;
+ background-image: url(../images/access/toolbar/bg.gif);
+ background-position: 0 top;
+}
+
+.x-list-header-inner div em {
+ border-left-color: #667;
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+ line-height: 14px;
+}
+
+.x-list-body-inner {
+ background-color: #1b232b;
+}
+
+.x-list-body dt em {
+ font: normal 14px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-list-over {
+ background-color: #7e5530;
+}
+
+.x-list-selected {
+ background-color: #e5872c;
+}
+
+.x-list-resizer {
+ border-left-color: #555;
+ border-right-color: #555;
+}
+
+.x-list-header-inner em.sort-asc,
+.x-list-header-inner em.sort-desc {
+ background-image: url(../images/access/grid/sort-hd.gif);
+ border-color: #3e4e6c;
+}
+.x-slider-horz,
+.x-slider-horz .x-slider-end,
+.x-slider-horz .x-slider-inner {
+ background-image: url(../images/access/slider/slider-bg.png);
+}
+
+.x-slider-horz .x-slider-thumb {
+ background-image: url(../images/access/slider/slider-thumb.png);
+}
+
+.x-slider-vert,
+.x-slider-vert .x-slider-end,
+.x-slider-vert .x-slider-inner {
+ background-image: url(../images/access/slider/slider-v-bg.png);
+}
+
+.x-slider-vert .x-slider-thumb {
+ background-image: url(../images/access/slider/slider-v-thumb.png);
+}
+.x-window-dlg .ext-mb-text,
+.x-window-dlg .x-window-header-text {
+ font-size: 15px;
+}
+
+.x-window-dlg .ext-mb-textarea {
+ font: normal 15px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-window-dlg .x-msg-box-wait {
+ background-image: url(../images/access/grid/loading.gif);
+}
+
+.x-window-dlg .ext-mb-info {
+ background-image: url(../images/access/window/icon-info.gif);
+}
+
+.x-window-dlg .ext-mb-warning {
+ background-image: url(../images/access/window/icon-warning.gif);
+}
+
+.x-window-dlg .ext-mb-question {
+ background-image: url(../images/access/window/icon-question.gif);
+}
+
+.x-window-dlg .ext-mb-error {
+ background-image: url(../images/access/window/icon-error.gif);
+}
diff --git a/deluge/ui/web/themes/css/xtheme-blue.css b/deluge/ui/web/themes/css/xtheme-blue.css
new file mode 100644
index 0000000..c2131cf
--- /dev/null
+++ b/deluge/ui/web/themes/css/xtheme-blue.css
@@ -0,0 +1,1793 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+.ext-el-mask {
+ background-color: #ccc;
+}
+
+.ext-el-mask-msg {
+ border-color: #6593cf;
+ background-color: #c3daf9;
+ background-image: url(../images/default/box/tb-blue.gif);
+}
+.ext-el-mask-msg div {
+ background-color: #eee;
+ border-color: #a3bad9;
+ color: #222;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-mask-loading div {
+ background-color: #fbfbfb;
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-item-disabled {
+ color: gray;
+}
+
+.x-item-disabled * {
+ color: gray !important;
+}
+
+.x-splitbar-proxy {
+ background-color: #aaa;
+}
+
+.x-color-palette a {
+ border-color: #fff;
+}
+
+.x-color-palette a:hover,
+.x-color-palette a.x-color-palette-sel {
+ border-color: #8bb8f3;
+ background-color: #deecfd;
+}
+
+/*
+.x-color-palette em:hover, .x-color-palette span:hover{
+ background-color: #deecfd;
+}
+*/
+
+.x-color-palette em {
+ border-color: #aca899;
+}
+
+.x-ie-shadow {
+ background-color: #777;
+}
+
+.x-shadow .xsmc {
+ background-image: url(../images/default/shadow-c.png);
+}
+
+.x-shadow .xsml,
+.x-shadow .xsmr {
+ background-image: url(../images/default/shadow-lr.png);
+}
+
+.x-shadow .xstl,
+.x-shadow .xstc,
+.x-shadow .xstr,
+.x-shadow .xsbl,
+.x-shadow .xsbc,
+.x-shadow .xsbr {
+ background-image: url(../images/default/shadow.png);
+}
+
+.loading-indicator {
+ font-size: 11px;
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-spotlight {
+ background-color: #ccc;
+}
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ background-color: #deecfd;
+ border-color: #8db2e3;
+ overflow: hidden;
+ zoom: 1;
+}
+
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ border-color: #8db2e3;
+}
+
+ul.x-tab-strip-top {
+ background-color: #cedff5;
+ background-image: url(../images/default/tabs/tab-strip-bg.gif);
+ border-bottom-color: #8db2e3;
+}
+
+ul.x-tab-strip-bottom {
+ background-color: #cedff5;
+ background-image: url(../images/default/tabs/tab-strip-btm-bg.gif);
+ border-top-color: #8db2e3;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+ border-color: #8db2e3;
+ background-color: #deecfd;
+}
+
+.x-tab-strip span.x-tab-strip-text {
+ font: normal 11px tahoma, arial, helvetica;
+ color: #416aa3;
+}
+
+.x-tab-strip-over span.x-tab-strip-text {
+ color: #15428b;
+}
+
+.x-tab-strip-active span.x-tab-strip-text {
+ color: #15428b;
+ font-weight: bold;
+}
+
+.x-tab-strip-disabled .x-tabs-text {
+ color: #aaaaaa;
+}
+
+.x-tab-strip-top .x-tab-right,
+.x-tab-strip-top .x-tab-left,
+.x-tab-strip-top .x-tab-strip-inner {
+ background-image: url(../images/default/tabs/tabs-sprite.gif);
+}
+
+.x-tab-strip-bottom .x-tab-right {
+ background-image: url(../images/default/tabs/tab-btm-inactive-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-left {
+ background-image: url(../images/default/tabs/tab-btm-inactive-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-over .x-tab-right {
+ background-image: url(../images/default/tabs/tab-btm-over-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-over .x-tab-left {
+ background-image: url(../images/default/tabs/tab-btm-over-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+ background-image: url(../images/default/tabs/tab-btm-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+ background-image: url(../images/default/tabs/tab-btm-left-bg.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ background-image: url(../images/default/tabs/tab-close.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover {
+ background-image: url(../images/default/tabs/tab-close.gif);
+}
+
+.x-tab-panel-body {
+ border-color: #8db2e3;
+ background-color: #fff;
+}
+
+.x-tab-panel-body-top {
+ border-top: 0 none;
+}
+
+.x-tab-panel-body-bottom {
+ border-bottom: 0 none;
+}
+
+.x-tab-scroller-left {
+ background-image: url(../images/default/tabs/scroll-left.gif);
+ border-bottom-color: #8db2e3;
+}
+
+.x-tab-scroller-left-over {
+ background-position: 0 0;
+}
+
+.x-tab-scroller-left-disabled {
+ background-position: -18px 0;
+ opacity: 0.5;
+ -moz-opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: default;
+}
+
+.x-tab-scroller-right {
+ background-image: url(../images/default/tabs/scroll-right.gif);
+ border-bottom-color: #8db2e3;
+}
+
+.x-tab-panel-bbar .x-toolbar,
+.x-tab-panel-tbar .x-toolbar {
+ border-color: #99bbe8;
+}
+.x-form-field {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-text,
+textarea.x-form-field {
+ background-color: #fff;
+ background-image: url(../images/default/form/text-bg.gif);
+ border-color: #b5b8c8;
+}
+
+.x-form-select-one {
+ background-color: #fff;
+ border-color: #b5b8c8;
+}
+
+.x-form-check-group-label {
+ border-bottom: 1px solid #99bbe8;
+ color: #15428b;
+}
+
+.x-editor .x-form-check-wrap {
+ background-color: #fff;
+}
+
+.x-form-field-wrap .x-form-trigger {
+ background-image: url(../images/default/form/trigger.gif);
+ border-bottom-color: #b5b8c8;
+}
+
+.x-form-field-wrap .x-form-date-trigger {
+ background-image: url(../images/default/form/date-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-clear-trigger {
+ background-image: url(../images/default/form/clear-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-search-trigger {
+ background-image: url(../images/default/form/search-trigger.gif);
+}
+
+.x-trigger-wrap-focus .x-form-trigger {
+ border-bottom-color: #7eadd9;
+}
+
+.x-item-disabled .x-form-trigger-over {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-item-disabled .x-form-trigger-click {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-form-focus,
+textarea.x-form-focus {
+ border-color: #7eadd9;
+}
+
+.x-form-invalid,
+textarea.x-form-invalid {
+ background-color: #fff;
+ background-image: url(../images/default/grid/invalid_line.gif);
+ border-color: #c30;
+}
+
+.x-form-invalid.x-form-composite {
+ border: none;
+ background-image: none;
+}
+
+.x-form-invalid.x-form-composite .x-form-invalid {
+ background-color: #fff;
+ background-image: url(../images/default/grid/invalid_line.gif);
+ border-color: #c30;
+}
+
+.x-form-inner-invalid,
+textarea.x-form-inner-invalid {
+ background-color: #fff;
+ background-image: url(../images/default/grid/invalid_line.gif);
+}
+
+.x-form-grow-sizer {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-item {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-invalid-msg {
+ color: #c0272b;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-image: url(../images/default/shared/warning.gif);
+}
+
+.x-form-empty-field {
+ color: gray;
+}
+
+.x-small-editor .x-form-field {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.ext-webkit .x-small-editor .x-form-field {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-form-invalid-icon {
+ background-image: url(../images/default/form/exclamation.gif);
+}
+
+.x-fieldset {
+ border-color: #b5b8c8;
+}
+
+.x-fieldset legend {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #15428b;
+}
+.x-btn {
+ font: normal 11px tahoma, verdana, helvetica;
+}
+
+.x-btn button {
+ font: normal 11px arial, tahoma, verdana, helvetica;
+ color: #333;
+}
+
+.x-btn em {
+ font-style: normal;
+ font-weight: normal;
+}
+
+.x-btn-tl,
+.x-btn-tr,
+.x-btn-tc,
+.x-btn-ml,
+.x-btn-mr,
+.x-btn-mc,
+.x-btn-bl,
+.x-btn-br,
+.x-btn-bc {
+ background-image: url(../images/default/button/btn.gif);
+}
+
+.x-btn-click .x-btn-text,
+.x-btn-menu-active .x-btn-text,
+.x-btn-pressed .x-btn-text {
+ color: #000;
+}
+
+.x-btn-disabled * {
+ color: gray !important;
+}
+
+.x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/default/button/arrow.gif);
+}
+
+.x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow.gif);
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split,
+.x-btn-click .x-btn-mc em.x-btn-split,
+.x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow-o.gif);
+}
+
+.x-btn-mc em.x-btn-arrow-bottom {
+ background-image: url(../images/default/button/s-arrow-b-noline.gif);
+}
+
+.x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-b.gif);
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-bo.gif);
+}
+
+.x-btn-group-header {
+ color: #3e6aaa;
+}
+
+.x-btn-group-tc {
+ background-image: url(../images/default/button/group-tb.gif);
+}
+
+.x-btn-group-tl {
+ background-image: url(../images/default/button/group-cs.gif);
+}
+
+.x-btn-group-tr {
+ background-image: url(../images/default/button/group-cs.gif);
+}
+
+.x-btn-group-bc {
+ background-image: url(../images/default/button/group-tb.gif);
+}
+
+.x-btn-group-bl {
+ background-image: url(../images/default/button/group-cs.gif);
+}
+
+.x-btn-group-br {
+ background-image: url(../images/default/button/group-cs.gif);
+}
+
+.x-btn-group-ml {
+ background-image: url(../images/default/button/group-lr.gif);
+}
+.x-btn-group-mr {
+ background-image: url(../images/default/button/group-lr.gif);
+}
+
+.x-btn-group-notitle .x-btn-group-tc {
+ background-image: url(../images/default/button/group-tb.gif);
+}
+.x-toolbar {
+ border-color: #a9bfd3;
+ background-color: #d0def0;
+ background-image: url(../images/default/toolbar/bg.gif);
+}
+
+.x-toolbar td,
+.x-toolbar span,
+.x-toolbar input,
+.x-toolbar div,
+.x-toolbar select,
+.x-toolbar label {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-toolbar .x-item-disabled {
+ color: gray;
+}
+
+.x-toolbar .x-item-disabled * {
+ color: gray;
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow-o.gif);
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-b-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-bo.gif);
+}
+
+.x-toolbar .xtb-sep {
+ background-image: url(../images/default/grid/grid-blue-split.gif);
+}
+
+.x-tbar-page-first {
+ background-image: url(../images/default/grid/page-first.gif) !important;
+}
+
+.x-tbar-loading {
+ background-image: url(../images/default/grid/refresh.gif) !important;
+}
+
+.x-tbar-page-last {
+ background-image: url(../images/default/grid/page-last.gif) !important;
+}
+
+.x-tbar-page-next {
+ background-image: url(../images/default/grid/page-next.gif) !important;
+}
+
+.x-tbar-page-prev {
+ background-image: url(../images/default/grid/page-prev.gif) !important;
+}
+
+.x-item-disabled .x-tbar-loading {
+ background-image: url(../images/default/grid/refresh-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-first {
+ background-image: url(../images/default/grid/page-first-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-last {
+ background-image: url(../images/default/grid/page-last-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-next {
+ background-image: url(../images/default/grid/page-next-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-prev {
+ background-image: url(../images/default/grid/page-prev-disabled.gif) !important;
+}
+
+.x-paging-info {
+ color: #444;
+}
+
+.x-toolbar-more-icon {
+ background-image: url(../images/default/toolbar/more.gif) !important;
+}
+.x-resizable-handle {
+ background-color: #fff;
+}
+
+.x-resizable-over .x-resizable-handle-east,
+.x-resizable-pinned .x-resizable-handle-east,
+.x-resizable-over .x-resizable-handle-west,
+.x-resizable-pinned .x-resizable-handle-west {
+ background-image: url(../images/default/sizer/e-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-south,
+.x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/default/sizer/s-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/default/sizer/s-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southeast,
+.x-resizable-pinned .x-resizable-handle-southeast {
+ background-image: url(../images/default/sizer/se-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northwest,
+.x-resizable-pinned .x-resizable-handle-northwest {
+ background-image: url(../images/default/sizer/nw-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northeast,
+.x-resizable-pinned .x-resizable-handle-northeast {
+ background-image: url(../images/default/sizer/ne-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southwest,
+.x-resizable-pinned .x-resizable-handle-southwest {
+ background-image: url(../images/default/sizer/sw-handle.gif);
+}
+.x-resizable-proxy {
+ border-color: #3b5a82;
+}
+.x-resizable-overlay {
+ background-color: #fff;
+}
+.x-grid3 {
+ background-color: #fff;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+ border-color: #99bbe8;
+}
+
+.x-grid3-row td,
+.x-grid3-summary-row td {
+ font: normal 11px/13px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-hd-row td {
+ font: normal 11px/15px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-hd-row td {
+ border-left-color: #eee;
+ border-right-color: #d0d0d0;
+}
+
+.x-grid-row-loading {
+ background-color: #fff;
+ background-image: url(../images/default/shared/loading-balls.gif);
+}
+
+.x-grid3-row {
+ border-color: #ededed;
+ border-top-color: #fff;
+}
+
+.x-grid3-row-alt {
+ background-color: #fafafa;
+}
+
+.x-grid3-row-over {
+ border-color: #ddd;
+ background-color: #efefef;
+ background-image: url(../images/default/grid/row-over.gif);
+}
+
+.x-grid3-resize-proxy {
+ background-color: #777;
+}
+
+.x-grid3-resize-marker {
+ background-color: #777;
+}
+
+.x-grid3-header {
+ background-color: #f9f9f9;
+ background-image: url(../images/default/grid/grid3-hrow.gif);
+}
+
+.x-grid3-header-pop {
+ border-left-color: #d0d0d0;
+}
+
+.x-grid3-header-pop-inner {
+ border-left-color: #eee;
+ background-image: url(../images/default/grid/hd-pop.gif);
+}
+
+td.x-grid3-hd-over,
+td.sort-desc,
+td.sort-asc,
+td.x-grid3-hd-menu-open {
+ border-left-color: #aaccf6;
+ border-right-color: #aaccf6;
+}
+
+td.x-grid3-hd-over .x-grid3-hd-inner,
+td.sort-desc .x-grid3-hd-inner,
+td.sort-asc .x-grid3-hd-inner,
+td.x-grid3-hd-menu-open .x-grid3-hd-inner {
+ background-color: #ebf3fd;
+ background-image: url(../images/default/grid/grid3-hrow-over.gif);
+}
+
+.sort-asc .x-grid3-sort-icon {
+ background-image: url(../images/default/grid/sort_asc.gif);
+}
+
+.sort-desc .x-grid3-sort-icon {
+ background-image: url(../images/default/grid/sort_desc.gif);
+}
+
+.x-grid3-cell-text,
+.x-grid3-hd-text {
+ color: #000;
+}
+
+.x-grid3-split {
+ background-image: url(../images/default/grid/grid-split.gif);
+}
+
+.x-grid3-hd-text {
+ color: #15428b;
+}
+
+.x-dd-drag-proxy .x-grid3-hd-inner {
+ background-color: #ebf3fd;
+ background-image: url(../images/default/grid/grid3-hrow-over.gif);
+ border-color: #aaccf6;
+}
+
+.col-move-top {
+ background-image: url(../images/default/grid/col-move-top.gif);
+}
+
+.col-move-bottom {
+ background-image: url(../images/default/grid/col-move-bottom.gif);
+}
+
+td.grid-hd-group-cell {
+ background: url(../images/default/grid/grid3-hrow.gif) repeat-x bottom;
+}
+
+.x-grid3-row-selected {
+ background-color: #dfe8f6 !important;
+ background-image: none;
+ border-color: #a3bae9;
+}
+
+.x-grid3-cell-selected {
+ background-color: #b8cfee !important;
+ color: #000;
+}
+
+.x-grid3-cell-selected span {
+ color: #000 !important;
+}
+
+.x-grid3-cell-selected .x-grid3-cell-text {
+ color: #000;
+}
+
+.x-grid3-locked td.x-grid3-row-marker,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker {
+ background-color: #ebeadb !important;
+ background-image: url(../images/default/grid/grid-hrow.gif) !important;
+ color: #000;
+ border-top-color: #fff;
+ border-right-color: #6fa0df !important;
+}
+
+.x-grid3-locked td.x-grid3-row-marker div,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div {
+ color: #15428b !important;
+}
+
+.x-grid3-dirty-cell {
+ background-image: url(../images/default/grid/dirty.gif);
+}
+
+.x-grid3-topbar,
+.x-grid3-bottombar {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-bottombar .x-toolbar {
+ border-top-color: #a9bfd3;
+}
+
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif) !important;
+ color: #000 !important;
+}
+
+.x-props-grid .x-grid3-body .x-grid3-td-name {
+ background-color: #fff !important;
+ border-right-color: #eee;
+}
+
+.xg-hmenu-sort-asc .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-asc.gif);
+}
+
+.xg-hmenu-sort-desc .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-desc.gif);
+}
+
+.xg-hmenu-lock .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-lock.gif);
+}
+
+.xg-hmenu-unlock .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-unlock.gif);
+}
+
+.x-grid3-hd-btn {
+ background-color: #c3daf9;
+ background-image: url(../images/default/grid/grid3-hd-btn.gif);
+}
+
+.x-grid3-body .x-grid3-td-expander {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-expander {
+ background-image: url(../images/default/grid/row-expand-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-checker {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-checker,
+.x-grid3-hd-checker {
+ background-image: url(../images/default/grid/row-check-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+ color: #444;
+}
+
+.x-grid3-body .x-grid3-td-row-icon {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
+ background-image: url(../images/default/grid/grid3-special-col-sel-bg.gif);
+}
+
+.x-grid3-check-col {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-grid3-check-col-on {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-grid-group,
+.x-grid-group-body,
+.x-grid-group-hd {
+ zoom: 1;
+}
+
+.x-grid-group-hd {
+ border-bottom-color: #99bbe8;
+}
+
+.x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/default/grid/group-collapse.gif);
+ color: #3764a0;
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/default/grid/group-expand.gif);
+}
+
+.x-group-by-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-cols-icon {
+ background-image: url(../images/default/grid/columns.gif);
+}
+
+.x-show-groups-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-grid-empty {
+ color: gray;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+ border-right-color: #ededed;
+}
+
+.x-grid-with-col-lines .x-grid3-row-selected {
+ border-top-color: #a3bae9;
+}
+.x-pivotgrid .x-grid3-header-offset table td {
+ background: url(../images/default/grid/grid3-hrow.gif) repeat-x 50% 100%;
+ border-left: 1px solid;
+ border-right: 1px solid;
+ border-left-color: #eee;
+ border-right-color: #d0d0d0;
+}
+
+.x-pivotgrid .x-grid3-row-headers {
+ background-color: #f9f9f9;
+}
+
+.x-pivotgrid .x-grid3-row-headers table td {
+ background: #eee url(../images/default/grid/grid3-rowheader.gif) repeat-x
+ left top;
+ border-left: 1px solid;
+ border-right: 1px solid;
+ border-left-color: #eee;
+ border-right-color: #d0d0d0;
+ border-bottom: 1px solid;
+ border-bottom-color: #d0d0d0;
+ height: 18px;
+}
+.x-dd-drag-ghost {
+ color: #000;
+ font: normal 11px arial, helvetica, sans-serif;
+ border-color: #ddd #bbb #bbb #ddd;
+ background-color: #fff;
+}
+
+.x-dd-drop-nodrop .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-no.gif);
+}
+
+.x-dd-drop-ok .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-yes.gif);
+}
+
+.x-dd-drop-ok-add .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-add.gif);
+}
+
+.x-view-selector {
+ background-color: #c3daf9;
+ border-color: #3399bb;
+}
+.x-tree-node-expanded .x-tree-node-icon {
+ background-image: url(../images/default/tree/folder-open.gif);
+}
+
+.x-tree-node-leaf .x-tree-node-icon {
+ background-image: url(../images/default/tree/leaf.gif);
+}
+
+.x-tree-node-collapsed .x-tree-node-icon {
+ background-image: url(../images/default/tree/folder.gif);
+}
+
+.x-tree-node-loading .x-tree-node-icon {
+ background-image: url(../images/default/tree/loading.gif) !important;
+}
+
+.x-tree-node .x-tree-node-inline-icon {
+ background-image: none;
+}
+
+.x-tree-node-loading a span {
+ font-style: italic;
+ color: #444444;
+}
+
+.x-tree-lines .x-tree-elbow {
+ background-image: url(../images/default/tree/elbow.gif);
+}
+
+.x-tree-lines .x-tree-elbow-plus {
+ background-image: url(../images/default/tree/elbow-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-minus {
+ background-image: url(../images/default/tree/elbow-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end {
+ background-image: url(../images/default/tree/elbow-end.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/default/tree/elbow-end-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/default/tree/elbow-end-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-line {
+ background-image: url(../images/default/tree/elbow-line.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-plus {
+ background-image: url(../images/default/tree/elbow-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-minus {
+ background-image: url(../images/default/tree/elbow-minus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/default/tree/elbow-end-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/default/tree/elbow-end-minus-nl.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-plus {
+ background-image: url(../images/default/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-minus {
+ background-image: url(../images/default/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-plus {
+ background-image: url(../images/default/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-minus {
+ background-image: url(../images/default/tree/arrows.gif);
+}
+
+.x-tree-node {
+ color: #000;
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-tree-node a,
+.x-dd-drag-ghost a {
+ color: #000;
+}
+
+.x-tree-node a span,
+.x-dd-drag-ghost a span {
+ color: #000;
+}
+
+.x-tree-node .x-tree-node-disabled a span {
+ color: gray !important;
+}
+
+.x-tree-node div.x-tree-drag-insert-below {
+ border-bottom-color: #36c;
+}
+
+.x-tree-node div.x-tree-drag-insert-above {
+ border-top-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a {
+ border-bottom-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a {
+ border-top-color: #36c;
+}
+
+.x-tree-node .x-tree-drag-append a span {
+ background-color: #ddd;
+ border-color: gray;
+}
+
+.x-tree-node .x-tree-node-over {
+ background-color: #eee;
+}
+
+.x-tree-node .x-tree-selected {
+ background-color: #d9e8fb;
+}
+
+.x-tree-drop-ok-append .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-add.gif);
+}
+
+.x-tree-drop-ok-above .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-over.gif);
+}
+
+.x-tree-drop-ok-below .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-under.gif);
+}
+
+.x-tree-drop-ok-between .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-between.gif);
+}
+.x-date-picker {
+ border-color: #1b376c;
+ background-color: #fff;
+}
+
+.x-date-middle,
+.x-date-left,
+.x-date-right {
+ background-image: url(../images/default/shared/hd-sprite.gif);
+ color: #fff;
+ font: bold 11px 'sans serif', tahoma, verdana, helvetica;
+}
+
+.x-date-middle .x-btn .x-btn-text {
+ color: #fff;
+}
+
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/default/toolbar/btn-arrow-light.gif);
+}
+
+.x-date-right a {
+ background-image: url(../images/default/shared/right-btn.gif);
+}
+
+.x-date-left a {
+ background-image: url(../images/default/shared/left-btn.gif);
+}
+
+.x-date-inner th {
+ background-color: #dfecfb;
+ background-image: url(../images/default/shared/glass-bg.gif);
+ border-bottom-color: #a3bad9;
+ font: normal 10px arial, helvetica, tahoma, sans-serif;
+ color: #233d6d;
+}
+
+.x-date-inner td {
+ border-color: #fff;
+}
+
+.x-date-inner a {
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+ color: #000;
+}
+
+.x-date-inner .x-date-active {
+ color: #000;
+}
+
+.x-date-inner .x-date-selected a {
+ background-color: #dfecfb;
+ background-image: url(../images/default/shared/glass-bg.gif);
+ border-color: #8db2e3;
+}
+
+.x-date-inner .x-date-today a {
+ border-color: darkred;
+}
+
+.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: #aaa;
+}
+
+.x-date-bottom {
+ border-top-color: #a3bad9;
+ background-color: #dfecfb;
+ background-image: url(../images/default/shared/glass-bg.gif);
+}
+
+.x-date-inner a:hover,
+.x-date-inner .x-date-disabled a:hover {
+ color: #000;
+ background-color: #ddecfe;
+}
+
+.x-date-inner .x-date-disabled a {
+ background-color: #eee;
+ color: #bbb;
+}
+
+.x-date-mmenu {
+ background-color: #eee !important;
+}
+
+.x-date-mmenu .x-menu-item {
+ font-size: 10px;
+ color: #000;
+}
+
+.x-date-mp {
+ background-color: #fff;
+}
+
+.x-date-mp td {
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns button {
+ background-color: #083772;
+ color: #fff;
+ border-color: #3366cc #000055 #000055 #3366cc;
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns {
+ background-color: #dfecfb;
+ background-image: url(../images/default/shared/glass-bg.gif);
+}
+
+.x-date-mp-btns td {
+ border-top-color: #c5d2df;
+}
+
+td.x-date-mp-month a,
+td.x-date-mp-year a {
+ color: #15428b;
+}
+
+td.x-date-mp-month a:hover,
+td.x-date-mp-year a:hover {
+ color: #15428b;
+ background-color: #ddecfe;
+}
+
+td.x-date-mp-sel a {
+ background-color: #dfecfb;
+ background-image: url(../images/default/shared/glass-bg.gif);
+ border-color: #8db2e3;
+}
+
+.x-date-mp-ybtn a {
+ background-image: url(../images/default/panel/tool-sprites.gif);
+}
+
+td.x-date-mp-sep {
+ border-right-color: #c5d2df;
+}
+.x-tip .x-tip-close {
+ background-image: url(../images/default/qtip/close.gif);
+}
+
+.x-tip .x-tip-tc,
+.x-tip .x-tip-tl,
+.x-tip .x-tip-tr,
+.x-tip .x-tip-bc,
+.x-tip .x-tip-bl,
+.x-tip .x-tip-br,
+.x-tip .x-tip-ml,
+.x-tip .x-tip-mr {
+ background-image: url(../images/default/qtip/tip-sprite.gif);
+}
+
+.x-tip .x-tip-mc {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-tip .x-tip-ml {
+ background-color: #fff;
+}
+
+.x-tip .x-tip-header-text {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #444;
+}
+
+.x-tip .x-tip-body {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ color: #444;
+}
+
+.x-form-invalid-tip .x-tip-tc,
+.x-form-invalid-tip .x-tip-tl,
+.x-form-invalid-tip .x-tip-tr,
+.x-form-invalid-tip .x-tip-bc,
+.x-form-invalid-tip .x-tip-bl,
+.x-form-invalid-tip .x-tip-br,
+.x-form-invalid-tip .x-tip-ml,
+.x-form-invalid-tip .x-tip-mr {
+ background-image: url(../images/default/form/error-tip-corners.gif);
+}
+
+.x-form-invalid-tip .x-tip-body {
+ background-image: url(../images/default/form/exclamation.gif);
+}
+
+.x-tip-anchor {
+ background-image: url(../images/default/qtip/tip-anchor-sprite.gif);
+}
+.x-menu {
+ background-color: #f0f0f0;
+ background-image: url(../images/default/menu/menu.gif);
+}
+
+.x-menu-floating {
+ border-color: #718bb7;
+}
+
+.x-menu-nosep {
+ background-image: none;
+}
+
+.x-menu-list-item {
+ font: normal 11px arial, tahoma, sans-serif;
+}
+
+.x-menu-item-arrow {
+ background-image: url(../images/default/menu/menu-parent.gif);
+}
+
+.x-menu-sep {
+ background-color: #e0e0e0;
+ border-bottom-color: #fff;
+}
+
+a.x-menu-item {
+ color: #222;
+}
+
+.x-menu-item-active {
+ background-image: url(../images/default/menu/item-over.gif);
+ background-color: #dbecf4;
+ border-color: #aaccf6;
+}
+
+.x-menu-item-active a.x-menu-item {
+ border-color: #aaccf6;
+}
+
+.x-menu-check-item .x-menu-item-icon {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-menu-item-checked .x-menu-item-icon {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon {
+ background-image: url(../images/default/menu/group-checked.gif);
+}
+
+.x-menu-group-item .x-menu-item-icon {
+ background-image: none;
+}
+
+.x-menu-plain {
+ background-color: #f0f0f0 !important;
+ background-image: none;
+}
+
+.x-date-menu,
+.x-color-menu {
+ background-color: #fff !important;
+}
+
+.x-menu .x-date-picker {
+ border-color: #a3bad9;
+}
+
+.x-cycle-menu .x-menu-item-checked {
+ border-color: #a3bae9 !important;
+ background-color: #def8f6;
+}
+
+.x-menu-scroller-top {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+
+.x-menu-scroller-bottom {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+.x-box-tl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-tc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-tr {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-ml {
+ background-image: url(../images/default/box/l.gif);
+}
+
+.x-box-mc {
+ background-color: #eee;
+ background-image: url(../images/default/box/tb.gif);
+ 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;
+}
+
+.x-box-mr {
+ background-image: url(../images/default/box/r.gif);
+}
+
+.x-box-bl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-bc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-br {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.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(../images/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(../images/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(../images/default/box/l-blue.gif);
+}
+
+.x-box-blue .x-box-mr {
+ background-image: url(../images/default/box/r-blue.gif);
+}
+.x-combo-list {
+ border-color: #98c0f4;
+ background-color: #ddecfe;
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-combo-list-inner {
+ background-color: #fff;
+}
+
+.x-combo-list-hd {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #15428b;
+ background-image: url(../images/default/layout/panel-title-light-bg.gif);
+ border-bottom-color: #98c0f4;
+}
+
+.x-resizable-pinned .x-combo-list-inner {
+ border-bottom-color: #98c0f4;
+}
+
+.x-combo-list-item {
+ border-color: #fff;
+}
+
+.x-combo-list .x-combo-selected {
+ border-color: #a3bae9 !important;
+ background-color: #dfe8f6;
+}
+
+.x-combo-list .x-toolbar {
+ border-top-color: #98c0f4;
+}
+
+.x-combo-list-small {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-panel {
+ border-color: #99bbe8;
+}
+
+.x-panel-header {
+ color: #15428b;
+ font-weight: bold;
+ font-size: 11px;
+ font-family: tahoma, arial, verdana, sans-serif;
+ border-color: #99bbe8;
+ background-image: url(../images/default/panel/white-top-bottom.gif);
+}
+
+.x-panel-body {
+ border-color: #99bbe8;
+ background-color: #fff;
+}
+
+.x-panel-bbar .x-toolbar,
+.x-panel-tbar .x-toolbar {
+ border-color: #99bbe8;
+}
+
+.x-panel-tbar-noheader .x-toolbar,
+.x-panel-mc .x-panel-tbar .x-toolbar {
+ border-top-color: #99bbe8;
+}
+
+.x-panel-body-noheader,
+.x-panel-mc .x-panel-body {
+ border-top-color: #99bbe8;
+}
+
+.x-panel-tl .x-panel-header {
+ color: #15428b;
+ font: bold 11px tahoma, arial, verdana, sans-serif;
+}
+
+.x-panel-tc {
+ background-image: url(../images/default/panel/top-bottom.gif);
+}
+
+.x-panel-tl,
+.x-panel-tr,
+.x-panel-bl,
+.x-panel-br {
+ background-image: url(../images/default/panel/corners-sprite.gif);
+ border-bottom-color: #99bbe8;
+}
+
+.x-panel-bc {
+ background-image: url(../images/default/panel/top-bottom.gif);
+}
+
+.x-panel-mc {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-color: #dfe8f6;
+}
+
+.x-panel-ml {
+ background-color: #fff;
+ background-image: url(../images/default/panel/left-right.gif);
+}
+
+.x-panel-mr {
+ background-image: url(../images/default/panel/left-right.gif);
+}
+
+.x-tool {
+ background-image: url(../images/default/panel/tool-sprites.gif);
+}
+
+.x-panel-ghost {
+ background-color: #cbddf3;
+}
+
+.x-panel-ghost ul {
+ border-color: #99bbe8;
+}
+
+.x-panel-dd-spacer {
+ border-color: #99bbe8;
+}
+
+.x-panel-fbar td,
+.x-panel-fbar span,
+.x-panel-fbar input,
+.x-panel-fbar div,
+.x-panel-fbar select,
+.x-panel-fbar label {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-window-proxy {
+ background-color: #c7dffc;
+ border-color: #99bbe8;
+}
+
+.x-window-tl .x-window-header {
+ color: #15428b;
+ font: bold 11px tahoma, arial, verdana, sans-serif;
+}
+
+.x-window-tc {
+ background-image: url(../images/default/window/top-bottom.png);
+}
+
+.x-window-tl {
+ background-image: url(../images/default/window/left-corners.png);
+}
+
+.x-window-tr {
+ background-image: url(../images/default/window/right-corners.png);
+}
+
+.x-window-bc {
+ background-image: url(../images/default/window/top-bottom.png);
+}
+
+.x-window-bl {
+ background-image: url(../images/default/window/left-corners.png);
+}
+
+.x-window-br {
+ background-image: url(../images/default/window/right-corners.png);
+}
+
+.x-window-mc {
+ border-color: #99bbe8;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-color: #dfe8f6;
+}
+
+.x-window-ml {
+ background-image: url(../images/default/window/left-right.png);
+}
+
+.x-window-mr {
+ background-image: url(../images/default/window/left-right.png);
+}
+
+.x-window-maximized .x-window-tc {
+ background-color: #fff;
+}
+
+.x-window-bbar .x-toolbar {
+ border-top-color: #99bbe8;
+}
+
+.x-panel-ghost .x-window-tl {
+ border-bottom-color: #99bbe8;
+}
+
+.x-panel-collapsed .x-window-tl {
+ border-bottom-color: #84a0c4;
+}
+
+.x-dlg-mask {
+ background-color: #ccc;
+}
+
+.x-window-plain .x-window-mc {
+ background-color: #ccd9e8;
+ border-color: #a3bae9 #dfe8f6 #dfe8f6 #a3bae9;
+}
+
+.x-window-plain .x-window-body {
+ border-color: #dfe8f6 #a3bae9 #a3bae9 #dfe8f6;
+}
+
+body.x-body-masked .x-window-plain .x-window-mc {
+ background-color: #ccd9e8;
+}
+.x-html-editor-wrap {
+ border-color: #a9bfd3;
+ background-color: #fff;
+}
+.x-html-editor-tb .x-btn-text {
+ background-image: url(../images/default/editor/tb-sprite.gif);
+}
+.x-panel-noborder .x-panel-header-noborder {
+ border-bottom-color: #99bbe8;
+}
+
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #99bbe8;
+}
+
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+ border-top-color: #99bbe8;
+}
+
+.x-tab-panel-bbar-noborder .x-toolbar {
+ border-top-color: #99bbe8;
+}
+
+.x-tab-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #99bbe8;
+}
+.x-border-layout-ct {
+ background-color: #dfe8f6;
+}
+
+.x-accordion-hd {
+ color: #222;
+ font-weight: normal;
+ background-image: url(../images/default/panel/light-hd.gif);
+}
+
+.x-layout-collapsed {
+ background-color: #d2e0f2;
+ border-color: #98c0f4;
+}
+
+.x-layout-collapsed-over {
+ background-color: #d9e8fb;
+}
+
+.x-layout-split-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+.x-layout-split-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+.x-layout-split-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+.x-layout-split-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+
+.x-layout-cmini-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+
+.x-layout-cmini-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+.x-progress-wrap {
+ border-color: #6593cf;
+}
+
+.x-progress-inner {
+ background-color: #e0e8f3;
+ background-image: url(../images/default/qtip/bg.gif);
+}
+
+.x-progress-bar {
+ background-color: #9cbfee;
+ background-image: url(../images/default/progress/progress-bg.gif);
+ border-top-color: #d1e4fd;
+ border-bottom-color: #7fa9e4;
+ border-right-color: #7fa9e4;
+}
+
+.x-progress-text {
+ font-size: 11px;
+ font-weight: bold;
+ color: #fff;
+}
+
+.x-progress-text-back {
+ color: #396095;
+}
+.x-list-header {
+ background-color: #f9f9f9;
+ background-image: url(../images/default/grid/grid3-hrow.gif);
+}
+
+.x-list-header-inner div em {
+ border-left-color: #ddd;
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-list-body dt em {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-list-over {
+ background-color: #eee;
+}
+
+.x-list-selected {
+ background-color: #dfe8f6;
+}
+
+.x-list-resizer {
+ border-left-color: #555;
+ border-right-color: #555;
+}
+
+.x-list-header-inner em.sort-asc,
+.x-list-header-inner em.sort-desc {
+ background-image: url(../images/default/grid/sort-hd.gif);
+ border-color: #99bbe8;
+}
+.x-slider-horz,
+.x-slider-horz .x-slider-end,
+.x-slider-horz .x-slider-inner {
+ background-image: url(../images/default/slider/slider-bg.png);
+}
+
+.x-slider-horz .x-slider-thumb {
+ background-image: url(../images/default/slider/slider-thumb.png);
+}
+
+.x-slider-vert,
+.x-slider-vert .x-slider-end,
+.x-slider-vert .x-slider-inner {
+ background-image: url(../images/default/slider/slider-v-bg.png);
+}
+
+.x-slider-vert .x-slider-thumb {
+ background-image: url(../images/default/slider/slider-v-thumb.png);
+}
+.x-window-dlg .ext-mb-text,
+.x-window-dlg .x-window-header-text {
+ font-size: 12px;
+}
+
+.x-window-dlg .ext-mb-textarea {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-window-dlg .x-msg-box-wait {
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-window-dlg .ext-mb-info {
+ background-image: url(../images/default/window/icon-info.gif);
+}
+
+.x-window-dlg .ext-mb-warning {
+ background-image: url(../images/default/window/icon-warning.gif);
+}
+
+.x-window-dlg .ext-mb-question {
+ background-image: url(../images/default/window/icon-question.gif);
+}
+
+.x-window-dlg .ext-mb-error {
+ background-image: url(../images/default/window/icon-error.gif);
+}
diff --git a/deluge/ui/web/themes/css/xtheme-gray.css b/deluge/ui/web/themes/css/xtheme-gray.css
new file mode 100644
index 0000000..25bae0a
--- /dev/null
+++ b/deluge/ui/web/themes/css/xtheme-gray.css
@@ -0,0 +1,1791 @@
+/**
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+.ext-el-mask {
+ background-color: #ccc;
+}
+
+.ext-el-mask-msg {
+ border-color: #999;
+ background-color: #ddd;
+ background-image: url(../images/gray/panel/white-top-bottom.gif);
+ background-position: 0 -1px;
+}
+.ext-el-mask-msg div {
+ background-color: #eee;
+ border-color: #d0d0d0;
+ color: #222;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-mask-loading div {
+ background-color: #fbfbfb;
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-item-disabled {
+ color: gray;
+}
+
+.x-item-disabled * {
+ color: gray !important;
+}
+
+.x-splitbar-proxy {
+ background-color: #aaa;
+}
+
+.x-color-palette a {
+ border-color: #fff;
+}
+
+.x-color-palette a:hover,
+.x-color-palette a.x-color-palette-sel {
+ border-color: #cfcfcf;
+ background-color: #eaeaea;
+}
+
+/*
+.x-color-palette em:hover, .x-color-palette span:hover{
+ background-color: #eaeaea;
+}
+*/
+
+.x-color-palette em {
+ border-color: #aca899;
+}
+
+.x-ie-shadow {
+ background-color: #777;
+}
+
+.x-shadow .xsmc {
+ background-image: url(../images/default/shadow-c.png);
+}
+
+.x-shadow .xsml,
+.x-shadow .xsmr {
+ background-image: url(../images/default/shadow-lr.png);
+}
+
+.x-shadow .xstl,
+.x-shadow .xstc,
+.x-shadow .xstr,
+.x-shadow .xsbl,
+.x-shadow .xsbc,
+.x-shadow .xsbr {
+ background-image: url(../images/default/shadow.png);
+}
+
+.loading-indicator {
+ font-size: 11px;
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-spotlight {
+ background-color: #ccc;
+}
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ background-color: #eaeaea;
+ border-color: #d0d0d0;
+ overflow: hidden;
+ zoom: 1;
+}
+
+.x-tab-panel-header,
+.x-tab-panel-footer {
+ border-color: #d0d0d0;
+}
+
+ul.x-tab-strip-top {
+ background-color: #dbdbdb;
+ background-image: url(../images/gray/tabs/tab-strip-bg.gif);
+ border-bottom-color: #d0d0d0;
+}
+
+ul.x-tab-strip-bottom {
+ background-color: #dbdbdb;
+ background-image: url(../images/gray/tabs/tab-strip-btm-bg.gif);
+ border-top-color: #d0d0d0;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+ border-color: #d0d0d0;
+ background-color: #eaeaea;
+}
+
+.x-tab-strip span.x-tab-strip-text {
+ font: normal 11px tahoma, arial, helvetica;
+ color: #333;
+}
+
+.x-tab-strip-over span.x-tab-strip-text {
+ color: #111;
+}
+
+.x-tab-strip-active span.x-tab-strip-text {
+ color: #333;
+ font-weight: bold;
+}
+
+.x-tab-strip-disabled .x-tabs-text {
+ color: #aaaaaa;
+}
+
+.x-tab-strip-top .x-tab-right,
+.x-tab-strip-top .x-tab-left,
+.x-tab-strip-top .x-tab-strip-inner {
+ background-image: url(../images/gray/tabs/tabs-sprite.gif);
+}
+
+.x-tab-strip-bottom .x-tab-right {
+ background-image: url(../images/gray/tabs/tab-btm-inactive-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-left {
+ background-image: url(../images/gray/tabs/tab-btm-inactive-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-over .x-tab-left {
+ background-image: url(../images/gray/tabs/tab-btm-over-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-over .x-tab-right {
+ background-image: url(../images/gray/tabs/tab-btm-over-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+ background-image: url(../images/gray/tabs/tab-btm-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+ background-image: url(../images/gray/tabs/tab-btm-left-bg.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+ background-image: url(../images/gray/tabs/tab-close.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover {
+ background-image: url(../images/gray/tabs/tab-close.gif);
+}
+
+.x-tab-panel-body {
+ border-color: #d0d0d0;
+ background-color: #fff;
+}
+
+.x-tab-panel-body-top {
+ border-top: 0 none;
+}
+
+.x-tab-panel-body-bottom {
+ border-bottom: 0 none;
+}
+
+.x-tab-scroller-left {
+ background-image: url(../images/gray/tabs/scroll-left.gif);
+ border-bottom-color: #d0d0d0;
+}
+
+.x-tab-scroller-left-over {
+ background-position: 0 0;
+}
+
+.x-tab-scroller-left-disabled {
+ background-position: -18px 0;
+ opacity: 0.5;
+ -moz-opacity: 0.5;
+ filter: alpha(opacity=50);
+ cursor: default;
+}
+
+.x-tab-scroller-right {
+ background-image: url(../images/gray/tabs/scroll-right.gif);
+ border-bottom-color: #d0d0d0;
+}
+
+.x-tab-panel-bbar .x-toolbar,
+.x-tab-panel-tbar .x-toolbar {
+ border-color: #d0d0d0;
+}
+.x-form-field {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-text,
+textarea.x-form-field {
+ background-color: #fff;
+ background-image: url(../images/default/form/text-bg.gif);
+ border-color: #c1c1c1;
+}
+
+.x-form-select-one {
+ background-color: #fff;
+ border-color: #c1c1c1;
+}
+
+.x-form-check-group-label {
+ border-bottom: 1px solid #d0d0d0;
+ color: #333;
+}
+
+.x-editor .x-form-check-wrap {
+ background-color: #fff;
+}
+
+.x-form-field-wrap .x-form-trigger {
+ background-image: url(../images/gray/form/trigger.gif);
+ border-bottom-color: #b5b8c8;
+}
+
+.x-form-field-wrap .x-form-date-trigger {
+ background-image: url(../images/gray/form/date-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-clear-trigger {
+ background-image: url(../images/gray/form/clear-trigger.gif);
+}
+
+.x-form-field-wrap .x-form-search-trigger {
+ background-image: url(../images/gray/form/search-trigger.gif);
+}
+
+.x-trigger-wrap-focus .x-form-trigger {
+ border-bottom-color: #777777;
+}
+
+.x-item-disabled .x-form-trigger-over {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-item-disabled .x-form-trigger-click {
+ border-bottom-color: #b5b8c8;
+}
+
+.x-form-focus,
+textarea.x-form-focus {
+ border-color: #777777;
+}
+
+.x-form-invalid,
+textarea.x-form-invalid {
+ background-color: #fff;
+ background-image: url(../images/default/grid/invalid_line.gif);
+ border-color: #c30;
+}
+
+.ext-webkit .x-form-invalid {
+ background-color: #fee;
+ border-color: #ff7870;
+}
+
+.x-form-inner-invalid,
+textarea.x-form-inner-invalid {
+ background-color: #fff;
+ background-image: url(../images/default/grid/invalid_line.gif);
+}
+
+.x-form-grow-sizer {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-item {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-form-invalid-msg {
+ color: #c0272b;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-image: url(../images/default/shared/warning.gif);
+}
+
+.x-form-empty-field {
+ color: gray;
+}
+
+.x-small-editor .x-form-field {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.ext-webkit .x-small-editor .x-form-field {
+ font: normal 12px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-form-invalid-icon {
+ background-image: url(../images/default/form/exclamation.gif);
+}
+
+.x-fieldset {
+ border-color: #cccccc;
+}
+
+.x-fieldset legend {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #777777;
+}
+.x-btn {
+ font: normal 11px tahoma, verdana, helvetica;
+}
+
+.x-btn button {
+ font: normal 11px arial, tahoma, verdana, helvetica;
+ color: #333;
+}
+
+.x-btn em {
+ font-style: normal;
+ font-weight: normal;
+}
+
+.x-btn-tl,
+.x-btn-tr,
+.x-btn-tc,
+.x-btn-ml,
+.x-btn-mr,
+.x-btn-mc,
+.x-btn-bl,
+.x-btn-br,
+.x-btn-bc {
+ background-image: url(../images/gray/button/btn.gif);
+}
+
+.x-btn-click .x-btn-text,
+.x-btn-menu-active .x-btn-text,
+.x-btn-pressed .x-btn-text {
+ color: #000;
+}
+
+.x-btn-disabled * {
+ color: gray !important;
+}
+
+.x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/default/button/arrow.gif);
+}
+
+.x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow.gif);
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split,
+.x-btn-click .x-btn-mc em.x-btn-split,
+.x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/gray/button/s-arrow-o.gif);
+}
+
+.x-btn-mc em.x-btn-arrow-bottom {
+ background-image: url(../images/default/button/s-arrow-b-noline.gif);
+}
+
+.x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-b.gif);
+}
+
+.x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/gray/button/s-arrow-bo.gif);
+}
+
+.x-btn-group-header {
+ color: #666;
+}
+
+.x-btn-group-tc {
+ background-image: url(../images/gray/button/group-tb.gif);
+}
+
+.x-btn-group-tl {
+ background-image: url(../images/gray/button/group-cs.gif);
+}
+
+.x-btn-group-tr {
+ background-image: url(../images/gray/button/group-cs.gif);
+}
+
+.x-btn-group-bc {
+ background-image: url(../images/gray/button/group-tb.gif);
+}
+
+.x-btn-group-bl {
+ background-image: url(../images/gray/button/group-cs.gif);
+}
+
+.x-btn-group-br {
+ background-image: url(../images/gray/button/group-cs.gif);
+}
+
+.x-btn-group-ml {
+ background-image: url(../images/gray/button/group-lr.gif);
+}
+.x-btn-group-mr {
+ background-image: url(../images/gray/button/group-lr.gif);
+}
+
+.x-btn-group-notitle .x-btn-group-tc {
+ background-image: url(../images/gray/button/group-tb.gif);
+}
+.x-toolbar {
+ border-color: #d0d0d0;
+ background-color: #f0f0f0;
+ background-image: url(../images/gray/toolbar/bg.gif);
+}
+
+.x-toolbar td,
+.x-toolbar span,
+.x-toolbar input,
+.x-toolbar div,
+.x-toolbar select,
+.x-toolbar label {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-toolbar .x-item-disabled {
+ color: gray;
+}
+
+.x-toolbar .x-item-disabled * {
+ color: gray;
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split {
+ background-image: url(../images/default/button/s-arrow-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split {
+ background-image: url(../images/gray/button/s-arrow-o.gif);
+}
+
+.x-toolbar .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/default/button/s-arrow-b-noline.gif);
+}
+
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,
+.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+ background-image: url(../images/gray/button/s-arrow-bo.gif);
+}
+
+.x-toolbar .xtb-sep {
+ background-image: url(../images/default/grid/grid-split.gif);
+}
+
+.x-tbar-page-first {
+ background-image: url(../images/gray/grid/page-first.gif) !important;
+}
+
+.x-tbar-loading {
+ background-image: url(../images/gray/grid/refresh.gif) !important;
+}
+
+.x-tbar-page-last {
+ background-image: url(../images/gray/grid/page-last.gif) !important;
+}
+
+.x-tbar-page-next {
+ background-image: url(../images/gray/grid/page-next.gif) !important;
+}
+
+.x-tbar-page-prev {
+ background-image: url(../images/gray/grid/page-prev.gif) !important;
+}
+
+.x-item-disabled .x-tbar-loading {
+ background-image: url(../images/default/grid/loading.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-first {
+ background-image: url(../images/default/grid/page-first-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-last {
+ background-image: url(../images/default/grid/page-last-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-next {
+ background-image: url(../images/default/grid/page-next-disabled.gif) !important;
+}
+
+.x-item-disabled .x-tbar-page-prev {
+ background-image: url(../images/default/grid/page-prev-disabled.gif) !important;
+}
+
+.x-paging-info {
+ color: #444;
+}
+
+.x-toolbar-more-icon {
+ background-image: url(../images/gray/toolbar/more.gif) !important;
+}
+.x-resizable-handle {
+ background-color: #fff;
+}
+
+.x-resizable-over .x-resizable-handle-east,
+.x-resizable-pinned .x-resizable-handle-east,
+.x-resizable-over .x-resizable-handle-west,
+.x-resizable-pinned .x-resizable-handle-west {
+ background-image: url(../images/gray/sizer/e-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-south,
+.x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/gray/sizer/s-handle.gif);
+}
+
+.x-resizable-over .x-resizable-handle-north,
+.x-resizable-pinned .x-resizable-handle-north {
+ background-image: url(../images/gray/sizer/s-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southeast,
+.x-resizable-pinned .x-resizable-handle-southeast {
+ background-image: url(../images/gray/sizer/se-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northwest,
+.x-resizable-pinned .x-resizable-handle-northwest {
+ background-image: url(../images/gray/sizer/nw-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northeast,
+.x-resizable-pinned .x-resizable-handle-northeast {
+ background-image: url(../images/gray/sizer/ne-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southwest,
+.x-resizable-pinned .x-resizable-handle-southwest {
+ background-image: url(../images/gray/sizer/sw-handle.gif);
+}
+.x-resizable-proxy {
+ border-color: #565656;
+}
+.x-resizable-overlay {
+ background-color: #fff;
+}
+.x-grid3 {
+ background-color: #fff;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+ border-color: #d0d0d0;
+}
+
+.x-grid3-row td,
+.x-grid3-summary-row td {
+ font: normal 11px/13px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-hd-row td {
+ font: normal 11px/15px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-hd-row td {
+ border-left-color: #eee;
+ border-right-color: #d0d0d0;
+}
+
+.x-grid-row-loading {
+ background-color: #fff;
+ background-image: url(../images/default/shared/loading-balls.gif);
+}
+
+.x-grid3-row {
+ border-color: #ededed;
+ border-top-color: #fff;
+}
+
+.x-grid3-row-alt {
+ background-color: #fafafa;
+}
+
+.x-grid3-row-over {
+ border-color: #ddd;
+ background-color: #efefef;
+ background-image: url(../images/default/grid/row-over.gif);
+}
+
+.x-grid3-resize-proxy {
+ background-color: #777;
+}
+
+.x-grid3-resize-marker {
+ background-color: #777;
+}
+
+.x-grid3-header {
+ background-color: #f9f9f9;
+ background-image: url(../images/gray/grid/grid3-hrow2.gif);
+}
+
+.x-grid3-header-pop {
+ border-left-color: #d0d0d0;
+}
+
+.x-grid3-header-pop-inner {
+ border-left-color: #eee;
+ background-image: url(../images/default/grid/hd-pop.gif);
+}
+
+td.x-grid3-hd-over,
+td.sort-desc,
+td.sort-asc,
+td.x-grid3-hd-menu-open {
+ border-left-color: #acacac;
+ border-right-color: #acacac;
+}
+
+td.x-grid3-hd-over .x-grid3-hd-inner,
+td.sort-desc .x-grid3-hd-inner,
+td.sort-asc .x-grid3-hd-inner,
+td.x-grid3-hd-menu-open .x-grid3-hd-inner {
+ background-color: #f9f9f9;
+ background-image: url(../images/gray/grid/grid3-hrow-over2.gif);
+}
+
+.sort-asc .x-grid3-sort-icon {
+ background-image: url(../images/gray/grid/sort_asc.gif);
+}
+
+.sort-desc .x-grid3-sort-icon {
+ background-image: url(../images/gray/grid/sort_desc.gif);
+}
+
+.x-grid3-cell-text,
+.x-grid3-hd-text {
+ color: #000;
+}
+
+.x-grid3-split {
+ background-image: url(../images/default/grid/grid-split.gif);
+}
+
+.x-grid3-hd-text {
+ color: #333;
+}
+
+.x-dd-drag-proxy .x-grid3-hd-inner {
+ background-color: #f9f9f9;
+ background-image: url(../images/gray/grid/grid3-hrow-over2.gif);
+ border-color: #acacac;
+}
+
+.col-move-top {
+ background-image: url(../images/gray/grid/col-move-top.gif);
+}
+
+.col-move-bottom {
+ background-image: url(../images/gray/grid/col-move-bottom.gif);
+}
+
+.x-grid3-row-selected {
+ background-color: #cccccc !important;
+ background-image: none;
+ border-color: #acacac;
+}
+
+.x-grid3-cell-selected {
+ background-color: #cbcbcb !important;
+ color: #000;
+}
+
+.x-grid3-cell-selected span {
+ color: #000 !important;
+}
+
+.x-grid3-cell-selected .x-grid3-cell-text {
+ color: #000;
+}
+
+.x-grid3-locked td.x-grid3-row-marker,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker {
+ background-color: #ebeadb !important;
+ background-image: url(../images/default/grid/grid-hrow.gif) !important;
+ color: #000;
+ border-top-color: #fff;
+ border-right-color: #6fa0df !important;
+}
+
+.x-grid3-locked td.x-grid3-row-marker div,
+.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div {
+ color: #333 !important;
+}
+
+.x-grid3-dirty-cell {
+ background-image: url(../images/default/grid/dirty.gif);
+}
+
+.x-grid3-topbar,
+.x-grid3-bottombar {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-grid3-bottombar .x-toolbar {
+ border-top-color: #a9bfd3;
+}
+
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif) !important;
+ color: #000 !important;
+}
+
+.x-props-grid .x-grid3-body .x-grid3-td-name {
+ background-color: #fff !important;
+ border-right-color: #eee;
+}
+
+.xg-hmenu-sort-asc .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-asc.gif);
+}
+
+.xg-hmenu-sort-desc .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-desc.gif);
+}
+
+.xg-hmenu-lock .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-lock.gif);
+}
+
+.xg-hmenu-unlock .x-menu-item-icon {
+ background-image: url(../images/default/grid/hmenu-unlock.gif);
+}
+
+.x-grid3-hd-btn {
+ background-color: #f9f9f9;
+ background-image: url(../images/gray/grid/grid3-hd-btn.gif);
+}
+
+.x-grid3-body .x-grid3-td-expander {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-expander {
+ background-image: url(../images/gray/grid/row-expand-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-checker {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-row-checker,
+.x-grid3-hd-checker {
+ background-image: url(../images/default/grid/row-check-sprite.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+ color: #444;
+}
+
+.x-grid3-body .x-grid3-td-row-icon {
+ background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
+ background-image: url(../images/gray/grid/grid3-special-col-sel-bg.gif);
+}
+
+.x-grid3-check-col {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-grid3-check-col-on {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-grid-group,
+.x-grid-group-body,
+.x-grid-group-hd {
+ zoom: 1;
+}
+
+.x-grid-group-hd {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/gray/grid/group-collapse.gif);
+ color: #5f5f5f;
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title {
+ background-image: url(../images/gray/grid/group-expand.gif);
+}
+
+.x-group-by-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-cols-icon {
+ background-image: url(../images/default/grid/columns.gif);
+}
+
+.x-show-groups-icon {
+ background-image: url(../images/default/grid/group-by.gif);
+}
+
+.x-grid-empty {
+ color: gray;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+ border-right-color: #ededed;
+}
+
+.x-grid-with-col-lines .x-grid3-row {
+ border-top-color: #ededed;
+}
+
+.x-grid-with-col-lines .x-grid3-row-selected {
+ border-top-color: #b9b9b9;
+}
+.x-pivotgrid .x-grid3-header-offset table td {
+ background: url(../images/gray/grid/grid3-hrow2.gif) repeat-x 50% 100%;
+ border-left: 1px solid;
+ border-right: 1px solid;
+ border-left-color: #d0d0d0;
+ border-right-color: #d0d0d0;
+}
+
+.x-pivotgrid .x-grid3-row-headers {
+ background-color: #f9f9f9;
+}
+
+.x-pivotgrid .x-grid3-row-headers table td {
+ background: #eee url(../images/default/grid/grid3-rowheader.gif) repeat-x
+ left top;
+ border-left: 1px solid;
+ border-right: 1px solid;
+ border-left-color: #eee;
+ border-right-color: #d0d0d0;
+ border-bottom: 1px solid;
+ border-bottom-color: #d0d0d0;
+ height: 18px;
+}
+.x-dd-drag-ghost {
+ color: #000;
+ font: normal 11px arial, helvetica, sans-serif;
+ border-color: #ddd #bbb #bbb #ddd;
+ background-color: #fff;
+}
+
+.x-dd-drop-nodrop .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-no.gif);
+}
+
+.x-dd-drop-ok .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-yes.gif);
+}
+
+.x-dd-drop-ok-add .x-dd-drop-icon {
+ background-image: url(../images/default/dd/drop-add.gif);
+}
+
+.x-view-selector {
+ background-color: #d6d6d6;
+ border-color: #888888;
+}
+.x-tree-node-expanded .x-tree-node-icon {
+ background-image: url(../images/default/tree/folder-open.gif);
+}
+
+.x-tree-node-leaf .x-tree-node-icon {
+ background-image: url(../images/default/tree/leaf.gif);
+}
+
+.x-tree-node-collapsed .x-tree-node-icon {
+ background-image: url(../images/default/tree/folder.gif);
+}
+
+.x-tree-node-loading .x-tree-node-icon {
+ background-image: url(../images/default/tree/loading.gif) !important;
+}
+
+.x-tree-node .x-tree-node-inline-icon {
+ background-image: none;
+}
+
+.x-tree-node-loading a span {
+ font-style: italic;
+ color: #444444;
+}
+
+.ext-ie .x-tree-node-el input {
+ width: 15px;
+ height: 15px;
+}
+
+.x-tree-lines .x-tree-elbow {
+ background-image: url(../images/default/tree/elbow.gif);
+}
+
+.x-tree-lines .x-tree-elbow-plus {
+ background-image: url(../images/default/tree/elbow-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-minus {
+ background-image: url(../images/default/tree/elbow-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end {
+ background-image: url(../images/default/tree/elbow-end.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/gray/tree/elbow-end-plus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/gray/tree/elbow-end-minus.gif);
+}
+
+.x-tree-lines .x-tree-elbow-line {
+ background-image: url(../images/default/tree/elbow-line.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-plus {
+ background-image: url(../images/default/tree/elbow-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-minus {
+ background-image: url(../images/default/tree/elbow-minus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-plus {
+ background-image: url(../images/gray/tree/elbow-end-plus-nl.gif);
+}
+
+.x-tree-no-lines .x-tree-elbow-end-minus {
+ background-image: url(../images/gray/tree/elbow-end-minus-nl.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-plus {
+ background-image: url(../images/gray/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-minus {
+ background-image: url(../images/gray/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-plus {
+ background-image: url(../images/gray/tree/arrows.gif);
+}
+
+.x-tree-arrows .x-tree-elbow-end-minus {
+ background-image: url(../images/gray/tree/arrows.gif);
+}
+
+.x-tree-node {
+ color: #000;
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-tree-node a,
+.x-dd-drag-ghost a {
+ color: #000;
+}
+
+.x-tree-node a span,
+.x-dd-drag-ghost a span {
+ color: #000;
+}
+
+.x-tree-node .x-tree-node-disabled a span {
+ color: gray !important;
+}
+
+.x-tree-node div.x-tree-drag-insert-below {
+ border-bottom-color: #36c;
+}
+
+.x-tree-node div.x-tree-drag-insert-above {
+ border-top-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a {
+ border-bottom-color: #36c;
+}
+
+.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a {
+ border-top-color: #36c;
+}
+
+.x-tree-node .x-tree-drag-append a span {
+ background-color: #ddd;
+ border-color: gray;
+}
+
+.x-tree-node .x-tree-node-over {
+ background-color: #eee;
+}
+
+.x-tree-node .x-tree-selected {
+ background-color: #ddd;
+}
+
+.x-tree-drop-ok-append .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-add.gif);
+}
+
+.x-tree-drop-ok-above .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-over.gif);
+}
+
+.x-tree-drop-ok-below .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-under.gif);
+}
+
+.x-tree-drop-ok-between .x-dd-drop-icon {
+ background-image: url(../images/default/tree/drop-between.gif);
+}
+.x-date-picker {
+ border-color: #585858;
+ background-color: #fff;
+}
+
+.x-date-middle,
+.x-date-left,
+.x-date-right {
+ background-image: url(../images/gray/shared/hd-sprite.gif);
+ color: #fff;
+ font: bold 11px 'sans serif', tahoma, verdana, helvetica;
+}
+
+.x-date-middle .x-btn .x-btn-text {
+ color: #fff;
+}
+
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+ background-image: url(../images/gray/toolbar/btn-arrow-light.gif);
+}
+
+.x-date-right a {
+ background-image: url(../images/gray/shared/right-btn.gif);
+}
+
+.x-date-left a {
+ background-image: url(../images/gray/shared/left-btn.gif);
+}
+
+.x-date-inner th {
+ background-color: #d8d8d8;
+ background-image: url(../images/gray/panel/white-top-bottom.gif);
+ border-bottom-color: #afafaf;
+ font: normal 10px arial, helvetica, tahoma, sans-serif;
+ color: #595959;
+}
+
+.x-date-inner td {
+ border-color: #fff;
+}
+
+.x-date-inner a {
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+ color: #000;
+}
+
+.x-date-inner .x-date-active {
+ color: #000;
+}
+
+.x-date-inner .x-date-selected a {
+ background-image: none;
+ background-color: #d8d8d8;
+ border-color: #dcdcdc;
+}
+
+.x-date-inner .x-date-today a {
+ border-color: darkred;
+}
+
+.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: #aaa;
+}
+
+.x-date-bottom {
+ border-top-color: #afafaf;
+ background-color: #d8d8d8;
+ background: #d8d8d8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px;
+}
+
+.x-date-inner a:hover,
+.x-date-inner .x-date-disabled a:hover {
+ color: #000;
+ background-color: #d8d8d8;
+}
+
+.x-date-inner .x-date-disabled a {
+ background-color: #eee;
+ color: #bbb;
+}
+
+.x-date-mmenu {
+ background-color: #eee !important;
+}
+
+.x-date-mmenu .x-menu-item {
+ font-size: 10px;
+ color: #000;
+}
+
+.x-date-mp {
+ background-color: #fff;
+}
+
+.x-date-mp td {
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns button {
+ background-color: #4e565f;
+ color: #fff;
+ border-color: #c0c0c0 #434343 #434343 #c0c0c0;
+ font: normal 11px arial, helvetica, tahoma, sans-serif;
+}
+
+.x-date-mp-btns {
+ background-color: #d8d8d8;
+ background: #d8d8d8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px;
+}
+
+.x-date-mp-btns td {
+ border-top-color: #afafaf;
+}
+
+td.x-date-mp-month a,
+td.x-date-mp-year a {
+ color: #333;
+}
+
+td.x-date-mp-month a:hover,
+td.x-date-mp-year a:hover {
+ color: #333;
+ background-color: #fdfdfd;
+}
+
+td.x-date-mp-sel a {
+ background-color: #d8d8d8;
+ background: #d8d8d8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px;
+ border-color: #dcdcdc;
+}
+
+.x-date-mp-ybtn a {
+ background-image: url(../images/gray/panel/tool-sprites.gif);
+}
+
+td.x-date-mp-sep {
+ border-right-color: #d7d7d7;
+}
+.x-tip .x-tip-close {
+ background-image: url(../images/gray/qtip/close.gif);
+}
+
+.x-tip .x-tip-tc,
+.x-tip .x-tip-tl,
+.x-tip .x-tip-tr,
+.x-tip .x-tip-bc,
+.x-tip .x-tip-bl,
+.x-tip .x-tip-br,
+.x-tip .x-tip-ml,
+.x-tip .x-tip-mr {
+ background-image: url(../images/gray/qtip/tip-sprite.gif);
+}
+
+.x-tip .x-tip-mc {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-tip .x-tip-ml {
+ background-color: #fff;
+}
+
+.x-tip .x-tip-header-text {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #444;
+}
+
+.x-tip .x-tip-body {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ color: #444;
+}
+
+.x-form-invalid-tip .x-tip-tc,
+.x-form-invalid-tip .x-tip-tl,
+.x-form-invalid-tip .x-tip-tr,
+.x-form-invalid-tip .x-tip-bc,
+.x-form-invalid-tip .x-tip-bl,
+.x-form-invalid-tip .x-tip-br,
+.x-form-invalid-tip .x-tip-ml,
+.x-form-invalid-tip .x-tip-mr {
+ background-image: url(../images/default/form/error-tip-corners.gif);
+}
+
+.x-form-invalid-tip .x-tip-body {
+ background-image: url(../images/default/form/exclamation.gif);
+}
+
+.x-tip-anchor {
+ background-image: url(../images/gray/qtip/tip-anchor-sprite.gif);
+}
+.x-menu {
+ background-color: #f0f0f0;
+ background-image: url(../images/default/menu/menu.gif);
+}
+
+.x-menu-floating {
+ border-color: #7d7d7d;
+}
+
+.x-menu-nosep {
+ background-image: none;
+}
+
+.x-menu-list-item {
+ font: normal 11px arial, tahoma, sans-serif;
+}
+
+.x-menu-item-arrow {
+ background-image: url(../images/gray/menu/menu-parent.gif);
+}
+
+.x-menu-sep {
+ background-color: #e0e0e0;
+ border-bottom-color: #fff;
+}
+
+a.x-menu-item {
+ color: #222;
+}
+
+.x-menu-item-active {
+ background-image: url(../images/gray/menu/item-over.gif);
+ background-color: #f1f1f1;
+ border-color: #acacac;
+}
+
+.x-menu-item-active a.x-menu-item {
+ border-color: #acacac;
+}
+
+.x-menu-check-item .x-menu-item-icon {
+ background-image: url(../images/default/menu/unchecked.gif);
+}
+
+.x-menu-item-checked .x-menu-item-icon {
+ background-image: url(../images/default/menu/checked.gif);
+}
+
+.x-menu-item-checked .x-menu-group-item .x-menu-item-icon {
+ background-image: url(../images/gray/menu/group-checked.gif);
+}
+
+.x-menu-group-item .x-menu-item-icon {
+ background-image: none;
+}
+
+.x-menu-plain {
+ background-color: #fff !important;
+}
+
+.x-menu .x-date-picker {
+ border-color: #afafaf;
+}
+
+.x-cycle-menu .x-menu-item-checked {
+ border-color: #b9b9b9 !important;
+ background-color: #f1f1f1;
+}
+
+.x-menu-scroller-top {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+
+.x-menu-scroller-bottom {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+.x-box-tl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-tc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-tr {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-ml {
+ background-image: url(../images/default/box/l.gif);
+}
+
+.x-box-mc {
+ background-color: #eee;
+ background-image: url(../images/default/box/tb.gif);
+ 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;
+}
+
+.x-box-mr {
+ background-image: url(../images/default/box/r.gif);
+}
+
+.x-box-bl {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.x-box-bc {
+ background-image: url(../images/default/box/tb.gif);
+}
+
+.x-box-br {
+ background-image: url(../images/default/box/corners.gif);
+}
+
+.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(../images/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(../images/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(../images/default/box/l-blue.gif);
+}
+
+.x-box-blue .x-box-mr {
+ background-image: url(../images/default/box/r-blue.gif);
+}
+.x-combo-list {
+ border-color: #ccc;
+ background-color: #ddd;
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-combo-list-inner {
+ background-color: #fff;
+}
+
+.x-combo-list-hd {
+ font: bold 11px tahoma, arial, helvetica, sans-serif;
+ color: #333;
+ background-image: url(../images/default/layout/panel-title-light-bg.gif);
+ border-bottom-color: #bcbcbc;
+}
+
+.x-resizable-pinned .x-combo-list-inner {
+ border-bottom-color: #bebebe;
+}
+
+.x-combo-list-item {
+ border-color: #fff;
+}
+
+.x-combo-list .x-combo-selected {
+ border-color: #777 !important;
+ background-color: #f0f0f0;
+}
+
+.x-combo-list .x-toolbar {
+ border-top-color: #bcbcbc;
+}
+
+.x-combo-list-small {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-panel {
+ border-color: #d0d0d0;
+}
+
+.x-panel-header {
+ color: #333;
+ font-weight: bold;
+ font-size: 11px;
+ font-family: tahoma, arial, verdana, sans-serif;
+ border-color: #d0d0d0;
+ background-image: url(../images/gray/panel/white-top-bottom.gif);
+}
+
+.x-panel-body {
+ border-color: #d0d0d0;
+ background-color: #fff;
+}
+
+.x-panel-bbar .x-toolbar,
+.x-panel-tbar .x-toolbar {
+ border-color: #d0d0d0;
+}
+
+.x-panel-tbar-noheader .x-toolbar,
+.x-panel-mc .x-panel-tbar .x-toolbar {
+ border-top-color: #d0d0d0;
+}
+
+.x-panel-body-noheader,
+.x-panel-mc .x-panel-body {
+ border-top-color: #d0d0d0;
+}
+
+.x-panel-tl .x-panel-header {
+ color: #333;
+ font: bold 11px tahoma, arial, verdana, sans-serif;
+}
+
+.x-panel-tc {
+ background-image: url(../images/gray/panel/top-bottom.gif);
+}
+
+.x-panel-tl,
+.x-panel-tr,
+.x-panel-bl,
+.x-panel-br {
+ background-image: url(../images/gray/panel/corners-sprite.gif);
+ border-bottom-color: #d0d0d0;
+}
+
+.x-panel-bc {
+ background-image: url(../images/gray/panel/top-bottom.gif);
+}
+
+.x-panel-mc {
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-color: #f1f1f1;
+}
+
+.x-panel-ml {
+ background-color: #fff;
+ background-image: url(../images/gray/panel/left-right.gif);
+}
+
+.x-panel-mr {
+ background-image: url(../images/gray/panel/left-right.gif);
+}
+
+.x-tool {
+ background-image: url(../images/gray/panel/tool-sprites.gif);
+}
+
+.x-panel-ghost {
+ background-color: #f2f2f2;
+}
+
+.x-panel-ghost ul {
+ border-color: #d0d0d0;
+}
+
+.x-panel-dd-spacer {
+ border-color: #d0d0d0;
+}
+
+.x-panel-fbar td,
+.x-panel-fbar span,
+.x-panel-fbar input,
+.x-panel-fbar div,
+.x-panel-fbar select,
+.x-panel-fbar label {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-window-proxy {
+ background-color: #fcfcfc;
+ border-color: #d0d0d0;
+}
+
+.x-window-tl .x-window-header {
+ color: #555;
+ font: bold 11px tahoma, arial, verdana, sans-serif;
+}
+
+.x-window-tc {
+ background-image: url(../images/gray/window/top-bottom.png);
+}
+
+.x-window-tl {
+ background-image: url(../images/gray/window/left-corners.png);
+}
+
+.x-window-tr {
+ background-image: url(../images/gray/window/right-corners.png);
+}
+
+.x-window-bc {
+ background-image: url(../images/gray/window/top-bottom.png);
+}
+
+.x-window-bl {
+ background-image: url(../images/gray/window/left-corners.png);
+}
+
+.x-window-br {
+ background-image: url(../images/gray/window/right-corners.png);
+}
+
+.x-window-mc {
+ border-color: #d0d0d0;
+ font: normal 11px tahoma, arial, helvetica, sans-serif;
+ background-color: #e8e8e8;
+}
+
+.x-window-ml {
+ background-image: url(../images/gray/window/left-right.png);
+}
+
+.x-window-mr {
+ background-image: url(../images/gray/window/left-right.png);
+}
+
+.x-window-maximized .x-window-tc {
+ background-color: #fff;
+}
+
+.x-window-bbar .x-toolbar {
+ border-top-color: #d0d0d0;
+}
+
+.x-panel-ghost .x-window-tl {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-panel-collapsed .x-window-tl {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-dlg-mask {
+ background-color: #ccc;
+}
+
+.x-window-plain .x-window-mc {
+ background-color: #e8e8e8;
+ border-color: #d0d0d0 #eeeeee #eeeeee #d0d0d0;
+}
+
+.x-window-plain .x-window-body {
+ border-color: #eeeeee #d0d0d0 #d0d0d0 #eeeeee;
+}
+
+body.x-body-masked .x-window-plain .x-window-mc {
+ background-color: #e4e4e4;
+}
+.x-html-editor-wrap {
+ border-color: #bcbcbc;
+ background-color: #fff;
+}
+.x-html-editor-tb .x-btn-text {
+ background-image: url(../images/default/editor/tb-sprite.gif);
+}
+.x-panel-noborder .x-panel-header-noborder {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+ border-top-color: #d0d0d0;
+}
+
+.x-tab-panel-bbar-noborder .x-toolbar {
+ border-top-color: #d0d0d0;
+}
+
+.x-tab-panel-tbar-noborder .x-toolbar {
+ border-bottom-color: #d0d0d0;
+}
+
+.x-border-layout-ct {
+ background-color: #f0f0f0;
+}
+.x-border-layout-ct {
+ background-color: #f0f0f0;
+}
+
+.x-accordion-hd {
+ color: #222;
+ font-weight: normal;
+ background-image: url(../images/gray/panel/light-hd.gif);
+}
+
+.x-layout-collapsed {
+ background-color: #dfdfdf;
+ border-color: #d0d0d0;
+}
+
+.x-layout-collapsed-over {
+ background-color: #e7e7e7;
+}
+
+.x-layout-split-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+.x-layout-split-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+.x-layout-split-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+.x-layout-split-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-west .x-layout-mini {
+ background-image: url(../images/default/layout/mini-right.gif);
+}
+
+.x-layout-cmini-east .x-layout-mini {
+ background-image: url(../images/default/layout/mini-left.gif);
+}
+
+.x-layout-cmini-north .x-layout-mini {
+ background-image: url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-layout-cmini-south .x-layout-mini {
+ background-image: url(../images/default/layout/mini-top.gif);
+}
+.x-progress-wrap {
+ border-color: #8e8e8e;
+}
+
+.x-progress-inner {
+ background-color: #e7e7e7;
+ background-image: url(../images/gray/qtip/bg.gif);
+}
+
+.x-progress-bar {
+ background-color: #bcbcbc;
+ background-image: url(../images/gray/progress/progress-bg.gif);
+ border-top-color: #e2e2e2;
+ border-bottom-color: #a4a4a4;
+ border-right-color: #a4a4a4;
+}
+
+.x-progress-text {
+ font-size: 11px;
+ font-weight: bold;
+ color: #fff;
+}
+
+.x-progress-text-back {
+ color: #5f5f5f;
+}
+.x-list-header {
+ background-color: #f9f9f9;
+ background-image: url(../images/gray/grid/grid3-hrow2.gif);
+}
+
+.x-list-header-inner div em {
+ border-left-color: #ddd;
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-list-body dt em {
+ font: normal 11px arial, tahoma, helvetica, sans-serif;
+}
+
+.x-list-over {
+ background-color: #eee;
+}
+
+.x-list-selected {
+ background-color: #f0f0f0;
+}
+
+.x-list-resizer {
+ border-left-color: #555;
+ border-right-color: #555;
+}
+
+.x-list-header-inner em.sort-asc,
+.x-list-header-inner em.sort-desc {
+ background-image: url(../images/gray/grid/sort-hd.gif);
+ border-color: #d0d0d0;
+}
+.x-slider-horz,
+.x-slider-horz .x-slider-end,
+.x-slider-horz .x-slider-inner {
+ background-image: url(../images/default/slider/slider-bg.png);
+}
+
+.x-slider-horz .x-slider-thumb {
+ background-image: url(../images/gray/slider/slider-thumb.png);
+}
+
+.x-slider-vert,
+.x-slider-vert .x-slider-end,
+.x-slider-vert .x-slider-inner {
+ background-image: url(../images/default/slider/slider-v-bg.png);
+}
+
+.x-slider-vert .x-slider-thumb {
+ background-image: url(../images/gray/slider/slider-v-thumb.png);
+}
+.x-window-dlg .ext-mb-text,
+.x-window-dlg .x-window-header-text {
+ font-size: 12px;
+}
+
+.x-window-dlg .ext-mb-textarea {
+ font: normal 12px tahoma, arial, helvetica, sans-serif;
+}
+
+.x-window-dlg .x-msg-box-wait {
+ background-image: url(../images/default/grid/loading.gif);
+}
+
+.x-window-dlg .ext-mb-info {
+ background-image: url(../images/gray/window/icon-info.gif);
+}
+
+.x-window-dlg .ext-mb-warning {
+ background-image: url(../images/gray/window/icon-warning.gif);
+}
+
+.x-window-dlg .ext-mb-question {
+ background-image: url(../images/gray/window/icon-question.gif);
+}
+
+.x-window-dlg .ext-mb-error {
+ background-image: url(../images/gray/window/icon-error.gif);
+}
diff --git a/deluge/ui/web/themes/images/access/box/corners-blue.gif b/deluge/ui/web/themes/images/access/box/corners-blue.gif
new file mode 100644
index 0000000..fa419b5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/corners-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/corners.gif b/deluge/ui/web/themes/images/access/box/corners.gif
new file mode 100644
index 0000000..8aa8cae
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/corners.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/l-blue.gif b/deluge/ui/web/themes/images/access/box/l-blue.gif
new file mode 100644
index 0000000..5ed7f00
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/l-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/l.gif b/deluge/ui/web/themes/images/access/box/l.gif
new file mode 100644
index 0000000..0160f97
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/l.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/r-blue.gif b/deluge/ui/web/themes/images/access/box/r-blue.gif
new file mode 100644
index 0000000..3ea5cae
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/r-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/r.gif b/deluge/ui/web/themes/images/access/box/r.gif
new file mode 100644
index 0000000..34237f6
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/r.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/tb-blue.gif b/deluge/ui/web/themes/images/access/box/tb-blue.gif
new file mode 100644
index 0000000..4b1382c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/tb-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/box/tb.gif b/deluge/ui/web/themes/images/access/box/tb.gif
new file mode 100644
index 0000000..435889b
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/box/tb.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/arrow.gif b/deluge/ui/web/themes/images/access/button/arrow.gif
new file mode 100644
index 0000000..087b450
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/btn.gif b/deluge/ui/web/themes/images/access/button/btn.gif
new file mode 100644
index 0000000..3e705ba
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/group-cs.gif b/deluge/ui/web/themes/images/access/button/group-cs.gif
new file mode 100644
index 0000000..aaf0d46
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/group-cs.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/group-lr.gif b/deluge/ui/web/themes/images/access/button/group-lr.gif
new file mode 100644
index 0000000..374ea75
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/group-lr.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/group-tb.gif b/deluge/ui/web/themes/images/access/button/group-tb.gif
new file mode 100644
index 0000000..50a9972
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/group-tb.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow-b-noline.gif b/deluge/ui/web/themes/images/access/button/s-arrow-b-noline.gif
new file mode 100644
index 0000000..644e9f3
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow-b-noline.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow-b.gif b/deluge/ui/web/themes/images/access/button/s-arrow-b.gif
new file mode 100644
index 0000000..ba55d0a
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow-b.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow-bo.gif b/deluge/ui/web/themes/images/access/button/s-arrow-bo.gif
new file mode 100644
index 0000000..c672b60
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow-bo.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow-noline.gif b/deluge/ui/web/themes/images/access/button/s-arrow-noline.gif
new file mode 100644
index 0000000..f3cd351
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow-noline.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow-o.gif b/deluge/ui/web/themes/images/access/button/s-arrow-o.gif
new file mode 100644
index 0000000..4bdafd0
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow-o.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/button/s-arrow.gif b/deluge/ui/web/themes/images/access/button/s-arrow.gif
new file mode 100644
index 0000000..a77be7f
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/button/s-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/editor/tb-sprite.gif b/deluge/ui/web/themes/images/access/editor/tb-sprite.gif
new file mode 100644
index 0000000..bd4011d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/editor/tb-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/checkbox.gif b/deluge/ui/web/themes/images/access/form/checkbox.gif
new file mode 100644
index 0000000..835b346
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/checkbox.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/clear-trigger.gif b/deluge/ui/web/themes/images/access/form/clear-trigger.gif
new file mode 100644
index 0000000..9bfd184
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/clear-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/clear-trigger.psd b/deluge/ui/web/themes/images/access/form/clear-trigger.psd
new file mode 100644
index 0000000..fcd7944
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/clear-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/date-trigger.gif b/deluge/ui/web/themes/images/access/form/date-trigger.gif
new file mode 100644
index 0000000..048506d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/date-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/date-trigger.psd b/deluge/ui/web/themes/images/access/form/date-trigger.psd
new file mode 100644
index 0000000..d9f9be1
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/date-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/error-tip-corners.gif b/deluge/ui/web/themes/images/access/form/error-tip-corners.gif
new file mode 100644
index 0000000..6ea4c38
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/error-tip-corners.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/exclamation.gif b/deluge/ui/web/themes/images/access/form/exclamation.gif
new file mode 100644
index 0000000..daa88b8
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/exclamation.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/radio.gif b/deluge/ui/web/themes/images/access/form/radio.gif
new file mode 100644
index 0000000..36bb91d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/radio.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/search-trigger.gif b/deluge/ui/web/themes/images/access/form/search-trigger.gif
new file mode 100644
index 0000000..ab8b3b4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/search-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/search-trigger.psd b/deluge/ui/web/themes/images/access/form/search-trigger.psd
new file mode 100644
index 0000000..4f92b72
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/search-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/text-bg.gif b/deluge/ui/web/themes/images/access/form/text-bg.gif
new file mode 100644
index 0000000..4ce90bb
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/text-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/trigger-tpl.gif b/deluge/ui/web/themes/images/access/form/trigger-tpl.gif
new file mode 100644
index 0000000..2574ead
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/trigger-tpl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/trigger.gif b/deluge/ui/web/themes/images/access/form/trigger.gif
new file mode 100644
index 0000000..bd25572
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/form/trigger.psd b/deluge/ui/web/themes/images/access/form/trigger.psd
new file mode 100644
index 0000000..c078133
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/form/trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/arrow-left-white.gif b/deluge/ui/web/themes/images/access/grid/arrow-left-white.gif
new file mode 100644
index 0000000..63088f5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/arrow-left-white.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/arrow-right-white.gif b/deluge/ui/web/themes/images/access/grid/arrow-right-white.gif
new file mode 100644
index 0000000..e9e0678
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/arrow-right-white.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/col-move-bottom.gif b/deluge/ui/web/themes/images/access/grid/col-move-bottom.gif
new file mode 100644
index 0000000..cc1e473
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/col-move-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/col-move-top.gif b/deluge/ui/web/themes/images/access/grid/col-move-top.gif
new file mode 100644
index 0000000..58ff32c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/col-move-top.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/columns.gif b/deluge/ui/web/themes/images/access/grid/columns.gif
new file mode 100644
index 0000000..2d3a823
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/columns.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/dirty.gif b/deluge/ui/web/themes/images/access/grid/dirty.gif
new file mode 100644
index 0000000..d524ee5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/dirty.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/done.gif b/deluge/ui/web/themes/images/access/grid/done.gif
new file mode 100644
index 0000000..a937cb2
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/done.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/drop-no.gif b/deluge/ui/web/themes/images/access/grid/drop-no.gif
new file mode 100644
index 0000000..31a332b
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/drop-no.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/drop-yes.gif b/deluge/ui/web/themes/images/access/grid/drop-yes.gif
new file mode 100644
index 0000000..926010e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/drop-yes.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/footer-bg.gif b/deluge/ui/web/themes/images/access/grid/footer-bg.gif
new file mode 100644
index 0000000..126120f
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/footer-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-blue-hd.gif b/deluge/ui/web/themes/images/access/grid/grid-blue-hd.gif
new file mode 100644
index 0000000..862094e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-blue-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-blue-split.gif b/deluge/ui/web/themes/images/access/grid/grid-blue-split.gif
new file mode 100644
index 0000000..1b0bae3
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-blue-split.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-hrow.gif b/deluge/ui/web/themes/images/access/grid/grid-hrow.gif
new file mode 100644
index 0000000..6374104
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-hrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-loading.gif b/deluge/ui/web/themes/images/access/grid/grid-loading.gif
new file mode 100644
index 0000000..d112c54
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-split.gif b/deluge/ui/web/themes/images/access/grid/grid-split.gif
new file mode 100644
index 0000000..c76a16e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-split.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid-vista-hd.gif b/deluge/ui/web/themes/images/access/grid/grid-vista-hd.gif
new file mode 100644
index 0000000..d097263
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid-vista-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid3-hd-btn.gif b/deluge/ui/web/themes/images/access/grid/grid3-hd-btn.gif
new file mode 100644
index 0000000..9ecd650
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid3-hd-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid3-hrow-over.gif b/deluge/ui/web/themes/images/access/grid/grid3-hrow-over.gif
new file mode 100644
index 0000000..0405f6c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid3-hrow-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid3-hrow.gif b/deluge/ui/web/themes/images/access/grid/grid3-hrow.gif
new file mode 100644
index 0000000..509737a
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid3-hrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid3-special-col-bg.gif b/deluge/ui/web/themes/images/access/grid/grid3-special-col-bg.gif
new file mode 100644
index 0000000..8ec57f5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid3-special-col-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/grid3-special-col-sel-bg.gif b/deluge/ui/web/themes/images/access/grid/grid3-special-col-sel-bg.gif
new file mode 100644
index 0000000..93a9ca6
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/grid3-special-col-sel-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/group-by.gif b/deluge/ui/web/themes/images/access/grid/group-by.gif
new file mode 100644
index 0000000..d6075bb
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/group-by.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/group-collapse.gif b/deluge/ui/web/themes/images/access/grid/group-collapse.gif
new file mode 100644
index 0000000..9bd255e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/group-collapse.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/group-expand-sprite.gif b/deluge/ui/web/themes/images/access/grid/group-expand-sprite.gif
new file mode 100644
index 0000000..f230489
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/group-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/group-expand.gif b/deluge/ui/web/themes/images/access/grid/group-expand.gif
new file mode 100644
index 0000000..fd22e6b
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/group-expand.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hd-pop.gif b/deluge/ui/web/themes/images/access/grid/hd-pop.gif
new file mode 100644
index 0000000..eb8ba79
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hd-pop.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-asc.gif b/deluge/ui/web/themes/images/access/grid/hmenu-asc.gif
new file mode 100644
index 0000000..8917e0e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-asc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-desc.gif b/deluge/ui/web/themes/images/access/grid/hmenu-desc.gif
new file mode 100644
index 0000000..f26b7c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-desc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-lock.gif b/deluge/ui/web/themes/images/access/grid/hmenu-lock.gif
new file mode 100644
index 0000000..1596126
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-lock.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-lock.png b/deluge/ui/web/themes/images/access/grid/hmenu-lock.png
new file mode 100644
index 0000000..5d33c09
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-lock.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-unlock.gif b/deluge/ui/web/themes/images/access/grid/hmenu-unlock.gif
new file mode 100644
index 0000000..af59cf9
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-unlock.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/hmenu-unlock.png b/deluge/ui/web/themes/images/access/grid/hmenu-unlock.png
new file mode 100644
index 0000000..0371ca4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/hmenu-unlock.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/invalid_line.gif b/deluge/ui/web/themes/images/access/grid/invalid_line.gif
new file mode 100644
index 0000000..025cffc
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/invalid_line.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/loading.gif b/deluge/ui/web/themes/images/access/grid/loading.gif
new file mode 100644
index 0000000..e846e1d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/mso-hd.gif b/deluge/ui/web/themes/images/access/grid/mso-hd.gif
new file mode 100644
index 0000000..669f3cf
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/mso-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/nowait.gif b/deluge/ui/web/themes/images/access/grid/nowait.gif
new file mode 100644
index 0000000..4c5862c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/nowait.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-first-disabled.gif b/deluge/ui/web/themes/images/access/grid/page-first-disabled.gif
new file mode 100644
index 0000000..e4df7a7
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-first-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-first.gif b/deluge/ui/web/themes/images/access/grid/page-first.gif
new file mode 100644
index 0000000..aa0a822
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-first.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-last-disabled.gif b/deluge/ui/web/themes/images/access/grid/page-last-disabled.gif
new file mode 100644
index 0000000..67fee75
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-last-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-last.gif b/deluge/ui/web/themes/images/access/grid/page-last.gif
new file mode 100644
index 0000000..e0cf111
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-last.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-next-disabled.gif b/deluge/ui/web/themes/images/access/grid/page-next-disabled.gif
new file mode 100644
index 0000000..e3e8e87
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-next-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-next.gif b/deluge/ui/web/themes/images/access/grid/page-next.gif
new file mode 100644
index 0000000..69899c0
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-next.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-prev-disabled.gif b/deluge/ui/web/themes/images/access/grid/page-prev-disabled.gif
new file mode 100644
index 0000000..0f94bf7
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-prev-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/page-prev.gif b/deluge/ui/web/themes/images/access/grid/page-prev.gif
new file mode 100644
index 0000000..289b126
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/page-prev.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/pick-button.gif b/deluge/ui/web/themes/images/access/grid/pick-button.gif
new file mode 100644
index 0000000..6957924
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/pick-button.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/refresh.gif b/deluge/ui/web/themes/images/access/grid/refresh.gif
new file mode 100644
index 0000000..8435d1e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/refresh.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/row-check-sprite.gif b/deluge/ui/web/themes/images/access/grid/row-check-sprite.gif
new file mode 100644
index 0000000..6101164
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/row-check-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/row-expand-sprite.gif b/deluge/ui/web/themes/images/access/grid/row-expand-sprite.gif
new file mode 100644
index 0000000..6f4d874
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/row-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/row-over.gif b/deluge/ui/web/themes/images/access/grid/row-over.gif
new file mode 100644
index 0000000..b288e38
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/row-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/row-sel.gif b/deluge/ui/web/themes/images/access/grid/row-sel.gif
new file mode 100644
index 0000000..98209e6
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/row-sel.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/sort-hd.gif b/deluge/ui/web/themes/images/access/grid/sort-hd.gif
new file mode 100644
index 0000000..681628f
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/sort-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/sort_asc.gif b/deluge/ui/web/themes/images/access/grid/sort_asc.gif
new file mode 100644
index 0000000..371f5e4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/sort_asc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/sort_desc.gif b/deluge/ui/web/themes/images/access/grid/sort_desc.gif
new file mode 100644
index 0000000..000e363
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/sort_desc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/grid/wait.gif b/deluge/ui/web/themes/images/access/grid/wait.gif
new file mode 100644
index 0000000..471c1a4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/grid/wait.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/checked.gif b/deluge/ui/web/themes/images/access/menu/checked.gif
new file mode 100644
index 0000000..fad5893
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/checked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/group-checked.gif b/deluge/ui/web/themes/images/access/menu/group-checked.gif
new file mode 100644
index 0000000..d8b08f5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/group-checked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/item-over.gif b/deluge/ui/web/themes/images/access/menu/item-over.gif
new file mode 100644
index 0000000..0167839
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/item-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/menu-parent.gif b/deluge/ui/web/themes/images/access/menu/menu-parent.gif
new file mode 100644
index 0000000..49286cd
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/menu-parent.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/menu.gif b/deluge/ui/web/themes/images/access/menu/menu.gif
new file mode 100644
index 0000000..9bb3960
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/menu.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/menu/unchecked.gif b/deluge/ui/web/themes/images/access/menu/unchecked.gif
new file mode 100644
index 0000000..43823e5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/menu/unchecked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/corners-sprite.gif b/deluge/ui/web/themes/images/access/panel/corners-sprite.gif
new file mode 100644
index 0000000..43e2862
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/left-right.gif b/deluge/ui/web/themes/images/access/panel/left-right.gif
new file mode 100644
index 0000000..51850b7
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/light-hd.gif b/deluge/ui/web/themes/images/access/panel/light-hd.gif
new file mode 100644
index 0000000..660bedb
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/light-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/tool-sprite-tpl.gif b/deluge/ui/web/themes/images/access/panel/tool-sprite-tpl.gif
new file mode 100644
index 0000000..e647867
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/tool-sprite-tpl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/tool-sprites.gif b/deluge/ui/web/themes/images/access/panel/tool-sprites.gif
new file mode 100644
index 0000000..a3ffe58
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/tool-sprites.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/tools-sprites-trans.gif b/deluge/ui/web/themes/images/access/panel/tools-sprites-trans.gif
new file mode 100644
index 0000000..ead931e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/tools-sprites-trans.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/top-bottom.gif b/deluge/ui/web/themes/images/access/panel/top-bottom.gif
new file mode 100644
index 0000000..6b2649d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/white-corners-sprite.gif b/deluge/ui/web/themes/images/access/panel/white-corners-sprite.gif
new file mode 100644
index 0000000..22d4bba
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/white-corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/white-left-right.gif b/deluge/ui/web/themes/images/access/panel/white-left-right.gif
new file mode 100644
index 0000000..51850b7
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/white-left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/panel/white-top-bottom.gif b/deluge/ui/web/themes/images/access/panel/white-top-bottom.gif
new file mode 100644
index 0000000..08f8fae
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/panel/white-top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/progress/progress-bg.gif b/deluge/ui/web/themes/images/access/progress/progress-bg.gif
new file mode 100644
index 0000000..55629b1
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/progress/progress-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/qtip/close.gif b/deluge/ui/web/themes/images/access/qtip/close.gif
new file mode 100644
index 0000000..69ab915
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/qtip/close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/qtip/tip-anchor-sprite.gif b/deluge/ui/web/themes/images/access/qtip/tip-anchor-sprite.gif
new file mode 100644
index 0000000..f46d31d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/qtip/tip-anchor-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/qtip/tip-sprite.gif b/deluge/ui/web/themes/images/access/qtip/tip-sprite.gif
new file mode 100644
index 0000000..9f6a629
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/qtip/tip-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/shared/glass-bg.gif b/deluge/ui/web/themes/images/access/shared/glass-bg.gif
new file mode 100644
index 0000000..ed3c886
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/shared/glass-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/shared/hd-sprite.gif b/deluge/ui/web/themes/images/access/shared/hd-sprite.gif
new file mode 100644
index 0000000..446be92
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/shared/hd-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/shared/left-btn.gif b/deluge/ui/web/themes/images/access/shared/left-btn.gif
new file mode 100644
index 0000000..0622439
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/shared/left-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/shared/right-btn.gif b/deluge/ui/web/themes/images/access/shared/right-btn.gif
new file mode 100644
index 0000000..5e3215d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/shared/right-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/e-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/e-handle-dark.gif
new file mode 100644
index 0000000..70aad3f
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/e-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/e-handle.gif b/deluge/ui/web/themes/images/access/sizer/e-handle.gif
new file mode 100644
index 0000000..52c045e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/e-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/ne-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/ne-handle-dark.gif
new file mode 100644
index 0000000..3a30ca2
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/ne-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/ne-handle.gif b/deluge/ui/web/themes/images/access/sizer/ne-handle.gif
new file mode 100644
index 0000000..e48f9f9
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/ne-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/nw-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/nw-handle-dark.gif
new file mode 100644
index 0000000..5ea8b51
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/nw-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/nw-handle.gif b/deluge/ui/web/themes/images/access/sizer/nw-handle.gif
new file mode 100644
index 0000000..65d5cc2
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/nw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/s-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/s-handle-dark.gif
new file mode 100644
index 0000000..421b534
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/s-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/s-handle.gif b/deluge/ui/web/themes/images/access/sizer/s-handle.gif
new file mode 100644
index 0000000..2b635de
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/s-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/se-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/se-handle-dark.gif
new file mode 100644
index 0000000..881a5c4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/se-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/se-handle.gif b/deluge/ui/web/themes/images/access/sizer/se-handle.gif
new file mode 100644
index 0000000..5f1e3b8
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/se-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/square.gif b/deluge/ui/web/themes/images/access/sizer/square.gif
new file mode 100644
index 0000000..4dc5a2d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/square.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/sw-handle-dark.gif b/deluge/ui/web/themes/images/access/sizer/sw-handle-dark.gif
new file mode 100644
index 0000000..030d8f8
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/sw-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/sizer/sw-handle.gif b/deluge/ui/web/themes/images/access/sizer/sw-handle.gif
new file mode 100644
index 0000000..79bcb84
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/sizer/sw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/slider/slider-bg.png b/deluge/ui/web/themes/images/access/slider/slider-bg.png
new file mode 100644
index 0000000..1ba12ad
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/slider/slider-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/slider/slider-thumb.png b/deluge/ui/web/themes/images/access/slider/slider-thumb.png
new file mode 100644
index 0000000..1712edf
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/slider/slider-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/slider/slider-v-bg.png b/deluge/ui/web/themes/images/access/slider/slider-v-bg.png
new file mode 100644
index 0000000..6944f9e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/slider/slider-v-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/slider/slider-v-thumb.png b/deluge/ui/web/themes/images/access/slider/slider-v-thumb.png
new file mode 100644
index 0000000..df9cfc9
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/slider/slider-v-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/scroll-left.gif b/deluge/ui/web/themes/images/access/tabs/scroll-left.gif
new file mode 100644
index 0000000..71a2e88
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/scroll-left.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/scroll-right.gif b/deluge/ui/web/themes/images/access/tabs/scroll-right.gif
new file mode 100644
index 0000000..8f3d659
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/scroll-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-left-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-left-bg.gif
new file mode 100644
index 0000000..687af2b
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-right-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-right-bg.gif
new file mode 100644
index 0000000..3c1b3eb
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-btm-inactive-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-btm-left-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-btm-left-bg.gif
new file mode 100644
index 0000000..e5f827a
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-btm-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-btm-right-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-btm-right-bg.gif
new file mode 100644
index 0000000..2551f4c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-btm-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-close.gif b/deluge/ui/web/themes/images/access/tabs/tab-close.gif
new file mode 100644
index 0000000..ef9a7c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-strip-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-strip-bg.gif
new file mode 100644
index 0000000..fc1fdcd
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-strip-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tab-strip-btm-bg.gif b/deluge/ui/web/themes/images/access/tabs/tab-strip-btm-bg.gif
new file mode 100644
index 0000000..a151553
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tab-strip-btm-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tabs/tabs-sprite.gif b/deluge/ui/web/themes/images/access/tabs/tabs-sprite.gif
new file mode 100644
index 0000000..8194001
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tabs/tabs-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/bg.gif b/deluge/ui/web/themes/images/access/toolbar/bg.gif
new file mode 100644
index 0000000..b67a54e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/btn-arrow-light.gif b/deluge/ui/web/themes/images/access/toolbar/btn-arrow-light.gif
new file mode 100644
index 0000000..b0e24b5
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/btn-arrow-light.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/btn-arrow.gif b/deluge/ui/web/themes/images/access/toolbar/btn-arrow.gif
new file mode 100644
index 0000000..8acb460
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/btn-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/btn-over-bg.gif b/deluge/ui/web/themes/images/access/toolbar/btn-over-bg.gif
new file mode 100644
index 0000000..ee2dd98
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/btn-over-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/gray-bg.gif b/deluge/ui/web/themes/images/access/toolbar/gray-bg.gif
new file mode 100644
index 0000000..bd49438
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/gray-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/more.gif b/deluge/ui/web/themes/images/access/toolbar/more.gif
new file mode 100644
index 0000000..4f01020
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/more.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/s-arrow-bo.gif b/deluge/ui/web/themes/images/access/toolbar/s-arrow-bo.gif
new file mode 100644
index 0000000..1505edd
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/s-arrow-bo.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/tb-btn-sprite.gif b/deluge/ui/web/themes/images/access/toolbar/tb-btn-sprite.gif
new file mode 100644
index 0000000..19bbef3
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/tb-btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/tb-xl-btn-sprite.gif b/deluge/ui/web/themes/images/access/toolbar/tb-xl-btn-sprite.gif
new file mode 100644
index 0000000..1bc0420
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/tb-xl-btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/toolbar/tb-xl-sep.gif b/deluge/ui/web/themes/images/access/toolbar/tb-xl-sep.gif
new file mode 100644
index 0000000..30555ee
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/toolbar/tb-xl-sep.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/arrows.gif b/deluge/ui/web/themes/images/access/tree/arrows.gif
new file mode 100644
index 0000000..2e635eb
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/arrows.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-add.gif b/deluge/ui/web/themes/images/access/tree/drop-add.gif
new file mode 100644
index 0000000..b22cd14
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-add.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-between.gif b/deluge/ui/web/themes/images/access/tree/drop-between.gif
new file mode 100644
index 0000000..5c6c09d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-between.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-no.gif b/deluge/ui/web/themes/images/access/tree/drop-no.gif
new file mode 100644
index 0000000..9d9c6a9
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-no.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-over.gif b/deluge/ui/web/themes/images/access/tree/drop-over.gif
new file mode 100644
index 0000000..30d1ca7
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-under.gif b/deluge/ui/web/themes/images/access/tree/drop-under.gif
new file mode 100644
index 0000000..85f66b1
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-under.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/drop-yes.gif b/deluge/ui/web/themes/images/access/tree/drop-yes.gif
new file mode 100644
index 0000000..8aacb30
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/drop-yes.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-end-minus-nl.gif b/deluge/ui/web/themes/images/access/tree/elbow-end-minus-nl.gif
new file mode 100644
index 0000000..b4ae595
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-end-minus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-end-minus.gif b/deluge/ui/web/themes/images/access/tree/elbow-end-minus.gif
new file mode 100644
index 0000000..514cf3e
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-end-minus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-end-plus-nl.gif b/deluge/ui/web/themes/images/access/tree/elbow-end-plus-nl.gif
new file mode 100644
index 0000000..6af2e29
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-end-plus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-end-plus.gif b/deluge/ui/web/themes/images/access/tree/elbow-end-plus.gif
new file mode 100644
index 0000000..96df679
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-end-plus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-end.gif b/deluge/ui/web/themes/images/access/tree/elbow-end.gif
new file mode 100644
index 0000000..f24ddee
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-end.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-line.gif b/deluge/ui/web/themes/images/access/tree/elbow-line.gif
new file mode 100644
index 0000000..75e6da4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-line.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-minus-nl.gif b/deluge/ui/web/themes/images/access/tree/elbow-minus-nl.gif
new file mode 100644
index 0000000..b4ae595
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-minus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-minus.gif b/deluge/ui/web/themes/images/access/tree/elbow-minus.gif
new file mode 100644
index 0000000..68ba298
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-minus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-plus-nl.gif b/deluge/ui/web/themes/images/access/tree/elbow-plus-nl.gif
new file mode 100644
index 0000000..6af2e29
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-plus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow-plus.gif b/deluge/ui/web/themes/images/access/tree/elbow-plus.gif
new file mode 100644
index 0000000..58ba9e4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow-plus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/elbow.gif b/deluge/ui/web/themes/images/access/tree/elbow.gif
new file mode 100644
index 0000000..b8f4208
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/elbow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/folder-open.gif b/deluge/ui/web/themes/images/access/tree/folder-open.gif
new file mode 100644
index 0000000..7c52965
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/folder-open.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/folder.gif b/deluge/ui/web/themes/images/access/tree/folder.gif
new file mode 100644
index 0000000..501e75c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/folder.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/leaf.gif b/deluge/ui/web/themes/images/access/tree/leaf.gif
new file mode 100644
index 0000000..445769d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/leaf.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/loading.gif b/deluge/ui/web/themes/images/access/tree/loading.gif
new file mode 100644
index 0000000..e846e1d
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/tree/s.gif b/deluge/ui/web/themes/images/access/tree/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/tree/s.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/icon-error.gif b/deluge/ui/web/themes/images/access/window/icon-error.gif
new file mode 100644
index 0000000..05c713c
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/icon-error.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/icon-info.gif b/deluge/ui/web/themes/images/access/window/icon-info.gif
new file mode 100644
index 0000000..adc0613
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/icon-info.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/icon-question.gif b/deluge/ui/web/themes/images/access/window/icon-question.gif
new file mode 100644
index 0000000..9b31a94
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/icon-question.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/icon-warning.gif b/deluge/ui/web/themes/images/access/window/icon-warning.gif
new file mode 100644
index 0000000..0d89077
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/icon-warning.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/left-corners.png b/deluge/ui/web/themes/images/access/window/left-corners.png
new file mode 100644
index 0000000..f9a6463
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/left-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/left-right.png b/deluge/ui/web/themes/images/access/window/left-right.png
new file mode 100644
index 0000000..7721193
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/left-right.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/right-corners.png b/deluge/ui/web/themes/images/access/window/right-corners.png
new file mode 100644
index 0000000..1111bb4
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/right-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/access/window/top-bottom.png b/deluge/ui/web/themes/images/access/window/top-bottom.png
new file mode 100644
index 0000000..179747b
--- /dev/null
+++ b/deluge/ui/web/themes/images/access/window/top-bottom.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/corners-blue.gif b/deluge/ui/web/themes/images/default/box/corners-blue.gif
new file mode 100644
index 0000000..fa419b5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/corners-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/corners.gif b/deluge/ui/web/themes/images/default/box/corners.gif
new file mode 100644
index 0000000..8aa8cae
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/corners.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/l-blue.gif b/deluge/ui/web/themes/images/default/box/l-blue.gif
new file mode 100644
index 0000000..5ed7f00
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/l-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/l.gif b/deluge/ui/web/themes/images/default/box/l.gif
new file mode 100644
index 0000000..0160f97
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/l.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/r-blue.gif b/deluge/ui/web/themes/images/default/box/r-blue.gif
new file mode 100644
index 0000000..3ea5cae
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/r-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/r.gif b/deluge/ui/web/themes/images/default/box/r.gif
new file mode 100644
index 0000000..34237f6
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/r.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/tb-blue.gif b/deluge/ui/web/themes/images/default/box/tb-blue.gif
new file mode 100644
index 0000000..562fecc
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/tb-blue.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/box/tb.gif b/deluge/ui/web/themes/images/default/box/tb.gif
new file mode 100644
index 0000000..435889b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/box/tb.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/arrow.gif b/deluge/ui/web/themes/images/default/button/arrow.gif
new file mode 100644
index 0000000..3ab4f71
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/btn.gif b/deluge/ui/web/themes/images/default/button/btn.gif
new file mode 100644
index 0000000..06b404d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/group-cs.gif b/deluge/ui/web/themes/images/default/button/group-cs.gif
new file mode 100644
index 0000000..3d1dca8
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/group-cs.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/group-lr.gif b/deluge/ui/web/themes/images/default/button/group-lr.gif
new file mode 100644
index 0000000..7c549f9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/group-lr.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/group-tb.gif b/deluge/ui/web/themes/images/default/button/group-tb.gif
new file mode 100644
index 0000000..adeb0a4
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/group-tb.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow-b-noline.gif b/deluge/ui/web/themes/images/default/button/s-arrow-b-noline.gif
new file mode 100644
index 0000000..a4220ee
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow-b-noline.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow-b.gif b/deluge/ui/web/themes/images/default/button/s-arrow-b.gif
new file mode 100644
index 0000000..84b6470
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow-b.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow-bo.gif b/deluge/ui/web/themes/images/default/button/s-arrow-bo.gif
new file mode 100644
index 0000000..548700b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow-bo.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow-noline.gif b/deluge/ui/web/themes/images/default/button/s-arrow-noline.gif
new file mode 100644
index 0000000..0953eab
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow-noline.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow-o.gif b/deluge/ui/web/themes/images/default/button/s-arrow-o.gif
new file mode 100644
index 0000000..89c70f3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow-o.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/button/s-arrow.gif b/deluge/ui/web/themes/images/default/button/s-arrow.gif
new file mode 100644
index 0000000..8940774
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/button/s-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/dd/drop-add.gif b/deluge/ui/web/themes/images/default/dd/drop-add.gif
new file mode 100644
index 0000000..b22cd14
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/dd/drop-add.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/dd/drop-no.gif b/deluge/ui/web/themes/images/default/dd/drop-no.gif
new file mode 100644
index 0000000..08d0833
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/dd/drop-no.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/dd/drop-yes.gif b/deluge/ui/web/themes/images/default/dd/drop-yes.gif
new file mode 100644
index 0000000..8aacb30
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/dd/drop-yes.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/editor/tb-sprite.gif b/deluge/ui/web/themes/images/default/editor/tb-sprite.gif
new file mode 100644
index 0000000..fb70577
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/editor/tb-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/checkbox.gif b/deluge/ui/web/themes/images/default/form/checkbox.gif
new file mode 100644
index 0000000..835b346
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/checkbox.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/clear-trigger.gif b/deluge/ui/web/themes/images/default/form/clear-trigger.gif
new file mode 100644
index 0000000..da78d45
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/clear-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/clear-trigger.psd b/deluge/ui/web/themes/images/default/form/clear-trigger.psd
new file mode 100644
index 0000000..f637fa5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/clear-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/date-trigger.gif b/deluge/ui/web/themes/images/default/form/date-trigger.gif
new file mode 100644
index 0000000..25ef7b3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/date-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/date-trigger.psd b/deluge/ui/web/themes/images/default/form/date-trigger.psd
new file mode 100644
index 0000000..74883b2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/date-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/error-tip-corners.gif b/deluge/ui/web/themes/images/default/form/error-tip-corners.gif
new file mode 100644
index 0000000..6ea4c38
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/error-tip-corners.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/exclamation.gif b/deluge/ui/web/themes/images/default/form/exclamation.gif
new file mode 100644
index 0000000..ea31a30
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/exclamation.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/radio.gif b/deluge/ui/web/themes/images/default/form/radio.gif
new file mode 100644
index 0000000..36bb91d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/radio.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/search-trigger.gif b/deluge/ui/web/themes/images/default/form/search-trigger.gif
new file mode 100644
index 0000000..db8802b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/search-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/search-trigger.psd b/deluge/ui/web/themes/images/default/form/search-trigger.psd
new file mode 100644
index 0000000..b11f273
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/search-trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/text-bg.gif b/deluge/ui/web/themes/images/default/form/text-bg.gif
new file mode 100644
index 0000000..4179607
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/text-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/trigger-square.gif b/deluge/ui/web/themes/images/default/form/trigger-square.gif
new file mode 100644
index 0000000..3004ec5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/trigger-square.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/trigger-square.psd b/deluge/ui/web/themes/images/default/form/trigger-square.psd
new file mode 100644
index 0000000..e922ee6
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/trigger-square.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/trigger-tpl.gif b/deluge/ui/web/themes/images/default/form/trigger-tpl.gif
new file mode 100644
index 0000000..e3701a3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/trigger-tpl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/trigger.gif b/deluge/ui/web/themes/images/default/form/trigger.gif
new file mode 100644
index 0000000..f6cba37
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/form/trigger.psd b/deluge/ui/web/themes/images/default/form/trigger.psd
new file mode 100644
index 0000000..344c768
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/form/trigger.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/gradient-bg.gif b/deluge/ui/web/themes/images/default/gradient-bg.gif
new file mode 100644
index 0000000..8134e49
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/gradient-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/arrow-left-white.gif b/deluge/ui/web/themes/images/default/grid/arrow-left-white.gif
new file mode 100644
index 0000000..63088f5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/arrow-left-white.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/arrow-right-white.gif b/deluge/ui/web/themes/images/default/grid/arrow-right-white.gif
new file mode 100644
index 0000000..e9e0678
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/arrow-right-white.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/col-move-bottom.gif b/deluge/ui/web/themes/images/default/grid/col-move-bottom.gif
new file mode 100644
index 0000000..cc1e473
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/col-move-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/col-move-top.gif b/deluge/ui/web/themes/images/default/grid/col-move-top.gif
new file mode 100644
index 0000000..58ff32c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/col-move-top.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/columns.gif b/deluge/ui/web/themes/images/default/grid/columns.gif
new file mode 100644
index 0000000..2d3a823
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/columns.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/dirty.gif b/deluge/ui/web/themes/images/default/grid/dirty.gif
new file mode 100644
index 0000000..4f217a4
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/dirty.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/done.gif b/deluge/ui/web/themes/images/default/grid/done.gif
new file mode 100644
index 0000000..a937cb2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/done.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/drop-no.gif b/deluge/ui/web/themes/images/default/grid/drop-no.gif
new file mode 100644
index 0000000..31a332b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/drop-no.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/drop-yes.gif b/deluge/ui/web/themes/images/default/grid/drop-yes.gif
new file mode 100644
index 0000000..926010e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/drop-yes.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/footer-bg.gif b/deluge/ui/web/themes/images/default/grid/footer-bg.gif
new file mode 100644
index 0000000..126120f
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/footer-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-blue-hd.gif b/deluge/ui/web/themes/images/default/grid/grid-blue-hd.gif
new file mode 100644
index 0000000..862094e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-blue-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-blue-split.gif b/deluge/ui/web/themes/images/default/grid/grid-blue-split.gif
new file mode 100644
index 0000000..5286f58
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-blue-split.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-hrow.gif b/deluge/ui/web/themes/images/default/grid/grid-hrow.gif
new file mode 100644
index 0000000..6374104
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-hrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-loading.gif b/deluge/ui/web/themes/images/default/grid/grid-loading.gif
new file mode 100644
index 0000000..d112c54
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-split.gif b/deluge/ui/web/themes/images/default/grid/grid-split.gif
new file mode 100644
index 0000000..c76a16e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-split.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid-vista-hd.gif b/deluge/ui/web/themes/images/default/grid/grid-vista-hd.gif
new file mode 100644
index 0000000..d097263
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid-vista-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-hd-btn.gif b/deluge/ui/web/themes/images/default/grid/grid3-hd-btn.gif
new file mode 100644
index 0000000..2112607
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-hd-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-hrow-over.gif b/deluge/ui/web/themes/images/default/grid/grid3-hrow-over.gif
new file mode 100644
index 0000000..f9c07af
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-hrow-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-hrow.gif b/deluge/ui/web/themes/images/default/grid/grid3-hrow.gif
new file mode 100644
index 0000000..8d459a3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-hrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-rowheader.gif b/deluge/ui/web/themes/images/default/grid/grid3-rowheader.gif
new file mode 100644
index 0000000..2799b45
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-rowheader.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-special-col-bg.gif b/deluge/ui/web/themes/images/default/grid/grid3-special-col-bg.gif
new file mode 100644
index 0000000..0b4d6ca
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-special-col-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/grid3-special-col-sel-bg.gif b/deluge/ui/web/themes/images/default/grid/grid3-special-col-sel-bg.gif
new file mode 100644
index 0000000..1dfe9a6
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/grid3-special-col-sel-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/group-by.gif b/deluge/ui/web/themes/images/default/grid/group-by.gif
new file mode 100644
index 0000000..d6075bb
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/group-by.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/group-collapse.gif b/deluge/ui/web/themes/images/default/grid/group-collapse.gif
new file mode 100644
index 0000000..495bb05
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/group-collapse.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/group-expand-sprite.gif b/deluge/ui/web/themes/images/default/grid/group-expand-sprite.gif
new file mode 100644
index 0000000..9c1653b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/group-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/group-expand.gif b/deluge/ui/web/themes/images/default/grid/group-expand.gif
new file mode 100644
index 0000000..a33ac30
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/group-expand.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hd-pop.gif b/deluge/ui/web/themes/images/default/grid/hd-pop.gif
new file mode 100644
index 0000000..eb8ba79
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hd-pop.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-asc.gif b/deluge/ui/web/themes/images/default/grid/hmenu-asc.gif
new file mode 100644
index 0000000..8917e0e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-asc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-desc.gif b/deluge/ui/web/themes/images/default/grid/hmenu-desc.gif
new file mode 100644
index 0000000..f26b7c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-desc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-lock.gif b/deluge/ui/web/themes/images/default/grid/hmenu-lock.gif
new file mode 100644
index 0000000..1596126
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-lock.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-lock.png b/deluge/ui/web/themes/images/default/grid/hmenu-lock.png
new file mode 100644
index 0000000..5d33c09
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-lock.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-unlock.gif b/deluge/ui/web/themes/images/default/grid/hmenu-unlock.gif
new file mode 100644
index 0000000..af59cf9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-unlock.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/hmenu-unlock.png b/deluge/ui/web/themes/images/default/grid/hmenu-unlock.png
new file mode 100644
index 0000000..0371ca4
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/hmenu-unlock.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/invalid_line.gif b/deluge/ui/web/themes/images/default/grid/invalid_line.gif
new file mode 100644
index 0000000..fb7e0f3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/invalid_line.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/loading.gif b/deluge/ui/web/themes/images/default/grid/loading.gif
new file mode 100644
index 0000000..e846e1d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/mso-hd.gif b/deluge/ui/web/themes/images/default/grid/mso-hd.gif
new file mode 100644
index 0000000..669f3cf
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/mso-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/nowait.gif b/deluge/ui/web/themes/images/default/grid/nowait.gif
new file mode 100644
index 0000000..4c5862c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/nowait.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-first-disabled.gif b/deluge/ui/web/themes/images/default/grid/page-first-disabled.gif
new file mode 100644
index 0000000..1e02c41
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-first-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-first.gif b/deluge/ui/web/themes/images/default/grid/page-first.gif
new file mode 100644
index 0000000..d84f41a
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-first.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-last-disabled.gif b/deluge/ui/web/themes/images/default/grid/page-last-disabled.gif
new file mode 100644
index 0000000..8697067
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-last-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-last.gif b/deluge/ui/web/themes/images/default/grid/page-last.gif
new file mode 100644
index 0000000..3df5c2b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-last.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-next-disabled.gif b/deluge/ui/web/themes/images/default/grid/page-next-disabled.gif
new file mode 100644
index 0000000..90a7756
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-next-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-next.gif b/deluge/ui/web/themes/images/default/grid/page-next.gif
new file mode 100644
index 0000000..9601635
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-next.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-prev-disabled.gif b/deluge/ui/web/themes/images/default/grid/page-prev-disabled.gif
new file mode 100644
index 0000000..37154d6
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-prev-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/page-prev.gif b/deluge/ui/web/themes/images/default/grid/page-prev.gif
new file mode 100644
index 0000000..eb70cf8
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/page-prev.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/pick-button.gif b/deluge/ui/web/themes/images/default/grid/pick-button.gif
new file mode 100644
index 0000000..6957924
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/pick-button.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/refresh-disabled.gif b/deluge/ui/web/themes/images/default/grid/refresh-disabled.gif
new file mode 100644
index 0000000..607800b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/refresh-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/refresh.gif b/deluge/ui/web/themes/images/default/grid/refresh.gif
new file mode 100644
index 0000000..110f684
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/refresh.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/row-check-sprite.gif b/deluge/ui/web/themes/images/default/grid/row-check-sprite.gif
new file mode 100644
index 0000000..6101164
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/row-check-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/row-expand-sprite.gif b/deluge/ui/web/themes/images/default/grid/row-expand-sprite.gif
new file mode 100644
index 0000000..6f4d874
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/row-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/row-over.gif b/deluge/ui/web/themes/images/default/grid/row-over.gif
new file mode 100644
index 0000000..b288e38
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/row-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/row-sel.gif b/deluge/ui/web/themes/images/default/grid/row-sel.gif
new file mode 100644
index 0000000..98209e6
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/row-sel.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/sort-hd.gif b/deluge/ui/web/themes/images/default/grid/sort-hd.gif
new file mode 100644
index 0000000..45e545f
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/sort-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/sort_asc.gif b/deluge/ui/web/themes/images/default/grid/sort_asc.gif
new file mode 100644
index 0000000..67a2a4c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/sort_asc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/sort_desc.gif b/deluge/ui/web/themes/images/default/grid/sort_desc.gif
new file mode 100644
index 0000000..34db47c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/sort_desc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/grid/wait.gif b/deluge/ui/web/themes/images/default/grid/wait.gif
new file mode 100644
index 0000000..471c1a4
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/grid/wait.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/collapse.gif b/deluge/ui/web/themes/images/default/layout/collapse.gif
new file mode 100644
index 0000000..d87b0a9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/collapse.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/expand.gif b/deluge/ui/web/themes/images/default/layout/expand.gif
new file mode 100644
index 0000000..7b6e1c1
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/expand.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/gradient-bg.gif b/deluge/ui/web/themes/images/default/layout/gradient-bg.gif
new file mode 100644
index 0000000..8134e49
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/gradient-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/mini-bottom.gif b/deluge/ui/web/themes/images/default/layout/mini-bottom.gif
new file mode 100644
index 0000000..c18f9e3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/mini-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/mini-left.gif b/deluge/ui/web/themes/images/default/layout/mini-left.gif
new file mode 100644
index 0000000..99f7993
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/mini-left.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/mini-right.gif b/deluge/ui/web/themes/images/default/layout/mini-right.gif
new file mode 100644
index 0000000..5b13c5a
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/mini-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/mini-top.gif b/deluge/ui/web/themes/images/default/layout/mini-top.gif
new file mode 100644
index 0000000..a4ca2bb
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/mini-top.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/ns-collapse.gif b/deluge/ui/web/themes/images/default/layout/ns-collapse.gif
new file mode 100644
index 0000000..df2a77e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/ns-collapse.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/ns-expand.gif b/deluge/ui/web/themes/images/default/layout/ns-expand.gif
new file mode 100644
index 0000000..77ab9da
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/ns-expand.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/panel-close.gif b/deluge/ui/web/themes/images/default/layout/panel-close.gif
new file mode 100644
index 0000000..2bdd623
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/panel-close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/panel-title-bg.gif b/deluge/ui/web/themes/images/default/layout/panel-title-bg.gif
new file mode 100644
index 0000000..d1daef5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/panel-title-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/panel-title-light-bg.gif b/deluge/ui/web/themes/images/default/layout/panel-title-light-bg.gif
new file mode 100644
index 0000000..8c2c83d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/panel-title-light-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/stick.gif b/deluge/ui/web/themes/images/default/layout/stick.gif
new file mode 100644
index 0000000..5a1e8ba
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/stick.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/stuck.gif b/deluge/ui/web/themes/images/default/layout/stuck.gif
new file mode 100644
index 0000000..0a8de4d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/stuck.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/tab-close-on.gif b/deluge/ui/web/themes/images/default/layout/tab-close-on.gif
new file mode 100644
index 0000000..eacea39
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/tab-close-on.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/layout/tab-close.gif b/deluge/ui/web/themes/images/default/layout/tab-close.gif
new file mode 100644
index 0000000..45db61e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/layout/tab-close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/checked.gif b/deluge/ui/web/themes/images/default/menu/checked.gif
new file mode 100644
index 0000000..fad5893
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/checked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/group-checked.gif b/deluge/ui/web/themes/images/default/menu/group-checked.gif
new file mode 100644
index 0000000..d30b3e5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/group-checked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/item-over.gif b/deluge/ui/web/themes/images/default/menu/item-over.gif
new file mode 100644
index 0000000..0167839
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/item-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/menu-parent.gif b/deluge/ui/web/themes/images/default/menu/menu-parent.gif
new file mode 100644
index 0000000..1e37562
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/menu-parent.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/menu.gif b/deluge/ui/web/themes/images/default/menu/menu.gif
new file mode 100644
index 0000000..30a2c4b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/menu.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/menu/unchecked.gif b/deluge/ui/web/themes/images/default/menu/unchecked.gif
new file mode 100644
index 0000000..43823e5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/menu/unchecked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/corners-sprite.gif b/deluge/ui/web/themes/images/default/panel/corners-sprite.gif
new file mode 100644
index 0000000..aa0d0ed
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/left-right.gif b/deluge/ui/web/themes/images/default/panel/left-right.gif
new file mode 100644
index 0000000..9fae2d5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/light-hd.gif b/deluge/ui/web/themes/images/default/panel/light-hd.gif
new file mode 100644
index 0000000..58d6747
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/light-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/tool-sprite-tpl.gif b/deluge/ui/web/themes/images/default/panel/tool-sprite-tpl.gif
new file mode 100644
index 0000000..e647867
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/tool-sprite-tpl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/tool-sprites.gif b/deluge/ui/web/themes/images/default/panel/tool-sprites.gif
new file mode 100644
index 0000000..2b6b809
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/tool-sprites.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/tools-sprites-trans.gif b/deluge/ui/web/themes/images/default/panel/tools-sprites-trans.gif
new file mode 100644
index 0000000..ead931e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/tools-sprites-trans.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/top-bottom.gif b/deluge/ui/web/themes/images/default/panel/top-bottom.gif
new file mode 100644
index 0000000..be6c50e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/top-bottom.png b/deluge/ui/web/themes/images/default/panel/top-bottom.png
new file mode 100644
index 0000000..6df5f68
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/top-bottom.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/white-corners-sprite.gif b/deluge/ui/web/themes/images/default/panel/white-corners-sprite.gif
new file mode 100644
index 0000000..22d4bba
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/white-corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/white-left-right.gif b/deluge/ui/web/themes/images/default/panel/white-left-right.gif
new file mode 100644
index 0000000..d82c337
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/white-left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/panel/white-top-bottom.gif b/deluge/ui/web/themes/images/default/panel/white-top-bottom.gif
new file mode 100644
index 0000000..fe7dd1c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/panel/white-top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/progress/progress-bg.gif b/deluge/ui/web/themes/images/default/progress/progress-bg.gif
new file mode 100644
index 0000000..1c1abeb
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/progress/progress-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/qtip/bg.gif b/deluge/ui/web/themes/images/default/qtip/bg.gif
new file mode 100644
index 0000000..43488af
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/qtip/bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/qtip/close.gif b/deluge/ui/web/themes/images/default/qtip/close.gif
new file mode 100644
index 0000000..69ab915
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/qtip/close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/qtip/tip-anchor-sprite.gif b/deluge/ui/web/themes/images/default/qtip/tip-anchor-sprite.gif
new file mode 100644
index 0000000..9cf4850
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/qtip/tip-anchor-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/qtip/tip-sprite.gif b/deluge/ui/web/themes/images/default/qtip/tip-sprite.gif
new file mode 100644
index 0000000..9810aca
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/qtip/tip-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/s.gif b/deluge/ui/web/themes/images/default/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/s.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shadow-c.png b/deluge/ui/web/themes/images/default/shadow-c.png
new file mode 100644
index 0000000..35891d3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shadow-c.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shadow-lr.png b/deluge/ui/web/themes/images/default/shadow-lr.png
new file mode 100644
index 0000000..e59a9d7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shadow-lr.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shadow.png b/deluge/ui/web/themes/images/default/shadow.png
new file mode 100644
index 0000000..87dcc6e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shadow.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/blue-loading.gif b/deluge/ui/web/themes/images/default/shared/blue-loading.gif
new file mode 100644
index 0000000..3bbf639
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/blue-loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/calendar.gif b/deluge/ui/web/themes/images/default/shared/calendar.gif
new file mode 100644
index 0000000..133cf23
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/calendar.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/glass-bg.gif b/deluge/ui/web/themes/images/default/shared/glass-bg.gif
new file mode 100644
index 0000000..26fbbae
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/glass-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/hd-sprite.gif b/deluge/ui/web/themes/images/default/shared/hd-sprite.gif
new file mode 100644
index 0000000..42da1ea
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/hd-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/large-loading.gif b/deluge/ui/web/themes/images/default/shared/large-loading.gif
new file mode 100644
index 0000000..b36b555
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/large-loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/left-btn.gif b/deluge/ui/web/themes/images/default/shared/left-btn.gif
new file mode 100644
index 0000000..a0ddd9e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/left-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/loading-balls.gif b/deluge/ui/web/themes/images/default/shared/loading-balls.gif
new file mode 100644
index 0000000..9ce214b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/loading-balls.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/right-btn.gif b/deluge/ui/web/themes/images/default/shared/right-btn.gif
new file mode 100644
index 0000000..dee63e2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/right-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/shared/warning.gif b/deluge/ui/web/themes/images/default/shared/warning.gif
new file mode 100644
index 0000000..806d4bc
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/shared/warning.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/e-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/e-handle-dark.gif
new file mode 100644
index 0000000..b5486c1
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/e-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/e-handle.gif b/deluge/ui/web/themes/images/default/sizer/e-handle.gif
new file mode 100644
index 0000000..00ba835
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/e-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/ne-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/ne-handle-dark.gif
new file mode 100644
index 0000000..04e5ecf
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/ne-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/ne-handle.gif b/deluge/ui/web/themes/images/default/sizer/ne-handle.gif
new file mode 100644
index 0000000..09405c7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/ne-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/nw-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/nw-handle-dark.gif
new file mode 100644
index 0000000..6e49d69
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/nw-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/nw-handle.gif b/deluge/ui/web/themes/images/default/sizer/nw-handle.gif
new file mode 100644
index 0000000..2fcea8a
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/nw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/s-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/s-handle-dark.gif
new file mode 100644
index 0000000..4eb5f0f
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/s-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/s-handle.gif b/deluge/ui/web/themes/images/default/sizer/s-handle.gif
new file mode 100644
index 0000000..bf069c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/s-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/se-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/se-handle-dark.gif
new file mode 100644
index 0000000..c4c1087
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/se-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/se-handle.gif b/deluge/ui/web/themes/images/default/sizer/se-handle.gif
new file mode 100644
index 0000000..972055e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/se-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/square.gif b/deluge/ui/web/themes/images/default/sizer/square.gif
new file mode 100644
index 0000000..14ce6f7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/square.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/sw-handle-dark.gif b/deluge/ui/web/themes/images/default/sizer/sw-handle-dark.gif
new file mode 100644
index 0000000..77224b0
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/sw-handle-dark.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/sizer/sw-handle.gif b/deluge/ui/web/themes/images/default/sizer/sw-handle.gif
new file mode 100644
index 0000000..3ca0ed9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/sizer/sw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/slider/slider-bg.png b/deluge/ui/web/themes/images/default/slider/slider-bg.png
new file mode 100644
index 0000000..6825d73
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/slider/slider-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/slider/slider-thumb.png b/deluge/ui/web/themes/images/default/slider/slider-thumb.png
new file mode 100644
index 0000000..d16ed52
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/slider/slider-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/slider/slider-v-bg.png b/deluge/ui/web/themes/images/default/slider/slider-v-bg.png
new file mode 100644
index 0000000..1ebe8ef
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/slider/slider-v-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/slider/slider-v-thumb.png b/deluge/ui/web/themes/images/default/slider/slider-v-thumb.png
new file mode 100644
index 0000000..cc86cb7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/slider/slider-v-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/scroll-left.gif b/deluge/ui/web/themes/images/default/tabs/scroll-left.gif
new file mode 100644
index 0000000..9f2f6d1
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/scroll-left.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/scroll-right.gif b/deluge/ui/web/themes/images/default/tabs/scroll-right.gif
new file mode 100644
index 0000000..4c5e7e3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/scroll-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/scroller-bg.gif b/deluge/ui/web/themes/images/default/tabs/scroller-bg.gif
new file mode 100644
index 0000000..099b90d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/scroller-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-left-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-left-bg.gif
new file mode 100644
index 0000000..188bf94
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-right-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-right-bg.gif
new file mode 100644
index 0000000..e1f5e3c
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-inactive-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-left-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-left-bg.gif
new file mode 100644
index 0000000..dde7968
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-over-left-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-over-left-bg.gif
new file mode 100644
index 0000000..da49c10
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-over-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-over-right-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-over-right-bg.gif
new file mode 100644
index 0000000..45346ab
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-over-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-btm-right-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-btm-right-bg.gif
new file mode 100644
index 0000000..e695186
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-btm-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-close.gif b/deluge/ui/web/themes/images/default/tabs/tab-close.gif
new file mode 100644
index 0000000..e699878
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.gif
new file mode 100644
index 0000000..34f1333
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.png b/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.png
new file mode 100644
index 0000000..fed48eb
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-strip-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tab-strip-btm-bg.gif b/deluge/ui/web/themes/images/default/tabs/tab-strip-btm-bg.gif
new file mode 100644
index 0000000..5eaba1e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tab-strip-btm-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tabs/tabs-sprite.gif b/deluge/ui/web/themes/images/default/tabs/tabs-sprite.gif
new file mode 100644
index 0000000..e969fb0
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tabs/tabs-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/bg.gif b/deluge/ui/web/themes/images/default/toolbar/bg.gif
new file mode 100644
index 0000000..0b085bf
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/btn-arrow-light.gif b/deluge/ui/web/themes/images/default/toolbar/btn-arrow-light.gif
new file mode 100644
index 0000000..b0e24b5
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/btn-arrow-light.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/btn-arrow.gif b/deluge/ui/web/themes/images/default/toolbar/btn-arrow.gif
new file mode 100644
index 0000000..8acb460
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/btn-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/btn-over-bg.gif b/deluge/ui/web/themes/images/default/toolbar/btn-over-bg.gif
new file mode 100644
index 0000000..ee2dd98
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/btn-over-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/gray-bg.gif b/deluge/ui/web/themes/images/default/toolbar/gray-bg.gif
new file mode 100644
index 0000000..bd49438
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/gray-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/more.gif b/deluge/ui/web/themes/images/default/toolbar/more.gif
new file mode 100644
index 0000000..02c2509
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/more.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/tb-bg.gif b/deluge/ui/web/themes/images/default/toolbar/tb-bg.gif
new file mode 100644
index 0000000..4969e4e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/tb-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/tb-btn-sprite.gif b/deluge/ui/web/themes/images/default/toolbar/tb-btn-sprite.gif
new file mode 100644
index 0000000..19bbef3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/tb-btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/tb-xl-btn-sprite.gif b/deluge/ui/web/themes/images/default/toolbar/tb-xl-btn-sprite.gif
new file mode 100644
index 0000000..1bc0420
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/tb-xl-btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/toolbar/tb-xl-sep.gif b/deluge/ui/web/themes/images/default/toolbar/tb-xl-sep.gif
new file mode 100644
index 0000000..30555ee
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/toolbar/tb-xl-sep.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/arrows.gif b/deluge/ui/web/themes/images/default/tree/arrows.gif
new file mode 100644
index 0000000..2683463
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/arrows.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-add.gif b/deluge/ui/web/themes/images/default/tree/drop-add.gif
new file mode 100644
index 0000000..b22cd14
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-add.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-between.gif b/deluge/ui/web/themes/images/default/tree/drop-between.gif
new file mode 100644
index 0000000..5c6c09d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-between.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-no.gif b/deluge/ui/web/themes/images/default/tree/drop-no.gif
new file mode 100644
index 0000000..9d9c6a9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-no.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-over.gif b/deluge/ui/web/themes/images/default/tree/drop-over.gif
new file mode 100644
index 0000000..30d1ca7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-under.gif b/deluge/ui/web/themes/images/default/tree/drop-under.gif
new file mode 100644
index 0000000..85f66b1
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-under.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/drop-yes.gif b/deluge/ui/web/themes/images/default/tree/drop-yes.gif
new file mode 100644
index 0000000..8aacb30
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/drop-yes.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-end-minus-nl.gif b/deluge/ui/web/themes/images/default/tree/elbow-end-minus-nl.gif
new file mode 100644
index 0000000..928779e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-end-minus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-end-minus.gif b/deluge/ui/web/themes/images/default/tree/elbow-end-minus.gif
new file mode 100644
index 0000000..9a8d727
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-end-minus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-end-plus-nl.gif b/deluge/ui/web/themes/images/default/tree/elbow-end-plus-nl.gif
new file mode 100644
index 0000000..9f7f698
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-end-plus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-end-plus.gif b/deluge/ui/web/themes/images/default/tree/elbow-end-plus.gif
new file mode 100644
index 0000000..5943a01
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-end-plus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-end.gif b/deluge/ui/web/themes/images/default/tree/elbow-end.gif
new file mode 100644
index 0000000..f24ddee
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-end.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-line.gif b/deluge/ui/web/themes/images/default/tree/elbow-line.gif
new file mode 100644
index 0000000..75e6da4
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-line.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-minus-nl.gif b/deluge/ui/web/themes/images/default/tree/elbow-minus-nl.gif
new file mode 100644
index 0000000..928779e
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-minus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-minus.gif b/deluge/ui/web/themes/images/default/tree/elbow-minus.gif
new file mode 100644
index 0000000..97dcc71
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-minus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-plus-nl.gif b/deluge/ui/web/themes/images/default/tree/elbow-plus-nl.gif
new file mode 100644
index 0000000..9f7f698
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-plus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow-plus.gif b/deluge/ui/web/themes/images/default/tree/elbow-plus.gif
new file mode 100644
index 0000000..698de47
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow-plus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/elbow.gif b/deluge/ui/web/themes/images/default/tree/elbow.gif
new file mode 100644
index 0000000..b8f4208
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/elbow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/folder-open.gif b/deluge/ui/web/themes/images/default/tree/folder-open.gif
new file mode 100644
index 0000000..56ba737
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/folder-open.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/folder.gif b/deluge/ui/web/themes/images/default/tree/folder.gif
new file mode 100644
index 0000000..20412f7
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/folder.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/leaf.gif b/deluge/ui/web/themes/images/default/tree/leaf.gif
new file mode 100644
index 0000000..445769d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/leaf.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/loading.gif b/deluge/ui/web/themes/images/default/tree/loading.gif
new file mode 100644
index 0000000..e846e1d
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/loading.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/tree/s.gif b/deluge/ui/web/themes/images/default/tree/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/tree/s.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/icon-error.gif b/deluge/ui/web/themes/images/default/window/icon-error.gif
new file mode 100644
index 0000000..397b655
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/icon-error.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/icon-info.gif b/deluge/ui/web/themes/images/default/window/icon-info.gif
new file mode 100644
index 0000000..58281c3
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/icon-info.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/icon-question.gif b/deluge/ui/web/themes/images/default/window/icon-question.gif
new file mode 100644
index 0000000..08abd82
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/icon-question.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/icon-warning.gif b/deluge/ui/web/themes/images/default/window/icon-warning.gif
new file mode 100644
index 0000000..27ff98b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/icon-warning.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/left-corners.png b/deluge/ui/web/themes/images/default/window/left-corners.png
new file mode 100644
index 0000000..a2250fd
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/left-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/left-corners.psd b/deluge/ui/web/themes/images/default/window/left-corners.psd
new file mode 100644
index 0000000..3d7f062
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/left-corners.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/left-right.png b/deluge/ui/web/themes/images/default/window/left-right.png
new file mode 100644
index 0000000..acd72c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/left-right.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/left-right.psd b/deluge/ui/web/themes/images/default/window/left-right.psd
new file mode 100644
index 0000000..59a3960
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/left-right.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/right-corners.png b/deluge/ui/web/themes/images/default/window/right-corners.png
new file mode 100644
index 0000000..7c40007
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/right-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/right-corners.psd b/deluge/ui/web/themes/images/default/window/right-corners.psd
new file mode 100644
index 0000000..86d5095
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/right-corners.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/top-bottom.png b/deluge/ui/web/themes/images/default/window/top-bottom.png
new file mode 100644
index 0000000..3b5f86b
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/top-bottom.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/default/window/top-bottom.psd b/deluge/ui/web/themes/images/default/window/top-bottom.psd
new file mode 100644
index 0000000..48c5395
--- /dev/null
+++ b/deluge/ui/web/themes/images/default/window/top-bottom.psd
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/btn-arrow.gif b/deluge/ui/web/themes/images/gray/button/btn-arrow.gif
new file mode 100644
index 0000000..f90d5df
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/btn-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/btn-sprite.gif b/deluge/ui/web/themes/images/gray/button/btn-sprite.gif
new file mode 100644
index 0000000..834ff97
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/btn.gif b/deluge/ui/web/themes/images/gray/button/btn.gif
new file mode 100644
index 0000000..96ea61a
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/group-cs.gif b/deluge/ui/web/themes/images/gray/button/group-cs.gif
new file mode 100644
index 0000000..7059e2b
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/group-cs.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/group-lr.gif b/deluge/ui/web/themes/images/gray/button/group-lr.gif
new file mode 100644
index 0000000..3f41fbd
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/group-lr.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/group-tb.gif b/deluge/ui/web/themes/images/gray/button/group-tb.gif
new file mode 100644
index 0000000..c5ea8ca
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/group-tb.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/s-arrow-bo.gif b/deluge/ui/web/themes/images/gray/button/s-arrow-bo.gif
new file mode 100644
index 0000000..fa5b2f4
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/s-arrow-bo.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/button/s-arrow-o.gif b/deluge/ui/web/themes/images/gray/button/s-arrow-o.gif
new file mode 100644
index 0000000..52a5141
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/button/s-arrow-o.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/form/clear-trigger.gif b/deluge/ui/web/themes/images/gray/form/clear-trigger.gif
new file mode 100644
index 0000000..be3ff58
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/form/clear-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/form/date-trigger.gif b/deluge/ui/web/themes/images/gray/form/date-trigger.gif
new file mode 100644
index 0000000..e0537cb
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/form/date-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/form/search-trigger.gif b/deluge/ui/web/themes/images/gray/form/search-trigger.gif
new file mode 100644
index 0000000..0cc4f59
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/form/search-trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/form/trigger-square.gif b/deluge/ui/web/themes/images/gray/form/trigger-square.gif
new file mode 100644
index 0000000..7a0f585
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/form/trigger-square.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/form/trigger.gif b/deluge/ui/web/themes/images/gray/form/trigger.gif
new file mode 100644
index 0000000..b563474
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/form/trigger.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/gradient-bg.gif b/deluge/ui/web/themes/images/gray/gradient-bg.gif
new file mode 100644
index 0000000..8134e49
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/gradient-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/col-move-bottom.gif b/deluge/ui/web/themes/images/gray/grid/col-move-bottom.gif
new file mode 100644
index 0000000..c525f7e
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/col-move-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/col-move-top.gif b/deluge/ui/web/themes/images/gray/grid/col-move-top.gif
new file mode 100644
index 0000000..ccc92b6
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/col-move-top.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-hd-btn.gif b/deluge/ui/web/themes/images/gray/grid/grid3-hd-btn.gif
new file mode 100644
index 0000000..daf1ef2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-hd-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over.gif b/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over.gif
new file mode 100644
index 0000000..d37252f
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over2.gif b/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over2.gif
new file mode 100644
index 0000000..353d906
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-hrow-over2.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-hrow.gif b/deluge/ui/web/themes/images/gray/grid/grid3-hrow.gif
new file mode 100644
index 0000000..8d459a3
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-hrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-hrow2.gif b/deluge/ui/web/themes/images/gray/grid/grid3-hrow2.gif
new file mode 100644
index 0000000..423b507
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-hrow2.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg.gif b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg.gif
new file mode 100644
index 0000000..12d64d7
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg2.gif b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg2.gif
new file mode 100644
index 0000000..f10e6ad
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-bg2.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/grid3-special-col-sel-bg.gif b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-sel-bg.gif
new file mode 100644
index 0000000..4fa6e10
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/grid3-special-col-sel-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/group-collapse.gif b/deluge/ui/web/themes/images/gray/grid/group-collapse.gif
new file mode 100644
index 0000000..c9ad30d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/group-collapse.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/group-expand-sprite.gif b/deluge/ui/web/themes/images/gray/grid/group-expand-sprite.gif
new file mode 100644
index 0000000..d24891d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/group-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/group-expand.gif b/deluge/ui/web/themes/images/gray/grid/group-expand.gif
new file mode 100644
index 0000000..663b5c8
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/group-expand.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/page-first.gif b/deluge/ui/web/themes/images/gray/grid/page-first.gif
new file mode 100644
index 0000000..60be4bc
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/page-first.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/page-last.gif b/deluge/ui/web/themes/images/gray/grid/page-last.gif
new file mode 100644
index 0000000..beb4a83
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/page-last.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/page-next.gif b/deluge/ui/web/themes/images/gray/grid/page-next.gif
new file mode 100644
index 0000000..97db1c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/page-next.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/page-prev.gif b/deluge/ui/web/themes/images/gray/grid/page-prev.gif
new file mode 100644
index 0000000..d07e61c
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/page-prev.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/refresh.gif b/deluge/ui/web/themes/images/gray/grid/refresh.gif
new file mode 100644
index 0000000..868b2dc
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/refresh.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/row-expand-sprite.gif b/deluge/ui/web/themes/images/gray/grid/row-expand-sprite.gif
new file mode 100644
index 0000000..09c00a6
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/row-expand-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/sort-hd.gif b/deluge/ui/web/themes/images/gray/grid/sort-hd.gif
new file mode 100644
index 0000000..4cf483d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/sort-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/sort_asc.gif b/deluge/ui/web/themes/images/gray/grid/sort_asc.gif
new file mode 100644
index 0000000..7e562e2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/sort_asc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/grid/sort_desc.gif b/deluge/ui/web/themes/images/gray/grid/sort_desc.gif
new file mode 100644
index 0000000..9b7a871
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/grid/sort_desc.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/menu/group-checked.gif b/deluge/ui/web/themes/images/gray/menu/group-checked.gif
new file mode 100644
index 0000000..c882488
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/menu/group-checked.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/menu/item-over-disabled.gif b/deluge/ui/web/themes/images/gray/menu/item-over-disabled.gif
new file mode 100644
index 0000000..97d5ffa
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/menu/item-over-disabled.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/menu/item-over.gif b/deluge/ui/web/themes/images/gray/menu/item-over.gif
new file mode 100644
index 0000000..e0dc5f7
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/menu/item-over.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/menu/menu-parent.gif b/deluge/ui/web/themes/images/gray/menu/menu-parent.gif
new file mode 100644
index 0000000..5461a8b
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/menu/menu-parent.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/corners-sprite.gif b/deluge/ui/web/themes/images/gray/panel/corners-sprite.gif
new file mode 100644
index 0000000..fad0e6d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/left-right.gif b/deluge/ui/web/themes/images/gray/panel/left-right.gif
new file mode 100644
index 0000000..c5f3dca
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/light-hd.gif b/deluge/ui/web/themes/images/gray/panel/light-hd.gif
new file mode 100644
index 0000000..6eb28ba
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/light-hd.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/tool-sprite-tpl.gif b/deluge/ui/web/themes/images/gray/panel/tool-sprite-tpl.gif
new file mode 100644
index 0000000..18277a3
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/tool-sprite-tpl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/tool-sprites.gif b/deluge/ui/web/themes/images/gray/panel/tool-sprites.gif
new file mode 100644
index 0000000..36b6b67
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/tool-sprites.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/tools-sprites-trans.gif b/deluge/ui/web/themes/images/gray/panel/tools-sprites-trans.gif
new file mode 100644
index 0000000..b6d7ba3
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/tools-sprites-trans.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/top-bottom.gif b/deluge/ui/web/themes/images/gray/panel/top-bottom.gif
new file mode 100644
index 0000000..24ceb30
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/top-bottom.png b/deluge/ui/web/themes/images/gray/panel/top-bottom.png
new file mode 100644
index 0000000..6df5f68
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/top-bottom.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/white-corners-sprite.gif b/deluge/ui/web/themes/images/gray/panel/white-corners-sprite.gif
new file mode 100644
index 0000000..d5b8adf
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/white-corners-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/white-left-right.gif b/deluge/ui/web/themes/images/gray/panel/white-left-right.gif
new file mode 100644
index 0000000..2c9e142
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/white-left-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/panel/white-top-bottom.gif b/deluge/ui/web/themes/images/gray/panel/white-top-bottom.gif
new file mode 100644
index 0000000..025fbd5
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/panel/white-top-bottom.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/progress/progress-bg.gif b/deluge/ui/web/themes/images/gray/progress/progress-bg.gif
new file mode 100644
index 0000000..5585d80
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/progress/progress-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/qtip/bg.gif b/deluge/ui/web/themes/images/gray/qtip/bg.gif
new file mode 100644
index 0000000..a9055a5
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/qtip/bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/qtip/close.gif b/deluge/ui/web/themes/images/gray/qtip/close.gif
new file mode 100644
index 0000000..69ab915
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/qtip/close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/qtip/tip-anchor-sprite.gif b/deluge/ui/web/themes/images/gray/qtip/tip-anchor-sprite.gif
new file mode 100644
index 0000000..0671586
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/qtip/tip-anchor-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/qtip/tip-sprite.gif b/deluge/ui/web/themes/images/gray/qtip/tip-sprite.gif
new file mode 100644
index 0000000..4ade664
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/qtip/tip-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/s.gif b/deluge/ui/web/themes/images/gray/s.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/s.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/shared/hd-sprite.gif b/deluge/ui/web/themes/images/gray/shared/hd-sprite.gif
new file mode 100644
index 0000000..d943833
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/shared/hd-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/shared/left-btn.gif b/deluge/ui/web/themes/images/gray/shared/left-btn.gif
new file mode 100644
index 0000000..3301054
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/shared/left-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/shared/right-btn.gif b/deluge/ui/web/themes/images/gray/shared/right-btn.gif
new file mode 100644
index 0000000..c529110
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/shared/right-btn.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/e-handle.gif b/deluge/ui/web/themes/images/gray/sizer/e-handle.gif
new file mode 100644
index 0000000..a8ed0ed
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/e-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/ne-handle.gif b/deluge/ui/web/themes/images/gray/sizer/ne-handle.gif
new file mode 100644
index 0000000..6f7b0c2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/ne-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/nw-handle.gif b/deluge/ui/web/themes/images/gray/sizer/nw-handle.gif
new file mode 100644
index 0000000..92ad82c
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/nw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/s-handle.gif b/deluge/ui/web/themes/images/gray/sizer/s-handle.gif
new file mode 100644
index 0000000..d7eeae2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/s-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/se-handle.gif b/deluge/ui/web/themes/images/gray/sizer/se-handle.gif
new file mode 100644
index 0000000..f011a3b
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/se-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/square.gif b/deluge/ui/web/themes/images/gray/sizer/square.gif
new file mode 100644
index 0000000..7751d5e
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/square.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/sizer/sw-handle.gif b/deluge/ui/web/themes/images/gray/sizer/sw-handle.gif
new file mode 100644
index 0000000..aa903dd
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/sizer/sw-handle.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/slider/slider-thumb.png b/deluge/ui/web/themes/images/gray/slider/slider-thumb.png
new file mode 100644
index 0000000..6ec1667
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/slider/slider-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/slider/slider-v-thumb.png b/deluge/ui/web/themes/images/gray/slider/slider-v-thumb.png
new file mode 100644
index 0000000..1945672
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/slider/slider-v-thumb.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/scroll-left.gif b/deluge/ui/web/themes/images/gray/tabs/scroll-left.gif
new file mode 100644
index 0000000..bbb3e3d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/scroll-left.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/scroll-right.gif b/deluge/ui/web/themes/images/gray/tabs/scroll-right.gif
new file mode 100644
index 0000000..feb6a76
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/scroll-right.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/scroller-bg.gif b/deluge/ui/web/themes/images/gray/tabs/scroller-bg.gif
new file mode 100644
index 0000000..f089c0a
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/scroller-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-left-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-left-bg.gif
new file mode 100644
index 0000000..d718173
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-right-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-right-bg.gif
new file mode 100644
index 0000000..bf35493
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-inactive-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-left-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-left-bg.gif
new file mode 100644
index 0000000..96d2e5e
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-left-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-left-bg.gif
new file mode 100644
index 0000000..164d101
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-left-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-right-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-right-bg.gif
new file mode 100644
index 0000000..f6f0495
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-over-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-btm-right-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-btm-right-bg.gif
new file mode 100644
index 0000000..c41cada
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-btm-right-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-close.gif b/deluge/ui/web/themes/images/gray/tabs/tab-close.gif
new file mode 100644
index 0000000..98d5da9
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-close.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.gif
new file mode 100644
index 0000000..040b677
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.png b/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.png
new file mode 100644
index 0000000..fed48eb
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-strip-bg.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tab-strip-btm-bg.gif b/deluge/ui/web/themes/images/gray/tabs/tab-strip-btm-bg.gif
new file mode 100644
index 0000000..f35087f
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tab-strip-btm-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tabs/tabs-sprite.gif b/deluge/ui/web/themes/images/gray/tabs/tabs-sprite.gif
new file mode 100644
index 0000000..1901b23
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tabs/tabs-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/bg.gif b/deluge/ui/web/themes/images/gray/toolbar/bg.gif
new file mode 100644
index 0000000..9ab78a2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/btn-arrow-light.gif b/deluge/ui/web/themes/images/gray/toolbar/btn-arrow-light.gif
new file mode 100644
index 0000000..b0e24b5
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/btn-arrow-light.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/btn-arrow.gif b/deluge/ui/web/themes/images/gray/toolbar/btn-arrow.gif
new file mode 100644
index 0000000..8acb460
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/btn-arrow.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/btn-over-bg.gif b/deluge/ui/web/themes/images/gray/toolbar/btn-over-bg.gif
new file mode 100644
index 0000000..ee2dd98
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/btn-over-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/gray-bg.gif b/deluge/ui/web/themes/images/gray/toolbar/gray-bg.gif
new file mode 100644
index 0000000..5464e21
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/gray-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/more.gif b/deluge/ui/web/themes/images/gray/toolbar/more.gif
new file mode 100644
index 0000000..77f4f23
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/more.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/tb-bg.gif b/deluge/ui/web/themes/images/gray/toolbar/tb-bg.gif
new file mode 100644
index 0000000..4969e4e
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/tb-bg.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/toolbar/tb-btn-sprite.gif b/deluge/ui/web/themes/images/gray/toolbar/tb-btn-sprite.gif
new file mode 100644
index 0000000..894fef2
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/toolbar/tb-btn-sprite.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tree/arrows.gif b/deluge/ui/web/themes/images/gray/tree/arrows.gif
new file mode 100644
index 0000000..a51a8e4
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tree/arrows.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tree/elbow-end-minus-nl.gif b/deluge/ui/web/themes/images/gray/tree/elbow-end-minus-nl.gif
new file mode 100644
index 0000000..8c5bc5d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tree/elbow-end-minus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tree/elbow-end-minus.gif b/deluge/ui/web/themes/images/gray/tree/elbow-end-minus.gif
new file mode 100644
index 0000000..5850513
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tree/elbow-end-minus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tree/elbow-end-plus-nl.gif b/deluge/ui/web/themes/images/gray/tree/elbow-end-plus-nl.gif
new file mode 100644
index 0000000..752b42a
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tree/elbow-end-plus-nl.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/tree/elbow-end-plus.gif b/deluge/ui/web/themes/images/gray/tree/elbow-end-plus.gif
new file mode 100644
index 0000000..ff12635
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/tree/elbow-end-plus.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/icon-error.gif b/deluge/ui/web/themes/images/gray/window/icon-error.gif
new file mode 100644
index 0000000..397b655
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/icon-error.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/icon-info.gif b/deluge/ui/web/themes/images/gray/window/icon-info.gif
new file mode 100644
index 0000000..58281c3
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/icon-info.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/icon-question.gif b/deluge/ui/web/themes/images/gray/window/icon-question.gif
new file mode 100644
index 0000000..08abd82
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/icon-question.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/icon-warning.gif b/deluge/ui/web/themes/images/gray/window/icon-warning.gif
new file mode 100644
index 0000000..27ff98b
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/icon-warning.gif
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/left-corners.png b/deluge/ui/web/themes/images/gray/window/left-corners.png
new file mode 100644
index 0000000..f9f44ad
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/left-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/left-right.png b/deluge/ui/web/themes/images/gray/window/left-right.png
new file mode 100644
index 0000000..0272b5d
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/left-right.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/right-corners.png b/deluge/ui/web/themes/images/gray/window/right-corners.png
new file mode 100644
index 0000000..e0a58d3
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/right-corners.png
Binary files differ
diff --git a/deluge/ui/web/themes/images/gray/window/top-bottom.png b/deluge/ui/web/themes/images/gray/window/top-bottom.png
new file mode 100644
index 0000000..798cb9b
--- /dev/null
+++ b/deluge/ui/web/themes/images/gray/window/top-bottom.png
Binary files differ
diff --git a/deluge/ui/web/web.py b/deluge/ui/web/web.py
new file mode 100644
index 0000000..4d06247
--- /dev/null
+++ b/deluge/ui/web/web.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+from __future__ import print_function, unicode_literals
+
+import logging
+
+from twisted.internet.error import CannotListenError
+
+from deluge.common import run_profiled
+from deluge.ui.ui import UI
+
+log = logging.getLogger(__name__)
+
+
+class Web(UI):
+
+ cmd_description = """Web-based user interface (http://localhost:8112)"""
+
+ def __init__(self, *args, **kwargs):
+ super(Web, self).__init__(
+ 'web', *args, description='Starts the Deluge Web interface', **kwargs
+ )
+ self.__server = None
+
+ group = self.parser.add_argument_group(_('Web Server Options'))
+ group.add_argument(
+ '-i',
+ '--interface',
+ metavar='<ip_address>',
+ action='store',
+ help=_('IP address for web server to listen on'),
+ )
+ group.add_argument(
+ '-p',
+ '--port',
+ metavar='<port>',
+ type=int,
+ action='store',
+ help=_('Port for web server to listen on'),
+ )
+ group.add_argument(
+ '-b',
+ '--base',
+ metavar='<path>',
+ action='store',
+ help=_('Set the base path that the ui is running on'),
+ )
+ group.add_argument(
+ '--ssl', action='store_true', help=_('Force the web server to use SSL')
+ )
+ group.add_argument(
+ '--no-ssl',
+ action='store_true',
+ help=_('Force the web server to disable SSL'),
+ )
+ self.parser.add_process_arg_group()
+
+ @property
+ def server(self):
+ return self.__server
+
+ def start(self):
+ super(Web, self).start()
+
+ from deluge.ui.web import server
+
+ self.__server = server.DelugeWeb(options=self.options)
+
+ def run():
+ try:
+ self.server.install_signal_handlers()
+ self.server.start()
+ except CannotListenError as ex:
+ log.error(
+ '%s \nCheck that deluge-web or webui plugin is not already running.',
+ ex,
+ )
+ except Exception as ex:
+ log.exception(ex)
+ raise
+
+ run_profiled(
+ run, output_file=self.options.profile, do_profile=self.options.profile
+ )