summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2016-06-19 12:25:22 +0100
committerCalum Lind <calumlind+deluge@gmail.com>2016-06-19 12:30:29 +0100
commitf769afd3ac1ae99b98e0c82d05547723e2bfa1a0 (patch)
tree313ba211f5290bf35cc38aa3f9b1613bcac084a9
parente1d78c3de640182afcc1bd40b74431fd26420bcc (diff)
downloaddeluge-f769afd3ac1ae99b98e0c82d05547723e2bfa1a0.tar.gz
deluge-f769afd3ac1ae99b98e0c82d05547723e2bfa1a0.tar.bz2
deluge-f769afd3ac1ae99b98e0c82d05547723e2bfa1a0.zip
[WebUI] Compress javascript
-rw-r--r--deluge/ui/web/js/deluge-all-debug.js2360
-rw-r--r--deluge/ui/web/js/deluge-all.js2050
-rw-r--r--deluge/ui/web/js/ext-extensions-debug.js1914
-rw-r--r--deluge/ui/web/js/ext-extensions.js352
4 files changed, 4187 insertions, 2489 deletions
diff --git a/deluge/ui/web/js/deluge-all-debug.js b/deluge/ui/web/js/deluge-all-debug.js
index ceb6c6f96..ce0375ffc 100644
--- a/deluge/ui/web/js/deluge-all-debug.js
+++ b/deluge/ui/web/js/deluge-all-debug.js
@@ -1,1071 +1,4 @@
/*!
- * Deluge.add.Window.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-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',
- 'addfailed'
- );
- },
-
- /**
- * Create an id for the torrent before we have any info about it.
- */
- createTorrentId: function() {
- return new Date().getTime();
- }
-});
-/*!
- * Deluge.add.AddWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-
-Ext.namespace('Deluge.add');
-
-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],
- margins: '5 5 5 5',
- bbar: new Ext.Toolbar({
- items: [{
- iconCls: 'x-deluge-add-file',
- text: _('File'),
- handler: this.onFile,
- scope: this
- }, {
- 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.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();
- },
-
- 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];
- 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.url.on('addfailed', this.onTorrentAddFailed, this);
- }
-
- if (!this.file) {
- this.file = new Deluge.add.FileWindow();
- this.file.on('beforeadd', this.onTorrentBeforeAdd, this);
- this.file.on('add', this.onTorrentAdd, this);
- this.file.on('addfailed', this.onTorrentAddFailed, this);
- }
-
- this.optionsPanel.form.getDefaults();
- },
-
- 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);
- }
- },
-
- onTorrentAddFailed: function(torrentId) {
- var store = this.list.getStore();
- var torrentRecord = store.getById(torrentId);
- if (torrentRecord) {
- store.remove(torrentRecord);
- }
- },
-
- onUrl: function(button, event) {
- this.url.show();
- }
-});
-/*!
- * Deluge.add.File.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-Ext.ns('Deluge.add');
-
-/**
- * @class Deluge.add.FileWindow
- * @extends Deluge.add.Window
- */
-Deluge.add.FileWindow = Ext.extend(Deluge.add.Window, {
-
- title: _('Add from File'),
- layout: 'fit',
- width: 350,
- height: 115,
- modal: true,
- plain: true,
- buttonAlign: 'center',
- closeAction: 'hide',
- bodyStyle: 'padding: 10px 5px;',
- iconCls: 'x-deluge-add-file',
-
- initComponent: function() {
- Deluge.add.FileWindow.superclass.initComponent.call(this);
- this.addButton(_('Add'), this.onAddClick, this);
-
- this.form = this.add({
- xtype: 'form',
- baseCls: 'x-plain',
- labelWidth: 35,
- autoHeight: true,
- fileUpload: true,
- items: [{
- xtype: 'fileuploadfield',
- id: 'torrentFile',
- width: 280,
- height: 24,
- emptyText: _('Select a torrent'),
- fieldLabel: _('File'),
- name: 'file',
- buttonCfg: {
- text: _('Browse') + '...'
- }
- }]
- });
- },
-
- // private
- onAddClick: function(field, e) {
- if (this.form.getForm().isValid()) {
- this.torrentId = this.createTorrentId();
- this.form.getForm().submit({
- url: deluge.config.base + 'upload',
- waitMsg: _('Uploading your torrent...'),
- failure: this.onUploadFailure,
- success: this.onUploadSuccess,
- scope: this
- });
- var name = this.form.getForm().findField('torrentFile').value;
- name = name.split('\\').slice(-1)[0];
- this.fireEvent('beforeadd', this.torrentId, name);
- }
- },
-
- // private
- onGotInfo: function(info, obj, response, request) {
- info['filename'] = request.options.filename;
- this.fireEvent('add', this.torrentId, info);
- },
-
- // private
- onUploadFailure: function(form, action) {
- this.hide();
- Ext.MessageBox.show({
- title: _('Error'),
- msg: _('Failed to upload torrent'),
- buttons: Ext.MessageBox.OK,
- modal: false,
- icon: Ext.MessageBox.ERROR,
- iconCls: 'x-deluge-icon-error'
- });
- this.fireEvent('addfailed', this.torrentId);
- },
-
- // private
- onUploadSuccess: function(fp, upload) {
- this.hide();
- if (upload.result.success) {
- var filename = upload.result.files[0];
- this.form.getForm().findField('torrentFile').setValue('');
- deluge.client.web.get_torrent_info(filename, {
- success: this.onGotInfo,
- scope: this,
- filename: filename
- });
- }
- }
-});
-/*!
- * Deluge.add.FilesTab.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-Ext.namespace('Ext.deluge.add');
-/*!
- * Deluge.add.OptionsPanel.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-Ext.ns('Deluge.add');
-
-Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
-
- torrents: {},
-
- // layout options
- region: 'south',
- margins: '5 5 5 5',
- 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) {
- if (this.form.optionsManager.get('compact_allocation')) {
- Ext.Msg.show({
- title: _('Unable to set file priority!'),
- msg: _('File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?'),
- buttons: Ext.Msg.YESNO,
- fn: function(result) {
- if (result == 'yes') {
- this.form.optionsManager.update('compact_allocation', false);
- 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);
- } else {
- this.files.setDownload(nodes[0], oldValue, true);
- }
- },
- scope: this,
- icon: Ext.MessageBox.QUESTION
- });
- } else {
- 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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-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 Location'),
- border: false,
- autoHeight: true,
- defaultType: 'textfield',
- labelWidth: 1,
- fieldLabel: '',
- style: 'padding-bottom: 5px; margin-bottom: 0px;'
- });
- this.optionsManager.bind('download_location', fieldset.add({
- fieldLabel: '',
- name: 'download_location',
- width: 400,
- labelSeparator: ''
- }));
-
- var fieldset = this.add({
- xtype: 'fieldset',
- title: _('Move Completed Location'),
- border: false,
- autoHeight: true,
- defaultType: 'togglefield',
- labelWidth: 1,
- fieldLabel: '',
- style: 'padding-bottom: 5px; margin-bottom: 0px;'
- });
- var field = fieldset.add({
- fieldLabel: '',
- name: 'move_completed_path',
- width: 425
- });
- 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: _('Allocation'),
- border: false,
- autoHeight: true,
- defaultType: 'radio'
- });
-
- this.optionsManager.bind('compact_allocation', fieldset.add({
- xtype: 'radiogroup',
- columns: 1,
- vertical: true,
- labelSeparator: '',
- width: 80,
- items: [{
- name: 'compact_allocation',
- value: false,
- inputValue: false,
- boxLabel: _('Full'),
- fieldLabel: '',
- labelSeparator: ''
- }, {
- name: 'compact_allocation',
- value: true,
- inputValue: true,
- boxLabel: _('Compact'),
- fieldLabel: '',
- labelSeparator: ''
- }]
- }));
-
- fieldset = panel.add({
- title: _('Bandwidth'),
- border: false,
- autoHeight: true,
- bodyStyle: 'margin-left: 7px',
- labelWidth: 105,
- width: 200,
- defaultType: 'spinnerfield'
- });
- 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: ''
- }));
- },
-
- getDefaults: function() {
- var keys = ['add_paused','compact_allocation','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'];
-
- deluge.client.core.get_config_values(keys, {
- success: function(config) {
- var options = {
- 'file_priorities': [],
- 'add_paused': config.add_paused,
- 'compact_allocation': config.compact_allocation,
- '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
- }
- this.optionsManager.options = options;
- this.optionsManager.resetAll();
- },
- scope: this
- });
- }
-});
-/*!
- * Deluge.add.UrlWindow.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-
-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,
- failure: this.onDownloadFailed,
- 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
- });
- },
-
- onDownloadFailed: function(obj, resp, req) {
- Ext.MessageBox.show({
- title: _('Error'),
- msg: _('Failed to download torrent'),
- buttons: Ext.MessageBox.OK,
- modal: false,
- icon: Ext.MessageBox.ERROR,
- iconCls: 'x-deluge-icon-error'
- });
- this.fireEvent('addfailed', 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>
@@ -2472,6 +1405,1073 @@ Deluge.details.StatusTab = Ext.extend(Ext.Panel, {
}
});
/*!
+ * Deluge.add.Window.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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',
+ 'addfailed'
+ );
+ },
+
+ /**
+ * Create an id for the torrent before we have any info about it.
+ */
+ createTorrentId: function() {
+ return new Date().getTime();
+ }
+});
+/*!
+ * Deluge.add.AddWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+
+Ext.namespace('Deluge.add');
+
+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],
+ margins: '5 5 5 5',
+ bbar: new Ext.Toolbar({
+ items: [{
+ iconCls: 'x-deluge-add-file',
+ text: _('File'),
+ handler: this.onFile,
+ scope: this
+ }, {
+ 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.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();
+ },
+
+ 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];
+ 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.url.on('addfailed', this.onTorrentAddFailed, this);
+ }
+
+ if (!this.file) {
+ this.file = new Deluge.add.FileWindow();
+ this.file.on('beforeadd', this.onTorrentBeforeAdd, this);
+ this.file.on('add', this.onTorrentAdd, this);
+ this.file.on('addfailed', this.onTorrentAddFailed, this);
+ }
+
+ this.optionsPanel.form.getDefaults();
+ },
+
+ 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);
+ }
+ },
+
+ onTorrentAddFailed: function(torrentId) {
+ var store = this.list.getStore();
+ var torrentRecord = store.getById(torrentId);
+ if (torrentRecord) {
+ store.remove(torrentRecord);
+ }
+ },
+
+ onUrl: function(button, event) {
+ this.url.show();
+ }
+});
+/*!
+ * Deluge.add.File.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns('Deluge.add');
+
+/**
+ * @class Deluge.add.FileWindow
+ * @extends Deluge.add.Window
+ */
+Deluge.add.FileWindow = Ext.extend(Deluge.add.Window, {
+
+ title: _('Add from File'),
+ layout: 'fit',
+ width: 350,
+ height: 115,
+ modal: true,
+ plain: true,
+ buttonAlign: 'center',
+ closeAction: 'hide',
+ bodyStyle: 'padding: 10px 5px;',
+ iconCls: 'x-deluge-add-file',
+
+ initComponent: function() {
+ Deluge.add.FileWindow.superclass.initComponent.call(this);
+ this.addButton(_('Add'), this.onAddClick, this);
+
+ this.form = this.add({
+ xtype: 'form',
+ baseCls: 'x-plain',
+ labelWidth: 35,
+ autoHeight: true,
+ fileUpload: true,
+ items: [{
+ xtype: 'fileuploadfield',
+ id: 'torrentFile',
+ width: 280,
+ height: 24,
+ emptyText: _('Select a torrent'),
+ fieldLabel: _('File'),
+ name: 'file',
+ buttonCfg: {
+ text: _('Browse') + '...'
+ }
+ }]
+ });
+ },
+
+ // private
+ onAddClick: function(field, e) {
+ if (this.form.getForm().isValid()) {
+ this.torrentId = this.createTorrentId();
+ this.form.getForm().submit({
+ url: deluge.config.base + 'upload',
+ waitMsg: _('Uploading your torrent...'),
+ failure: this.onUploadFailure,
+ success: this.onUploadSuccess,
+ scope: this
+ });
+ var name = this.form.getForm().findField('torrentFile').value;
+ name = name.split('\\').slice(-1)[0];
+ this.fireEvent('beforeadd', this.torrentId, name);
+ }
+ },
+
+ // private
+ onGotInfo: function(info, obj, response, request) {
+ info['filename'] = request.options.filename;
+ this.fireEvent('add', this.torrentId, info);
+ },
+
+ // private
+ onUploadFailure: function(form, action) {
+ this.hide();
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: _('Failed to upload torrent'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error'
+ });
+ this.fireEvent('addfailed', this.torrentId);
+ },
+
+ // private
+ onUploadSuccess: function(fp, upload) {
+ this.hide();
+ if (upload.result.success) {
+ var filename = upload.result.files[0];
+ this.form.getForm().findField('torrentFile').setValue('');
+ deluge.client.web.get_torrent_info(filename, {
+ success: this.onGotInfo,
+ scope: this,
+ filename: filename
+ });
+ }
+ }
+});
+/*!
+ * Deluge.add.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace('Ext.deluge.add');
+/*!
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns('Deluge.add');
+
+Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, {
+
+ torrents: {},
+
+ // layout options
+ region: 'south',
+ margins: '5 5 5 5',
+ 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) {
+ if (this.form.optionsManager.get('compact_allocation')) {
+ Ext.Msg.show({
+ title: _('Unable to set file priority!'),
+ msg: _('File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?'),
+ buttons: Ext.Msg.YESNO,
+ fn: function(result) {
+ if (result == 'yes') {
+ this.form.optionsManager.update('compact_allocation', false);
+ 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);
+ } else {
+ this.files.setDownload(nodes[0], oldValue, true);
+ }
+ },
+ scope: this,
+ icon: Ext.MessageBox.QUESTION
+ });
+ } else {
+ 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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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 Location'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'textfield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding-bottom: 5px; margin-bottom: 0px;'
+ });
+ this.optionsManager.bind('download_location', fieldset.add({
+ fieldLabel: '',
+ name: 'download_location',
+ width: 400,
+ labelSeparator: ''
+ }));
+
+ var fieldset = this.add({
+ xtype: 'fieldset',
+ title: _('Move Completed Location'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'togglefield',
+ labelWidth: 1,
+ fieldLabel: '',
+ style: 'padding-bottom: 5px; margin-bottom: 0px;'
+ });
+ var field = fieldset.add({
+ fieldLabel: '',
+ name: 'move_completed_path',
+ width: 425
+ });
+ 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: _('Allocation'),
+ border: false,
+ autoHeight: true,
+ defaultType: 'radio'
+ });
+
+ this.optionsManager.bind('compact_allocation', fieldset.add({
+ xtype: 'radiogroup',
+ columns: 1,
+ vertical: true,
+ labelSeparator: '',
+ width: 80,
+ items: [{
+ name: 'compact_allocation',
+ value: false,
+ inputValue: false,
+ boxLabel: _('Full'),
+ fieldLabel: '',
+ labelSeparator: ''
+ }, {
+ name: 'compact_allocation',
+ value: true,
+ inputValue: true,
+ boxLabel: _('Compact'),
+ fieldLabel: '',
+ labelSeparator: ''
+ }]
+ }));
+
+ fieldset = panel.add({
+ title: _('Bandwidth'),
+ border: false,
+ autoHeight: true,
+ bodyStyle: 'margin-left: 7px',
+ labelWidth: 105,
+ width: 200,
+ defaultType: 'spinnerfield'
+ });
+ 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: ''
+ }));
+ },
+
+ getDefaults: function() {
+ var keys = ['add_paused','compact_allocation','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'];
+
+ deluge.client.core.get_config_values(keys, {
+ success: function(config) {
+ var options = {
+ 'file_priorities': [],
+ 'add_paused': config.add_paused,
+ 'compact_allocation': config.compact_allocation,
+ '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
+ }
+ this.optionsManager.options = options;
+ this.optionsManager.resetAll();
+ },
+ scope: this
+ });
+ }
+});
+/*!
+ * Deluge.add.UrlWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+
+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,
+ failure: this.onDownloadFailed,
+ 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
+ });
+ },
+
+ onDownloadFailed: function(obj, resp, req) {
+ Ext.MessageBox.show({
+ title: _('Error'),
+ msg: _('Failed to download torrent'),
+ buttons: Ext.MessageBox.OK,
+ modal: false,
+ icon: Ext.MessageBox.ERROR,
+ iconCls: 'x-deluge-icon-error'
+ });
+ this.fireEvent('addfailed', req.options.torrentId);
+ },
+
+ onGotInfo: function(info, obj, response, request) {
+ info['filename'] = request.options.filename;
+ this.fireEvent('add', request.options.torrentId, info);
+ }
+});
+/*!
* Deluge.preferences.BandwidthPage.js
*
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
@@ -7316,69 +7316,54 @@ Deluge.LoginWindow = Ext.extend(Ext.Window, {
*/
deluge.menus = {
- onTorrentAction: function(item, e) {
+ 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 'pause':
- case 'resume':
- deluge.client.core[action + '_torrent'](ids, {
- success: function() {
- deluge.ui.update();
- }
- });
- break;
- case 'top':
- case 'up':
- case 'down':
- case 'bottom':
- deluge.client.core['queue_' + action](ids, {
- success: function() {
- deluge.ui.update();
- }
- });
- break;
case 'edit_trackers':
deluge.editTrackers.show();
break;
- case 'update':
- deluge.client.core.force_reannounce(ids, {
- success: function() {
- deluge.ui.update();
- }
- });
- break;
case 'remove':
deluge.removeWindow.show(ids);
break;
- case 'recheck':
- deluge.client.core.force_recheck(ids, {
- success: function() {
- deluge.ui.update();
- }
- });
- break;
case 'move':
deluge.moveStorage.show(ids);
break;
}
- }
+ },
}
deluge.menus.torrent = new Ext.menu.Menu({
id: 'torrentMenu',
items: [{
- torrentAction: 'pause',
+ torrentAction: 'pause_torrent',
text: _('Pause'),
iconCls: 'icon-pause',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
}, {
- torrentAction: 'resume',
+ torrentAction: 'resume_torrent',
text: _('Resume'),
iconCls: 'icon-resume',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
}, '-', {
text: _('Options'),
@@ -7391,17 +7376,35 @@ deluge.menus.torrent = new Ext.menu.Menu({
hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
- text: _('5 KiB/s')
+ torrentAction: ['max_download_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('10 KiB/s')
+ torrentAction: ['max_download_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('30 KiB/s')
+ torrentAction: ['max_download_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('80 KiB/s')
+ torrentAction: ['max_download_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('300 KiB/s')
+ torrentAction: ['max_download_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
},{
- text: _('Unlimited')
+ torrentAction: ['max_download_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}]
})
}, {
@@ -7410,17 +7413,35 @@ deluge.menus.torrent = new Ext.menu.Menu({
hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
- text: _('5 KiB/s')
+ torrentAction: ['max_upload_speed', 5],
+ text: _('5 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('10 KiB/s')
+ torrentAction: ['max_upload_speed', 10],
+ text: _('10 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('30 KiB/s')
+ torrentAction: ['max_upload_speed', 30],
+ text: _('30 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('80 KiB/s')
+ torrentAction: ['max_upload_speed', 80],
+ text: _('80 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('300 KiB/s')
+ torrentAction: ['max_upload_speed', 300],
+ text: _('300 KiB/s'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
},{
- text: _('Unlimited')
+ torrentAction: ['max_upload_speed', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}]
})
}, {
@@ -7429,17 +7450,35 @@ deluge.menus.torrent = new Ext.menu.Menu({
hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
- text: _('50')
+ torrentAction: ['max_connections', 50],
+ text: _('50'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('100')
+ torrentAction: ['max_connections', 100],
+ text: _('100'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('200')
+ torrentAction: ['max_connections', 200],
+ text: _('200'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('300')
+ torrentAction: ['max_connections', 300],
+ text: _('300'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('500')
+ torrentAction: ['max_connections', 500],
+ text: _('500'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
},{
- text: _('Unlimited')
+ torrentAction: ['max_connections', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}]
})
}, {
@@ -7448,23 +7487,54 @@ deluge.menus.torrent = new Ext.menu.Menu({
hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
- text: _('0')
+ torrentAction: ['max_upload_slots', 0],
+ text: _('0'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('1')
+ torrentAction: ['max_upload_slots', 1],
+ text: _('1'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('2')
+ torrentAction: ['max_upload_slots', 2],
+ text: _('2'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('3')
+ torrentAction: ['max_upload_slots', 3],
+ text: _('3'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}, {
- text: _('5')
+ torrentAction: ['max_upload_slots', 5],
+ text: _('5'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
},{
- text: _('Unlimited')
+ torrentAction: ['max_upload_slots', -1],
+ text: _('Unlimited'),
+ handler: deluge.menus.onTorrentActionSetOpt,
+ scope: deluge.menus
}]
})
}, {
id: 'auto_managed',
text: _('Auto Managed'),
- checked: false
+ 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
+ }]
+ })
}]
})
}, '-', {
@@ -7473,60 +7543,60 @@ deluge.menus.torrent = new Ext.menu.Menu({
hideOnClick: false,
menu: new Ext.menu.Menu({
items: [{
- torrentAction: 'top',
+ torrentAction: 'queue_top',
text: _('Top'),
iconCls: 'icon-top',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
},{
- torrentAction: 'up',
+ torrentAction: 'queue_up',
text: _('Up'),
iconCls: 'icon-up',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
},{
- torrentAction: 'down',
+ torrentAction: 'queue_down',
text: _('Down'),
iconCls: 'icon-down',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
},{
- torrentAction: 'bottom',
+ torrentAction: 'queue_bottom',
text: _('Bottom'),
iconCls: 'icon-bottom',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
}]
})
}, '-', {
- torrentAction: 'update',
+ torrentAction: 'force_reannounce',
text: _('Update Tracker'),
iconCls: 'icon-update-tracker',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
}, {
torrentAction: 'edit_trackers',
text: _('Edit Trackers'),
iconCls: 'icon-edit-trackers',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionShow,
scope: deluge.menus
}, '-', {
torrentAction: 'remove',
text: _('Remove Torrent'),
iconCls: 'icon-remove',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionShow,
scope: deluge.menus
}, '-', {
- torrentAction: 'recheck',
+ torrentAction: 'force_recheck',
text: _('Force Recheck'),
iconCls: 'icon-recheck',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionMethod,
scope: deluge.menus
}, {
torrentAction: 'move',
text: _('Move Storage'),
iconCls: 'icon-move',
- handler: deluge.menus.onTorrentAction,
+ handler: deluge.menus.onTorrentActionShow,
scope: deluge.menus
}]
});
diff --git a/deluge/ui/web/js/deluge-all.js b/deluge/ui/web/js/deluge-all.js
index 1e6b5ada4..3c4e13216 100644
--- a/deluge/ui/web/js/deluge-all.js
+++ b/deluge/ui/web/js/deluge-all.js
@@ -1,258 +1,1792 @@
-Ext.ns("Deluge.add");Deluge.add.Window=Ext.extend(Ext.Window,{initComponent:function(){Deluge.add.Window.superclass.initComponent.call(this);this.addEvents("beforeadd","add","addfailed")},createTorrentId:function(){return(new Date).getTime()}});Ext.namespace("Deluge.add");
-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:!0,plain:!0,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);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:!0,renderer:function(a,b,c){return c.data.info_hash?String.format('<div class="x-deluge-add-torrent-name">{0}</div>',a):String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>',a)},dataIndex:"text"}],stripeRows:!0,singleSelect:!0,listeners:{selectionchange:{fn:this.onSelect,scope:this}},hideHeaders:!0,autoExpandColumn:"torrent",height:"100%",autoScroll:!0});this.add({region:"center",items:[this.list],
-margins:"5 5 5 5",bbar:new Ext.Toolbar({items:[{iconCls:"x-deluge-add-file",text:_("File"),handler:this.onFile,scope:this},{text:_("Url"),iconCls:"icon-add-url",handler:this.onUrl,scope:this},{text:_("Infohash"),iconCls:"icon-add-magnet",hidden:!0,disabled:!0},"->",{text:_("Remove"),iconCls:"icon-remove",handler:this.onRemove,scope:this}]})});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()},onAddClick:function(){var a=[];this.list&&(this.list.getStore().each(function(b){b=b.get("info_hash");a.push({path:this.optionsPanel.getFilename(b),options:this.optionsPanel.getOptions(b)})},this),deluge.client.web.add_torrents(a,{success:function(a){}}),this.clear(),this.hide())},onCancelClick:function(){this.clear();this.hide()},onFile:function(){this.file||(this.file=new Deluge.add.FileWindow);this.file.show()},onHide:function(){this.optionsPanel.setActiveTab(0);this.optionsPanel.files.setDisabled(!0);
-this.optionsPanel.form.setDisabled(!0)},onRemove:function(){if(this.list.getSelectionCount()){var a=this.list.getSelectedRecords()[0];this.list.getStore().remove(a);this.optionsPanel.clear();this.torrents&&this.torrents[a.id]&&delete this.torrents[a.id]}},onSelect:function(a,b){if(b.length){var c=this.list.getRecord(b[0]);this.optionsPanel.setTorrent(c.get("info_hash"))}else this.optionsPanel.files.setDisabled(!0),this.optionsPanel.form.setDisabled(!0)},onShow:function(){this.url||(this.url=new Deluge.add.UrlWindow,
-this.url.on("beforeadd",this.onTorrentBeforeAdd,this),this.url.on("add",this.onTorrentAdd,this),this.url.on("addfailed",this.onTorrentAddFailed,this));this.file||(this.file=new Deluge.add.FileWindow,this.file.on("beforeadd",this.onTorrentBeforeAdd,this),this.file.on("add",this.onTorrentAdd,this),this.file.on("addfailed",this.onTorrentAddFailed,this));this.optionsPanel.form.getDefaults()},onTorrentBeforeAdd:function(a,b){this.list.getStore().loadData([[a,null,b]],!0)},onTorrentAdd:function(a,b){var c=
-this.list.getStore().getById(a);b?(c.set("info_hash",b.info_hash),c.set("text",b.name),this.list.getStore().commitChanges(),this.optionsPanel.addTorrent(b),this.list.select(c)):(Ext.MessageBox.show({title:_("Error"),msg:_("Not a valid torrent"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"}),this.list.getStore().remove(c))},onTorrentAddFailed:function(a){var b=this.list.getStore();(a=b.getById(a))&&b.remove(a)},onUrl:function(a,b){this.url.show()}});Ext.ns("Deluge.add");
-Deluge.add.FileWindow=Ext.extend(Deluge.add.Window,{title:_("Add from File"),layout:"fit",width:350,height:115,modal:!0,plain:!0,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-file",initComponent:function(){Deluge.add.FileWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:35,autoHeight:!0,fileUpload:!0,items:[{xtype:"fileuploadfield",id:"torrentFile",width:280,
-height:24,emptyText:_("Select a torrent"),fieldLabel:_("File"),name:"file",buttonCfg:{text:_("Browse")+"..."}}]})},onAddClick:function(a,b){if(this.form.getForm().isValid()){this.torrentId=this.createTorrentId();this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your torrent..."),failure:this.onUploadFailure,success:this.onUploadSuccess,scope:this});var c=this.form.getForm().findField("torrentFile").value,c=c.split("\\").slice(-1)[0];this.fireEvent("beforeadd",this.torrentId,
-c)}},onGotInfo:function(a,b,c,d){a.filename=d.options.filename;this.fireEvent("add",this.torrentId,a)},onUploadFailure:function(a,b){this.hide();Ext.MessageBox.show({title:_("Error"),msg:_("Failed to upload torrent"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",this.torrentId)},onUploadSuccess:function(a,b){this.hide();if(b.result.success){var c=b.result.files[0];this.form.getForm().findField("torrentFile").setValue("");deluge.client.web.get_torrent_info(c,
-{success:this.onGotInfo,scope:this,filename:c})}}});Ext.ns("Deluge.add");
-Deluge.add.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{layout:"fit",title:_("Files"),autoScroll:!1,animate:!1,border:!1,disabled:!0,rootVisible:!1,columns:[{header:_("Filename"),width:295,dataIndex:"filename"},{header:_("Size"),width:60,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{header:_("Download"),width:65,dataIndex:"download",tpl:new Ext.XTemplate("{download:this.format}",{format:function(a){return'<div rel="chkbox" class="x-grid3-check-col'+
-(a?"-on":"")+'"> </div>'}})}],initComponent:function(){Deluge.add.FilesTab.superclass.initComponent.call(this);this.on("click",this.onNodeClick,this)},clearFiles:function(){var a=this.getRootNode();a.hasChildNodes()&&a.cascade(function(a){a.parentNode&&a.getOwnerTree()&&a.remove()})},setDownload:function(a,b,c){a.attributes.download=b;a.ui.updateColumns();if(a.isLeaf()){if(!c)return this.fireEvent("fileschecked",[a],b,!b)}else{var d=[a];a.cascade(function(a){a.attributes.download=b;a.ui.updateColumns();
-d.push(a)},this);if(!c)return this.fireEvent("fileschecked",d,b,!b)}},onNodeClick:function(a,b){"chkbox"==(new Ext.Element(b.target)).getAttribute("rel")&&this.setDownload(a,!a.attributes.download)}});Ext.namespace("Ext.deluge.add");Ext.ns("Deluge.add");
-Deluge.add.OptionsPanel=Ext.extend(Ext.TabPanel,{torrents:{},region:"south",margins:"5 5 5 5",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(a){this.torrents[a.info_hash]=a;var b={};this.walkFileTree(a.files_tree,function(a,c,g,e){"file"==c&&(b[g.index]=g.download)},this);
-var c=[];Ext.each(Ext.keys(b),function(a){c[a]=b[a]});a=this.form.optionsManager.changeId(a.info_hash,!0);this.form.optionsManager.setDefault("file_priorities",c);this.form.optionsManager.changeId(a,!0)},clear:function(){this.files.clearFiles();this.form.optionsManager.resetAll()},getFilename:function(a){return this.torrents[a].filename},getOptions:function(a){a=this.form.optionsManager.changeId(a,!0);var b=this.form.optionsManager.get();this.form.optionsManager.changeId(a,!0);Ext.each(b.file_priorities,
-function(a,d){b.file_priorities[d]=a?1:0});return b},setTorrent:function(a){if(a){this.torrentId=a;this.form.optionsManager.changeId(a);this.files.clearFiles();var b=this.files.getRootNode(),c=this.form.optionsManager.get("file_priorities");this.form.setDisabled(!1);this.torrents[a].files_tree?(this.walkFileTree(this.torrents[a].files_tree,function(a,b,g,e){a=new Ext.tree.TreeNode({download:g.index?c[g.index]:!0,filename:a,fileindex:g.index,leaf:"dir"!=b,size:g.length});e.appendChild(a);if("dir"==
-b)return a},this,b),b.firstChild.expand(),this.files.setDisabled(!1),this.files.show()):(this.form.show(),this.files.setDisabled(!0))}},walkFileTree:function(a,b,c,d){for(var f in a.contents){var g=a.contents[f],e=g.type,h=c?b.apply(c,[f,e,g,d]):b(f,e,g,d);"dir"==e&&this.walkFileTree(g,b,c,h)}},onFilesChecked:function(a,b,c){this.form.optionsManager.get("compact_allocation")?Ext.Msg.show({title:_("Unable to set file priority!"),msg:_("File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?"),
-buttons:Ext.Msg.YESNO,fn:function(d){"yes"==d?(this.form.optionsManager.update("compact_allocation",!1),Ext.each(a,function(a){if(!(0>a.attributes.fileindex)){var c=this.form.optionsManager.get("file_priorities");c[a.attributes.fileindex]=b;this.form.optionsManager.update("file_priorities",c)}},this)):this.files.setDownload(a[0],c,!0)},scope:this,icon:Ext.MessageBox.QUESTION}):Ext.each(a,function(a){if(!(0>a.attributes.fileindex)){var c=this.form.optionsManager.get("file_priorities");c[a.attributes.fileindex]=
-b;this.form.optionsManager.update("file_priorities",c)}},this)}});Ext.ns("Deluge.add");
-Deluge.add.OptionsTab=Ext.extend(Ext.form.FormPanel,{title:_("Options"),height:170,border:!1,bodyStyle:"padding: 5px",disabled:!0,labelWidth:1,initComponent:function(){Deluge.add.OptionsTab.superclass.initComponent.call(this);this.optionsManager=new Deluge.MultiOptionsManager;var a=this.add({xtype:"fieldset",title:_("Download Location"),border:!1,autoHeight:!0,defaultType:"textfield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});this.optionsManager.bind("download_location",
-a.add({fieldLabel:"",name:"download_location",width:400,labelSeparator:""}));a=this.add({xtype:"fieldset",title:_("Move Completed Location"),border:!1,autoHeight:!0,defaultType:"togglefield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});a=a.add({fieldLabel:"",name:"move_completed_path",width:425});this.optionsManager.bind("move_completed",a.toggle);this.optionsManager.bind("move_completed_path",a.input);var b=this.add({border:!1,layout:"column",defaultType:"fieldset"}),
-a=b.add({title:_("Allocation"),border:!1,autoHeight:!0,defaultType:"radio"});this.optionsManager.bind("compact_allocation",a.add({xtype:"radiogroup",columns:1,vertical:!0,labelSeparator:"",width:80,items:[{name:"compact_allocation",value:!1,inputValue:!1,boxLabel:_("Full"),fieldLabel:"",labelSeparator:""},{name:"compact_allocation",value:!0,inputValue:!0,boxLabel:_("Compact"),fieldLabel:"",labelSeparator:""}]}));a=b.add({title:_("Bandwidth"),border:!1,autoHeight:!0,bodyStyle:"margin-left: 7px",labelWidth:105,
-width:200,defaultType:"spinnerfield"});this.optionsManager.bind("max_download_speed",a.add({fieldLabel:_("Max Down Speed"),name:"max_download_speed",width:60}));this.optionsManager.bind("max_upload_speed",a.add({fieldLabel:_("Max Up Speed"),name:"max_upload_speed",width:60}));this.optionsManager.bind("max_connections",a.add({fieldLabel:_("Max Connections"),name:"max_connections",width:60}));this.optionsManager.bind("max_upload_slots",a.add({fieldLabel:_("Max Upload Slots"),name:"max_upload_slots",
-width:60}));a=b.add({title:_("General"),border:!1,autoHeight:!0,defaultType:"checkbox"});this.optionsManager.bind("add_paused",a.add({name:"add_paused",boxLabel:_("Add In Paused State"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",boxLabel:_("Prioritize First/Last Pieces"),fieldLabel:"",labelSeparator:""}))},getDefaults:function(){deluge.client.core.get_config_values("add_paused compact_allocation 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".split(" "),
-{success:function(a){this.optionsManager.options={file_priorities:[],add_paused:a.add_paused,compact_allocation:a.compact_allocation,download_location:a.download_location,move_completed:a.move_completed,move_completed_path:a.move_completed_path,max_connections:a.max_connections_per_torrent,max_download_speed:a.max_download_speed_per_torrent,max_upload_slots:a.max_upload_slots_per_torrent,max_upload_speed:a.max_upload_speed_per_torrent,prioritize_first_last_pieces:a.prioritize_first_last_pieces};this.optionsManager.resetAll()},
-scope:this})}});Ext.namespace("Deluge.add");
-Deluge.add.UrlWindow=Ext.extend(Deluge.add.Window,{title:_("Add from Url"),modal:!0,plain:!0,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 a=this.add({xtype:"form",defaultType:"textfield",baseCls:"x-plain",labelWidth:55});this.urlField=a.add({fieldLabel:_("Url"),id:"url",
-name:"url",width:"97%"});this.urlField.on("specialkey",this.onAdd,this);this.cookieField=a.add({fieldLabel:_("Cookies"),id:"cookies",name:"cookies",width:"97%"});this.cookieField.on("specialkey",this.onAdd,this)},onAddClick:function(a,b){if("url"!=a.id&&"cookies"!=a.id||b.getKey()==b.ENTER){a=this.urlField;var c=a.getValue(),d=this.cookieField.getValue(),f=this.createTorrentId();0==c.indexOf("magnet:?")&&-1<c.indexOf("xt=urn:btih")?deluge.client.web.get_magnet_info(c,{success:this.onGotInfo,scope:this,
-filename:c,torrentId:f}):deluge.client.web.download_torrent_from_url(c,d,{success:this.onDownload,failure:this.onDownloadFailed,scope:this,torrentId:f});this.hide();this.urlField.setValue("");this.fireEvent("beforeadd",f,c)}},onDownload:function(a,b,c,d){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a,torrentId:d.options.torrentId})},onDownloadFailed:function(a,b,c){Ext.MessageBox.show({title:_("Error"),msg:_("Failed to download torrent"),buttons:Ext.MessageBox.OK,
-modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",c.options.torrentId)},onGotInfo:function(a,b,c,d){a.filename=d.options.filename;this.fireEvent("add",d.options.torrentId,a)}});Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){a=a.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);return 256*(256*(256*+a[1]+ +a[2])+ +a[3])+ +a[4]},asQueuePosition:function(a){return-1<a?a:Number.MAX_VALUE},asName:function(a){return String(a).toLowerCase()}};
-Ext.namespace("Deluge.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"}]);Ext.namespace("Deluge.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:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]);Ext.namespace("Deluge.details");
-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(a){a.clear&&(a.clear.defer(100,a),a.disable())})},update:function(a){var b=deluge.torrents.getSelected();
-b?(this.items.each(function(a){a.disabled&&a.enable()}),a=a||this.getActiveTab(),a.update&&a.update(b.id)):this.clear()},onRender:function(a,b){Deluge.details.DetailsPanel.superclass.onRender.call(this,a,b);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(a){a.hasSelection()||this.clear()},this)},onTabChange:function(a,b){this.update(b)},
-onTorrentsClick:function(a,b,c){this.update()}});
-Deluge.details.DetailsTab=Ext.extend(Ext.Panel,{title:_("Details"),fields:{},autoScroll:!0,queuedItems:{},oldData:{},initComponent:function(){Deluge.details.DetailsTab.superclass.initComponent.call(this);this.addItem("torrent_name",_("Name"));this.addItem("hash",_("Hash"));this.addItem("path",_("Path"));this.addItem("size",_("Total Size"));this.addItem("files",_("# of files"));this.addItem("comment",_("Comment"));this.addItem("status",_("Status"));this.addItem("tracker",_("Tracker"))},onRender:function(a,
-b){Deluge.details.DetailsTab.superclass.onRender.call(this,a,b);this.body.setStyle("padding","10px");this.dl=Ext.DomHelper.append(this.body,{tag:"dl"},!0);for(var c in this.queuedItems)this.doAddItem(c,this.queuedItems[c])},addItem:function(a,b){this.rendered?this.doAddItem(a,b):this.queuedItems[a]=b},doAddItem:function(a,b){Ext.DomHelper.append(this.dl,{tag:"dt",cls:a,html:b+":"});this.fields[a]=Ext.DomHelper.append(this.dl,{tag:"dd",cls:a,html:""},!0)},clear:function(){if(this.fields){for(var a in this.fields)this.fields[a].dom.innerHTML=
-"";this.oldData={}}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Details,{success:this.onRequestComplete,scope:this,torrentId:a})},onRequestComplete:function(a,b,c,d){a={torrent_name:a.name,hash:d.options.torrentId,path:a.save_path,size:fsize(a.total_size),files:a.num_files,status:a.message,tracker:a.tracker,comment:a.comment};for(var f in this.fields)Ext.isDefined(a[f])&&a[f]!=this.oldData[f]&&(this.fields[f].dom.innerHTML=Ext.escapeHTML(a[f]));this.oldData=a}});
-Deluge.details.FilesTab=Ext.extend(Ext.ux.tree.TreeGrid,{title:_("Files"),rootVisible:!1,columns:[{header:_("Filename"),width:330,dataIndex:"filename"},{header:_("Size"),width:150,dataIndex:"size",tpl:new Ext.XTemplate("{size:this.fsize}",{fsize:function(a){return fsize(a)}})},{xtype:"tgrendercolumn",header:_("Progress"),width:150,dataIndex:"progress",renderer:function(a){a*=100;return Deluge.progressBar(a,this.col.width,a.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(a){return FILE_PRIORITY_CSS[a]},getName:function(a){return _(FILE_PRIORITY[a])}})}],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 a=this.getRootNode();a.hasChildNodes()&&a.cascade(function(a){var c=a.parentNode;c&&c.ownerTree&&c.removeChild(a)})},createFileTree:function(a){function b(a,c){for(var g in a.contents){var e=a.contents[g];
-"dir"==e.type?b(e,c.appendChild(new Ext.tree.TreeNode({text:g,filename:g,size:e.size,progress:e.progress,priority:e.priority}))):c.appendChild(new Ext.tree.TreeNode({text:g,filename:g,fileIndex:e.index,size:e.size,progress:e.progress,priority:e.priority,leaf:!0,iconCls:"x-deluge-file",uiProvider:Ext.ux.tree.TreeGridNodeUI}))}}var c=this.getRootNode();b(a,c);c.firstChild.expand()},update:function(a){this.torrentId!=a&&(this.clear(),this.torrentId=a);deluge.client.web.get_torrent_files(a,{success:this.onRequestComplete,
-scope:this,torrentId:a})},updateFileTree:function(a){function b(a,d){for(var f in a.contents){var g=a.contents[f],e=d.findChild("filename",f);e.attributes.size=g.size;e.attributes.progress=g.progress;e.attributes.priority=g.priority;e.ui.updateColumns();"dir"==g.type&&b(g,e)}}b(a,this.getRootNode())},onRender:function(a,b){Deluge.details.FilesTab.superclass.onRender.call(this,a,b);deluge.menus.filePriorities.on("itemclick",this.onItemClick,this);this.on("contextmenu",this.onContextMenu,this);this.sorter=
-new Ext.tree.TreeSorter(this,{folderSort:!0})},onContextMenu:function(a,b){b.stopEvent();var c=this.getSelectionModel();2>c.getSelectedNodes().length&&(c.clearSelections(),a.select());deluge.menus.filePriorities.showAt(b.getPoint())},onItemClick:function(a,b){switch(a.id){case "expandAll":this.expandAll();break;default:var c={};this.getRootNode().cascade(function(a){Ext.isEmpty(a.attributes.fileIndex)||(c[a.attributes.fileIndex]=a.attributes.priority)});var d=this.getSelectionModel().getSelectedNodes();
-Ext.each(d,function(b){b.isLeaf()?Ext.isEmpty(b.attributes.fileIndex)||(c[b.attributes.fileIndex]=a.filePriority):b.cascade(function(b){Ext.isEmpty(b.attributes.fileIndex)||(c[b.attributes.fileIndex]=a.filePriority)})});var f=Array(Ext.keys(c).length),g;for(g in c)f[g]=c[g];deluge.client.core.set_torrent_file_priorities(this.torrentId,f,{success:function(){Ext.each(d,function(b){b.setColumnValue(3,a.filePriority)})},scope:this})}},onRequestComplete:function(a,b){this.getRootNode().hasChildNodes()?
-this.updateFileTree(a):this.createFileTree(a)}});
-Deluge.details.OptionsTab=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({autoScroll:!0,bodyStyle:"padding: 5px;",border:!1,cls:"x-deluge-options",defaults:{autoHeight:!0,labelWidth:1,defaultType:"checkbox"},deferredRender:!1,layout:"column",title:_("Options")},a);Deluge.details.OptionsTab.superclass.constructor.call(this,a)},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:!1,stop_at_ratio:!1,stop_ratio:2,remove_at_ratio:!1,move_completed:!1,move_completed_path:"","private":!1,prioritize_first_last:!1}});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});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"});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"});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});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});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:!0,width:50,value:2,strategy:{xtype:"number",minValue:-1,maxValue:99999,incrementValue:.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:!0,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:!0});this.rightColumn=this.add({border:!1,autoHeight:!0,style:"margin-left: 5px",width:210});this.fieldsets.general=this.rightColumn.add({xtype:"fieldset",autoHeight:!0,defaultType:"checkbox",title:_("General"),layout:"form"});this.fields["private"]=
-this.fieldsets.general.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Private"),id:"private",disabled:!0});this.fields.prioritize_first_last=this.fieldsets.general.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Prioritize First/Last"),id:"prioritize_first_last"});for(var a in this.fields)this.optionsManager.bind(a,this.fields[a]);this.buttonPanel=this.rightColumn.add({layout:"hbox",xtype:"panel",border:!1});this.buttonPanel.add({id:"edit_trackers",xtype:"button",text:_("Edit Trackers"),cls:"x-btn-text-icon",
-iconCls:"x-deluge-edit-trackers",border:!1,width:100,handler:this.onEditTrackers,scope:this});this.buttonPanel.add({id:"apply",xtype:"button",text:_("Apply"),style:"margin-left: 10px;",border:!1,width:100,handler:this.onApply,scope:this})},onRender:function(a,b){Deluge.details.OptionsTab.superclass.onRender.call(this,a,b);this.layout=new Ext.layout.ColumnLayout;this.layout.setContainer(this);this.doLayout()},clear:function(){null!=this.torrentId&&(this.torrentId=null,this.optionsManager.changeId(null))},
-reset:function(){this.torrentId&&this.optionsManager.reset()},update:function(a){this.torrentId&&!a&&this.clear();a&&(this.torrentId!=a&&(this.torrentId=a,this.optionsManager.changeId(a)),deluge.client.web.get_torrent_status(a,Deluge.Keys.Options,{success:this.onRequestComplete,scope:this}))},onApply:function(){var a=this.optionsManager.getDirty();if(!Ext.isEmpty(a.prioritize_first_last)){var b=a.prioritize_first_last;deluge.client.core.set_torrent_prioritize_first_last(this.torrentId,b,{success:function(){this.optionsManager.set("prioritize_first_last",
-b)},scope:this})}deluge.client.core.set_torrent_options([this.torrentId],a,{success:function(){this.optionsManager.commit()},scope:this})},onEditTrackers:function(){deluge.editTrackers.show()},onMoveCompletedChecked:function(a,b){this.fields.move_completed_path.setDisabled(!b);b&&this.fields.move_completed_path.focus()},onStopRatioChecked:function(a,b){this.fields.remove_at_ratio.setDisabled(!b);this.fields.stop_ratio.setDisabled(!b)},onRequestComplete:function(a,b){this.fields["private"].setValue(a["private"]);
-this.fields["private"].setDisabled(!0);delete a["private"];a.auto_managed=a.is_auto_managed;this.optionsManager.setDefault(a);var c=this.optionsManager.get("stop_at_ratio");this.fields.remove_at_ratio.setDisabled(!c);this.fields.stop_ratio.setDisabled(!c);this.fields.move_completed_path.setDisabled(!this.optionsManager.get("move_completed"))}});
-(function(){function a(a){return a.replace(" ","").replace(" ","")?String.format('<img src="{0}flag/{1}" />',deluge.config.base,a):""}function b(a,b,c){b=1024==c.data.seed?"x-deluge-seed":"x-deluge-peer";c=a.split(":");2<c.length&&(a=c.pop(),a="["+c.join(":")+"]:"+a);return String.format('<div class="{0}">{1}</div>',b,a)}function c(a){a=(100*a).toFixed(0);return Deluge.progressBar(a,this.width-8,a+"%")}Deluge.details.PeersTab=Ext.extend(Ext.grid.GridPanel,{peers:{},constructor:function(d){d=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:!0,renderer:a,dataIndex:"country"},{header:"Address",width:125,sortable:!0,renderer:b,dataIndex:"ip"},{header:"Client",width:125,sortable:!0,renderer:fplain,dataIndex:"client"},{header:"Progress",width:150,sortable:!0,renderer:c,dataIndex:"progress"},{header:"Down Speed",width:100,sortable:!0,renderer:fspeed,dataIndex:"down_speed"},
-{header:"Up Speed",width:100,sortable:!0,renderer:fspeed,dataIndex:"up_speed"}],stripeRows:!0,deferredRender:!1,autoScroll:!0},d);Deluge.details.PeersTab.superclass.constructor.call(this,d)},clear:function(){this.getStore().removeAll();this.peers={}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Peers,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(a,b){if(a){var c=this.getStore(),e=[],h={};Ext.each(a.peers,function(a){if(this.peers[a.ip]){var b=c.getById(a.ip);
-b.beginEdit();for(var d in a)b.get(d)!=a[d]&&b.set(d,a[d]);b.endEdit()}else this.peers[a.ip]=1,e.push(new Deluge.data.Peer(a,a.ip));h[a.ip]=1},this);c.add(e);c.each(function(a){h[a.id]||(c.remove(a),delete this.peers[a.id])},this);c.commitChanges();var k=c.getSortState();k&&c.sort(k.field,k.direction)}}})})();Ext.ns("Deluge.details");
-Deluge.details.StatusTab=Ext.extend(Ext.Panel,{title:_("Status"),autoScroll:!0,onRender:function(a,b){Deluge.details.StatusTab.superclass.onRender.call(this,a,b);this.progressBar=this.add({xtype:"progress",cls:"x-deluge-status-progressbar"});this.status=this.add({cls:"x-deluge-status",id:"deluge-details-status",border:!1,width:1E3,listeners:{render:{fn:function(a){a.load({url:deluge.config.base+"render/tab_status.html",text:_("Loading")+"..."});a.getUpdater().on("update",this.onPanelUpdate,this)},
-scope:this}}})},clear:function(){this.progressBar.updateProgress(0," ");for(var a in this.fields)this.fields[a].innerHTML=""},update:function(a){this.fields||this.getFields();deluge.client.web.get_torrent_status(a,Deluge.Keys.Status,{success:this.onRequestComplete,scope:this})},onPanelUpdate:function(a,b){this.fields={};Ext.each(Ext.query("dd",this.status.body.dom),function(a){this.fields[a.className]=a},this)},onRequestComplete:function(a){seeders=-1<a.total_seeds?a.num_seeds+" ("+a.total_seeds+
-")":a.num_seeds;peers=-1<a.total_peers?a.num_peers+" ("+a.total_peers+")":a.num_peers;var b={downloaded:fsize(a.total_done,!0),uploaded:fsize(a.total_uploaded,!0),share:-1==a.ratio?"&infin;":a.ratio.toFixed(3),announce:ftime(a.next_announce),tracker_status:a.tracker_status,downspeed:a.download_payload_rate?fspeed(a.download_payload_rate):"0.0 KiB/s",upspeed:a.upload_payload_rate?fspeed(a.upload_payload_rate):"0.0 KiB/s",eta:ftime(a.eta),pieces:a.num_pieces+" ("+fsize(a.piece_length)+")",seeders:seeders,
-peers:peers,avail:a.distributed_copies.toFixed(3),active_time:ftime(a.active_time),seeding_time:ftime(a.seeding_time),seed_rank:a.seed_rank,time_added:fdate(a.time_added)};b.auto_managed=_(a.is_auto_managed?"True":"False");b.downloaded+=" ("+(a.total_payload_download?fsize(a.total_payload_download):"0.0 KiB")+")";b.uploaded+=" ("+(a.total_payload_upload?fsize(a.total_payload_upload):"0.0 KiB")+")";for(var c in this.fields)this.fields[c].innerHTML=b[c];b=a.state+" "+a.progress.toFixed(2)+"%";this.progressBar.updateProgress(a.progress/
-100,b)}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Bandwidth=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Bandwidth"),layout:"form",labelWidth:10},a);Deluge.preferences.Bandwidth.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Bandwidth.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Global Bandwidth Usage"),labelWidth:200,defaultType:"spinnerfield",defaults:{minValue:-1,maxValue:99999},
-style:"margin-bottom: 0px; padding-bottom: 0px;",autoHeight:!0});a.bind("max_connections_global",b.add({name:"max_connections_global",fieldLabel:_("Maximum Connections"),width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_slots_global",b.add({name:"max_upload_slots_global",fieldLabel:_("Maximum Upload Slots"),width:80,value:-1,decimalPrecision:0}));a.bind("max_download_speed",b.add({name:"max_download_speed",fieldLabel:_("Maximum Download Speed (KiB/s)"),width:80,value:-1,decimalPrecision:1}));
-a.bind("max_upload_speed",b.add({name:"max_upload_speed",fieldLabel:_("Maximum Upload Speed (KiB/s)"),width:80,value:-1,decimalPrecision:1}));a.bind("max_half_open_connections",b.add({name:"max_half_open_connections",fieldLabel:_("Maximum Half-Open Connections"),width:80,value:-1,decimalPrecision:0}));a.bind("max_connections_per_second",b.add({name:"max_connections_per_second",fieldLabel:_("Maximum Connection Attempts per Second"),width:80,value:-1,decimalPrecision:0}));b=this.add({xtype:"fieldset",
-border:!1,title:"",defaultType:"checkbox",style:"padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;",autoHeight:!0});a.bind("ignore_limits_on_local_network",b.add({name:"ignore_limits_on_local_network",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Ignore limits on local network")}));a.bind("rate_limit_ip_overhead",b.add({name:"rate_limit_ip_overhead",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Rate limit IP overhead")}));b=this.add({xtype:"fieldset",border:!1,
-title:_("Per Torrent Bandwidth Usage"),style:"margin-bottom: 0px; padding-bottom: 0px;",defaultType:"spinnerfield",labelWidth:200,defaults:{minValue:-1,maxValue:99999},autoHeight:!0});a.bind("max_connections_per_torrent",b.add({name:"max_connections_per_torrent",fieldLabel:_("Maximum Connections"),width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_slots_per_torrent",b.add({name:"max_upload_slots_per_torrent",fieldLabel:_("Maximum Upload Slots"),width:80,value:-1,decimalPrecision:0}));a.bind("max_download_speed_per_torrent",
-b.add({name:"max_download_speed_per_torrent",fieldLabel:_("Maximum Download Speed (KiB/s)"),width:80,value:-1,decimalPrecision:0}));a.bind("max_upload_speed_per_torrent",b.add({name:"max_upload_speed_per_torrent",fieldLabel:_("Maximum Upload Speed (KiB/s)"),width:80,value:-1,decimalPrecision:0}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Cache=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Cache"),layout:"form",initComponent:function(){Deluge.preferences.Cache.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Settings"),autoHeight:!0,labelWidth:180,defaultType:"spinnerfield",defaults:{decimalPrecision:0,minValue:-1,maxValue:999999}});a.bind("cache_size",b.add({fieldLabel:_("Cache Size (16 KiB Blocks)"),name:"cache_size",width:60,value:512}));
-a.bind("cache_expiry",b.add({fieldLabel:_("Cache Expiry (seconds)"),name:"cache_expiry",width:60,value:60}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Daemon=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Daemon"),layout:"form",initComponent:function(){Deluge.preferences.Daemon.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Port"),autoHeight:!0,defaultType:"spinnerfield"});a.bind("daemon_port",b.add({fieldLabel:_("Daemon port"),name:"daemon_port",value:58846,decimalPrecision:0,minValue:-1,maxValue:99999}));b=this.add({xtype:"fieldset",border:!1,
-title:_("Connections"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("allow_remote",b.add({fieldLabel:"",height:22,labelSeparator:"",boxLabel:_("Allow Remote Connections"),name:"allow_remote"}));b=this.add({xtype:"fieldset",border:!1,title:_("Other"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("new_release_check",b.add({fieldLabel:"",labelSeparator:"",height:40,boxLabel:_("Periodically check the website for new releases"),id:"new_release_check"}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Downloads=Ext.extend(Ext.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Downloads"),layout:"form",autoHeight:!0,width:320},a);Deluge.preferences.Downloads.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Downloads.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Folders"),labelWidth:150,defaultType:"togglefield",autoHeight:!0,labelAlign:"top",width:300,
-style:"margin-bottom: 5px; padding-bottom: 5px;"});a.bind("download_location",b.add({xtype:"textfield",name:"download_location",fieldLabel:_("Download to"),width:280}));var c=b.add({name:"move_completed_path",fieldLabel:_("Move completed to"),width:280});a.bind("move_completed",c.toggle);a.bind("move_completed_path",c.input);c=b.add({name:"torrentfiles_location",fieldLabel:_("Copy of .torrent files to"),width:280});a.bind("copy_torrent_file",c.toggle);a.bind("torrentfiles_location",c.input);c=b.add({name:"autoadd_location",
-fieldLabel:_("Autoadd .torrent files from"),width:280});a.bind("autoadd_enable",c.toggle);a.bind("autoadd_location",c.input);b=this.add({xtype:"fieldset",border:!1,title:_("Allocation"),autoHeight:!0,labelWidth:1,defaultType:"radiogroup",style:"margin-bottom: 5px; margin-top: 0; padding-bottom: 5px; padding-top: 0;",width:240});a.bind("compact_allocation",b.add({name:"compact_allocation",width:200,labelSeparator:"",defaults:{width:80,height:22,name:"compact_allocation"},items:[{boxLabel:_("Use Full"),
-inputValue:!1},{boxLabel:_("Use Compact"),inputValue:!0}]}));b=this.add({xtype:"fieldset",border:!1,title:_("Options"),autoHeight:!0,labelWidth:1,defaultType:"checkbox",style:"margin-bottom: 0; padding-bottom: 0;",width:280});a.bind("prioritize_first_last_pieces",b.add({name:"prioritize_first_last_pieces",labelSeparator:"",height:22,boxLabel:_("Prioritize first and last pieces of torrent")}));a.bind("add_paused",b.add({name:"add_paused",labelSeparator:"",height:22,boxLabel:_("Add torrents in Paused state")}))}});
-Ext.namespace("Deluge.preferences");
-Deluge.preferences.Encryption=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Encryption"),initComponent:function(){Deluge.preferences.Encryption.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Settings"),autoHeight:!0,defaultType:"combo",width:300});a.bind("enc_in_policy",b.add({fieldLabel:_("Inbound"),mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],data:[[0,_("Forced")],[1,_("Enabled")],
-[2,_("Disabled")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));a.bind("enc_out_policy",b.add({fieldLabel:_("Outbound"),mode:"local",width:150,store:new Ext.data.SimpleStore({fields:["id","text"],data:[[0,_("Forced")],[1,_("Enabled")],[2,_("Disabled")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));a.bind("enc_level",b.add({fieldLabel:_("Level"),mode:"local",width:150,store:new Ext.data.SimpleStore({fields:["id","text"],data:[[0,_("Handshake")],
-[1,_("Full Stream")],[2,_("Either")]]}),editable:!1,triggerAction:"all",valueField:"id",displayField:"text"}));a.bind("enc_prefer_rc4",b.add({xtype:"checkbox",name:"enc_prefer_rc4",height:40,hideLabel:!0,boxLabel:_("Encrypt entire stream")}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.InstallPluginWindow=Ext.extend(Ext.Window,{title:_("Install Plugin"),layout:"fit",height:115,width:350,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closeAction:"hide",iconCls:"x-deluge-install-plugin",modal:!0,plain:!0,initComponent:function(){Deluge.add.FileWindow.superclass.initComponent.call(this);this.addButton(_("Install"),this.onInstall,this);this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:70,autoHeight:!0,fileUpload:!0,items:[{xtype:"fileuploadfield",
-width:240,emptyText:_("Select an egg"),fieldLabel:_("Plugin Egg"),name:"file",buttonCfg:{text:_("Browse")+"..."}}]})},onInstall:function(a,b){this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your plugin..."),success:this.onUploadSuccess,scope:this})},onUploadPlugin:function(a,b,c,d){this.fireEvent("pluginadded")},onUploadSuccess:function(a,b){this.hide();if(b.result.success){var c=this.form.getForm().getFieldValues().file,c=c.split("\\").slice(-1)[0],d=b.result.files[0];
-this.form.getForm().setValues({file:""});deluge.client.web.upload_plugin(c,d,{success:this.onUploadPlugin,scope:this,filename:c})}}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Interface=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Interface"),layout:"form",initComponent:function(){Deluge.preferences.Interface.superclass.initComponent.call(this);var a=this.optionsManager=new Deluge.OptionsManager;this.on("show",this.onPageShow,this);var b=this.add({xtype:"fieldset",border:!1,title:_("Interface"),style:"margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("show_session_speed",b.add({name:"show_session_speed",
-height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Show session speed in titlebar")}));a.bind("sidebar_show_zero",b.add({name:"sidebar_show_zero",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Show filters with zero torrents")}));a.bind("sidebar_multiple_filters",b.add({name:"sidebar_multiple_filters",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Allow the use of multiple filters at once")}));b=this.add({xtype:"fieldset",border:!1,title:_("Password"),style:"margin-bottom: 0px; padding-bottom: 0px; padding-top: 5px",
-autoHeight:!0,labelWidth:110,defaultType:"textfield",defaults:{width:180,inputType:"password"}});this.oldPassword=b.add({name:"old_password",fieldLabel:_("Old Password")});this.newPassword=b.add({name:"new_password",fieldLabel:_("New Password")});this.confirmPassword=b.add({name:"confirm_password",fieldLabel:_("Confirm Password")});b.add({xtype:"panel",autoHeight:!0,border:!1,width:320,bodyStyle:"padding-left: 230px"}).add({xtype:"button",text:_("Change"),listeners:{click:{fn:this.onPasswordChange,
-scope:this}}});b=this.add({xtype:"fieldset",border:!1,title:_("Server"),style:"margin-top: 0px; padding-top: 0px; margin-bottom: 0px; padding-bottom: 0px",autoHeight:!0,labelWidth:110,defaultType:"spinnerfield",defaults:{width:80}});a.bind("session_timeout",b.add({name:"session_timeout",fieldLabel:_("Session Timeout"),decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("port",b.add({name:"port",fieldLabel:_("Port"),decimalPrecision:0,minValue:-1,maxValue:99999}));this.httpsField=a.bind("https",
-b.add({xtype:"checkbox",name:"https",hideLabel:!0,width:280,height:22,boxLabel:_("Use SSL (paths relative to Deluge config folder)")}));this.httpsField.on("check",this.onSSLCheck,this);this.pkeyField=a.bind("pkey",b.add({xtype:"textfield",disabled:!0,name:"pkey",width:180,fieldLabel:_("Private Key")}));this.certField=a.bind("cert",b.add({xtype:"textfield",disabled:!0,name:"cert",width:180,fieldLabel:_("Certificate")}))},onApply:function(){var a=this.optionsManager.getDirty();if(!Ext.isObjectEmpty(a)){deluge.client.web.set_config(a,
-{success:this.onSetConfig,scope:this});for(var b in deluge.config)deluge.config[b]=this.optionsManager.get(b)}},onGotConfig:function(a){this.optionsManager.set(a)},onPasswordChange:function(){var a=this.newPassword.getValue();if(a!=this.confirmPassword.getValue())Ext.MessageBox.show({title:_("Invalid Password"),msg:_("Your passwords don't match!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});else{var b=this.oldPassword.getValue();deluge.client.auth.change_password(b,
-a,{success:function(a){a?(Ext.MessageBox.show({title:_("Change Successful"),msg:_("Your password was successfully changed!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.INFO,iconCls:"x-deluge-icon-info"}),this.oldPassword.setValue(""),this.newPassword.setValue(""),this.confirmPassword.setValue("")):(Ext.MessageBox.show({title:_("Password"),msg:_("Your old password was incorrect!"),buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"}),this.oldPassword.setValue(""))},
-scope:this})}},onSetConfig:function(){this.optionsManager.commit()},onPageShow:function(){deluge.client.web.get_config({success:this.onGotConfig,scope:this})},onSSLCheck:function(a,b){this.pkeyField.setDisabled(!b);this.certField.setDisabled(!b)}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Network=Ext.extend(Ext.form.FormPanel,{border:!1,layout:"form",title:_("Network"),initComponent:function(){Deluge.preferences.Network.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Incoming Ports"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("random_port",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Ports"),name:"random_port",
-height:22,listeners:{check:{fn:function(a,b){this.listenPorts.setDisabled(b)},scope:this}}}));this.listenPorts=b.add({xtype:"spinnergroup",name:"listen_ports",fieldLabel:"",labelSeparator:"",colCfg:{labelWidth:40,style:"margin-right: 10px;"},items:[{fieldLabel:"From",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}},{fieldLabel:"To",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}}]});a.bind("listen_ports",this.listenPorts);b=this.add({xtype:"fieldset",
-border:!1,title:_("Outgoing Ports"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("random_outgoing_ports",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Ports"),name:"random_outgoing_ports",height:22,listeners:{check:{fn:function(a,b){this.outgoingPorts.setDisabled(b)},scope:this}}}));this.outgoingPorts=b.add({xtype:"spinnergroup",name:"outgoing_ports",fieldLabel:"",labelSeparator:"",colCfg:{labelWidth:40,style:"margin-right: 10px;"},
-items:[{fieldLabel:"From",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}},{fieldLabel:"To",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}}]});a.bind("outgoing_ports",this.outgoingPorts);b=this.add({xtype:"fieldset",border:!1,title:_("Network Interface"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:!0,labelWidth:1,defaultType:"textfield"});a.bind("listen_interface",b.add({name:"listen_interface",fieldLabel:"",labelSeparator:"",width:200}));
-b=this.add({xtype:"fieldset",border:!1,title:_("TOS"),style:"margin-bottom: 5px; padding-bottom: 0px;",bodyStyle:"margin: 0px; padding: 0px",autoHeight:!0,defaultType:"textfield"});a.bind("peer_tos",b.add({name:"peer_tos",fieldLabel:_("Peer TOS Byte"),width:80}));b=this.add({xtype:"fieldset",border:!1,title:_("Network Extras"),autoHeight:!0,layout:"table",layoutConfig:{columns:3},defaultType:"checkbox"});a.bind("upnp",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("UPnP"),name:"upnp"}));a.bind("natpmp",
-b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("NAT-PMP"),ctCls:"x-deluge-indent-checkbox",name:"natpmp"}));a.bind("utpex",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Peer Exchange"),ctCls:"x-deluge-indent-checkbox",name:"utpex"}));a.bind("lsd",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("LSD"),name:"lsd"}));a.bind("dht",b.add({fieldLabel:"",labelSeparator:"",boxLabel:_("DHT"),ctCls:"x-deluge-indent-checkbox",name:"dht"}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Other=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Other"),layout:"form"},a);Deluge.preferences.Other.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Other.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("Updates"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("new_release_check",b.add({fieldLabel:"",labelSeparator:"",
-height:22,name:"new_release_check",boxLabel:_("Be alerted about new releases")}));b=this.add({xtype:"fieldset",border:!1,title:_("System Information"),autoHeight:!0,labelWidth:1,defaultType:"checkbox"});b.add({xtype:"panel",border:!1,bodyCfg:{html:_("Help us improve Deluge by sending us your Python version, PyGTK version, OS and processor types. Absolutely no other information is sent.")}});a.bind("send_info",b.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Yes, please send anonymous statistics"),
-name:"send_info"}));b=this.add({xtype:"fieldset",border:!1,title:_("GeoIP Database"),autoHeight:!0,labelWidth:80,defaultType:"textfield"});a.bind("geoip_db_location",b.add({name:"geoip_db_location",fieldLabel:_("Location"),width:200}))}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Plugins=Ext.extend(Ext.Panel,{layout:"border",title:_("Plugins"),border:!1,height:400,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>{details}</dd></dl>'),initComponent:function(){Deluge.preferences.Plugins.superclass.initComponent.call(this);this.defaultValues={version:"",email:"",homepage:"",
-details:""};this.pluginTemplate.compile();this.list=this.add({xtype:"listview",store:new Ext.data.ArrayStore({fields:[{name:"enabled",mapping:0},{name:"plugin",mapping:1}]}),columns:[{id:"enabled",header:_("Enabled"),width:.2,sortable:!0,tpl:new Ext.XTemplate("{enabled:this.getCheckbox}",{getCheckbox:function(a){return'<div class="x-grid3-check-col'+(a?"-on":"")+'" rel="chkbox"> </div>'}}),dataIndex:"enabled"},{id:"plugin",header:_("Plugin"),width:.8,sortable:!0,dataIndex:"plugin"}],singleSelect:!0,
-autoExpandColumn:"plugin",listeners:{selectionchange:{fn:this.onPluginSelect,scope:this}}});this.panel=this.add({region:"center",autoScroll:!0,margins:"5 5 5 5",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}]})});this.pluginInfo=(this.pluginInfo=this.add({xtype:"panel",
-border:!0,height:160,region:"south",margins:"0 5 5 5"})).add({xtype:"fieldset",title:_("Info"),border:!1,autoHeight:!0,labelWidth:1,style:"margin-top: 5px;"}).add({xtype:"panel",border:!1,bodyCfg:{style:"margin-left: 10px"}});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(a){deluge.client.core.disable_plugin(a)},enablePlugin:function(a){deluge.client.core.enable_plugin(a)},setInfo:function(a){this.pluginInfo.rendered&&(this.pluginInfo.body.dom.innerHTML=this.pluginTemplate.apply(a||this.defaultValues))},updatePlugins:function(){deluge.client.web.get_plugins({success:this.onGotPlugins,scope:this})},updatePluginsGrid:function(){var a=[];Ext.each(this.availablePlugins,function(b){-1<this.enabledPlugins.indexOf(b)?a.push([!0,b]):a.push([!1,
-b])},this);this.list.getStore().loadData(a)},onNodeClick:function(a,b,c,d){"chkbox"==(new Ext.Element(d.target)).getAttribute("rel")&&(a=a.getStore().getAt(b),a.set("enabled",!a.get("enabled")),a.commit(),a.get("enabled")?this.enablePlugin(a.get("plugin")):this.disablePlugin(a.get("plugin")))},onFindMorePlugins:function(){window.open("http://dev.deluge-torrent.org/wiki/Plugins")},onGotPlugins:function(a){this.enabledPlugins=a.enabled_plugins;this.availablePlugins=a.available_plugins;this.setInfo();
-this.updatePluginsGrid()},onGotPluginInfo:function(a){this.setInfo({author:a.Author,version:a.Version,email:a["Author-email"],homepage:a["Home-page"],details:a.Description});delete a},onInstallPluginWindow:function(){this.installWindow||(this.installWindow=new Deluge.preferences.InstallPluginWindow,this.installWindow.on("pluginadded",this.onPluginInstall,this));this.installWindow.show()},onPluginEnabled:function(a){a=this.list.getStore().find("plugin",a);-1!=a&&(a=this.list.getStore().getAt(a),a.set("enabled",
-!0),a.commit())},onPluginDisabled:function(a){a=this.list.getStore().find("plugin",a);-1!=a&&(a=this.list.getStore().getAt(a),a.set("enabled",!1),a.commit())},onPluginInstall:function(){this.updatePlugins()},onPluginSelect:function(a,b){if(0!=b.length){var c=a.getRecords(b)[0];deluge.client.web.get_plugin_info(c.get("plugin"),{success:this.onGotPluginInfo,scope:this})}},onPreferencesShow:function(){this.updatePlugins()},onPluginInfoRender:function(a,b){this.setInfo()}});Ext.namespace("Deluge.preferences");
-PreferencesRecord=Ext.data.Record.create([{name:"name",type:"string"}]);
-Deluge.preferences.PreferencesWindow=Ext.extend(Ext.Window,{currentPage:null,title:_("Preferences"),layout:"border",width:485,height:500,buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-preferences",plain:!0,resizable:!1,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:!0,listeners:{selectionchange:{fn:this.onPageSelect,
-scope:this}},hideHeaders:!0,autoExpandColumn:"name",deferredRender:!1,autoScroll:!0,collapsible:!0});this.add({region:"west",title:_("Categories"),items:[this.list],width:120,margins:"5 0 5 5",cmargins:"5 0 5 5"});this.configPanel=this.add({type:"container",autoDestroy:!1,region:"center",layout:"card",layoutConfig:{deferredRender:!0},autoScroll:!0,width:300,margins:"5 5 5 5",cmargins:"5 5 5 5"});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(a){a=this.optionsManager.getDirty();Ext.isObjectEmpty(a)||deluge.client.core.set_config(a,{success:this.onSetConfig,scope:this});for(var b in this.pages)if(this.pages[b].onApply)this.pages[b].onApply()},getOptionsManager:function(){return this.optionsManager},addPage:function(a){var b=this.list.getStore(),c=
-a.title;b.add([new PreferencesRecord({name:c})]);a.bodyStyle="padding: 5px";a.preferences=this;this.pages[c]=this.configPanel.add(a);this.pages[c].index=-1;return this.pages[c]},removePage:function(a){var b=a.title,c=this.list.getStore();c.removeAt(c.find("name",b));this.configPanel.remove(a);delete this.pages[a.title]},selectPage:function(a){0>this.pages[a].index&&(this.pages[a].index=this.configPanel.items.indexOf(this.pages[a]));this.list.select(this.pages[a].index)},doSelectPage:function(a){0>
-this.pages[a].index&&(this.pages[a].index=this.configPanel.items.indexOf(this.pages[a]));this.configPanel.getLayout().setActiveItem(this.pages[a].index);this.currentPage=a},onGotConfig:function(a){this.getOptionsManager().set(a)},onPageSelect:function(a,b){var c=a.getRecord(b[0]);this.doSelectPage(c.get("name"))},onSetConfig:function(){this.getOptionsManager().commit()},onAfterRender:function(){this.list.getSelectionCount()||this.list.select(0);this.configPanel.getLayout().setActiveItem(0)},onShow:function(){deluge.client.core&&
-deluge.client.core.get_config({success:this.onGotConfig,scope:this})},onClose:function(){this.hide()},onOk:function(){var a=this.optionsManager.getDirty();Ext.isObjectEmpty(a)||deluge.client.core.set_config(a,{success:this.onSetConfig,scope:this});for(var b in this.pages)if(this.pages[b].onOk)this.pages[b].onOk();this.hide()}});Ext.ns("Deluge.preferences");
-Deluge.preferences.ProxyField=Ext.extend(Ext.form.FieldSet,{border:!1,autoHeight:!0,labelWidth:70,initComponent:function(){Deluge.preferences.ProxyField.superclass.initComponent.call(this);this.proxyType=this.add({xtype:"combo",fieldLabel:_("Type"),name:"proxytype",mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],data:[[0,_("None")],[1,_("Socksv4")],[2,_("Socksv5")],[3,_("Socksv5 with Auth")],[4,_("HTTP")],[5,_("HTTP with Auth")]]}),editable:!1,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"),width:220});this.hostname.on("change",this.onFieldChange,this);this.port=this.add({xtype:"spinnerfield",name:"port",fieldLabel:_("Port"),width:80,decimalPrecision:0,minValue:-1,maxValue:99999});this.port.on("change",this.onFieldChange,this);this.username=this.add({xtype:"textfield",name:"username",
-fieldLabel:_("Username"),width:220});this.username.on("change",this.onFieldChange,this);this.password=this.add({xtype:"textfield",name:"password",fieldLabel:_("Password"),inputType:"password",width:220});this.password.on("change",this.onFieldChange,this);this.setting=!1},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()}},
-setValue:function(a){this.setting=!0;this.proxyType.setValue(a.type);var b=this.proxyType.getStore().find("id",a.type),c=this.proxyType.getStore().getAt(b);this.hostname.setValue(a.hostname);this.port.setValue(a.port);this.username.setValue(a.username);this.password.setValue(a.password);this.onTypeSelect(this.type,c,b);this.setting=!1},onFieldChange:function(a,b,c){if(!this.setting){b=this.getValue();var d=Ext.apply({},b);d[a.getName()]=c;this.fireEvent("change",this,b,d)}},onTypeSelect:function(a,
-b,c){a=b.get("id");0<a?(this.hostname.show(),this.port.show()):(this.hostname.hide(),this.port.hide());3==a||5==a?(this.username.show(),this.password.show()):(this.username.hide(),this.password.hide())}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Proxy=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:!1,title:_("Proxy"),layout:"form",autoScroll:!0},a);Deluge.preferences.Proxy.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Proxy.superclass.initComponent.call(this);this.peer=this.add(new Deluge.preferences.ProxyField({title:_("Peer"),name:"peer"}));this.peer.on("change",this.onProxyChange,this);this.web_seed=this.add(new Deluge.preferences.ProxyField({title:_("Web Seed"),
-name:"web_seed"}));this.web_seed.on("change",this.onProxyChange,this);this.tracker=this.add(new Deluge.preferences.ProxyField({title:_("Tracker"),name:"tracker"}));this.tracker.on("change",this.onProxyChange,this);this.dht=this.add(new Deluge.preferences.ProxyField({title:_("DHT"),name:"dht"}));this.dht.on("change",this.onProxyChange,this);deluge.preferences.getOptionsManager().bind("proxies",this)},getValue:function(){return{dht:this.dht.getValue(),peer:this.peer.getValue(),tracker:this.tracker.getValue(),
-web_seed:this.web_seed.getValue()}},setValue:function(a){for(var b in a)this[b].setValue(a[b])},onProxyChange:function(a,b,c){b=this.getValue();var d=Ext.apply({},b);d[a.getName()]=c;this.fireEvent("change",this,b,d)}});Ext.namespace("Deluge.preferences");
-Deluge.preferences.Queue=Ext.extend(Ext.form.FormPanel,{border:!1,title:_("Queue"),layout:"form",initComponent:function(){Deluge.preferences.Queue.superclass.initComponent.call(this);var a=deluge.preferences.getOptionsManager(),b=this.add({xtype:"fieldset",border:!1,title:_("General"),style:"padding-top: 5px;",autoHeight:!0,labelWidth:1,defaultType:"checkbox"});a.bind("queue_new_to_top",b.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Queue new torrents to top"),name:"queue_new_to_top"}));
-b=this.add({xtype:"fieldset",border:!1,title:_("Active Torrents"),autoHeight:!0,labelWidth:150,defaultType:"spinnerfield",style:"margin-bottom: 0px; padding-bottom: 0px;"});a.bind("max_active_limit",b.add({fieldLabel:_("Total Active"),name:"max_active_limit",value:8,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("max_active_downloading",b.add({fieldLabel:_("Total Active Downloading"),name:"max_active_downloading",value:3,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));
-a.bind("max_active_seeding",b.add({fieldLabel:_("Total Active Seeding"),name:"max_active_seeding",value:5,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));a.bind("dont_count_slow_torrents",b.add({xtype:"checkbox",name:"dont_count_slow_torrents",height:40,hideLabel:!0,boxLabel:_("Do not count slow torrents")}));b=this.add({xtype:"fieldset",border:!1,title:_("Seeding"),autoHeight:!0,labelWidth:150,defaultType:"spinnerfield",style:"margin-bottom: 0px; padding-bottom: 0px; margin-top: 0; padding-top: 0;"});
-a.bind("share_ratio_limit",b.add({fieldLabel:_("Share Ratio Limit"),name:"share_ratio_limit",value:8,width:80,incrementValue:.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));a.bind("seed_time_ratio_limit",b.add({fieldLabel:_("Share Time Ratio"),name:"seed_time_ratio_limit",value:3,width:80,incrementValue:.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));a.bind("seed_time_limit",b.add({fieldLabel:_("Seed Time (m)"),name:"seed_time_limit",value:5,
-width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));b=this.add({xtype:"fieldset",border:!1,autoHeight:!0,layout:"table",layoutConfig:{columns:2},labelWidth:0,defaultType:"checkbox",defaults:{fieldLabel:"",labelSeparator:""}});this.stopAtRatio=b.add({name:"stop_seed_at_ratio",boxLabel:_("Stop seeding when share ratio reaches:")});this.stopAtRatio.on("check",this.onStopRatioCheck,this);a.bind("stop_seed_at_ratio",this.stopAtRatio);this.stopRatio=b.add({xtype:"spinnerfield",name:"stop_seed_ratio",
-ctCls:"x-deluge-indent-checkbox",disabled:!0,value:"2.0",width:60,incrementValue:.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2});a.bind("stop_seed_ratio",this.stopRatio);this.removeAtRatio=b.add({name:"remove_seed_at_ratio",ctCls:"x-deluge-indent-checkbox",boxLabel:_("Remove torrent when share ratio is reached"),disabled:!0,colspan:2});a.bind("remove_seed_at_ratio",this.removeAtRatio)},onStopRatioCheck:function(a,b){this.stopRatio.setDisabled(!b);this.removeAtRatio.setDisabled(!b)}});
-Ext.ns("Deluge");
-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(a){if("menucheckitem"==a.getXType())if("other"==a.value)a.on("click",this.onOtherClicked,this);else a.on("checkchange",this.onLimitChanged,this)},this)},setValue:function(a){var b=!1;this.value=a=0==a?-1:a;var c=null;this.items.each(function(d){d.setChecked&&(d.suspendEvents(),
-d.value==a?(d.setChecked(!0),b=!0):d.setChecked(!1),d.resumeEvents());"other"==d.value&&(c=d)});b||(c.suspendEvents(),c.setChecked(!0),c.resumeEvents())},onLimitChanged:function(a,b){if(b&&"other"!=a.value){var c={};c[a.group]=a.value;deluge.client.core.set_config(c,{success:function(){deluge.ui.update()}})}},onOtherClicked:function(a,b){this.otherWin.group=a.group;this.otherWin.setValue(this.value);this.otherWin.show()}});Ext.namespace("Deluge");
-Deluge.OptionsManager=Ext.extend(Ext.util.Observable,{constructor:function(a){a=a||{};this.binds={};this.changed={};this.options=a&&a.options||{};this.focused=null;this.addEvents({add:!0,changed:!0,reset:!0});this.on("changed",this.onChange,this);Deluge.OptionsManager.superclass.constructor.call(this)},addOptions:function(a){this.options=Ext.applyIf(this.options,a)},bind:function(a,b){this.binds[a]=this.binds[a]||[];this.binds[a].push(b);b._doption=a;b.on("focus",this.onFieldFocus,this);b.on("blur",
-this.onFieldBlur,this);b.on("change",this.onFieldChange,this);b.on("check",this.onFieldChange,this);b.on("spin",this.onFieldChange,this);return b},commit:function(){this.options=Ext.apply(this.options,this.changed);this.reset()},convertValueType:function(a,b){if(Ext.type(a)!=Ext.type(b))switch(Ext.type(a)){case "string":b=String(b);break;case "number":b=Number(b);break;case "boolean":"string"==Ext.type(b)?(b=b.toLowerCase(),b="true"==b||"1"==b||"on"==b?!0:!1):b=Boolean(b)}return b},get:function(){if(1==
-arguments.length){var a=arguments[0];return this.isDirty(a)?this.changed[a]:this.options[a]}var b={};Ext.each(arguments,function(a){this.has(a)&&(b[a]=this.isDirty(a)?this.changed[a]:this.options[a])},this);return b},getDefault:function(a){return this.options[a]},getDirty:function(){return this.changed},isDirty:function(a){return!Ext.isEmpty(this.changed[a])},has:function(a){return this.options[a]},reset:function(){this.changed={}},set:function(a,b){if(void 0!==a)if("object"==typeof a){var c=a;this.options=
-Ext.apply(this.options,c);for(a in c)this.onChange(a,c[a])}else this.options[a]=b,this.onChange(a,b)},update:function(a,b){if(void 0!==a)if(void 0===b)for(var c in a)this.update(c,a[c]);else{c=this.getDefault(a);b=this.convertValueType(c,b);var d=this.get(a);d!=b&&(c==b?this.isDirty(a)&&delete this.changed[a]:this.changed[a]=b,this.fireEvent("changed",a,b,d))}},onFieldBlur:function(a,b){this.focused==a&&(this.focused=null)},onFieldChange:function(a,b){a.field&&(a=a.field);this.update(a._doption,a.getValue())},
-onFieldFocus:function(a,b){this.focused=a},onChange:function(a,b,c){Ext.isEmpty(this.binds[a])||Ext.each(this.binds[a],function(a){a!=this.focused&&a.setValue(b)},this)}});Ext.ns("Deluge");
-Deluge.AddConnectionWindow=Ext.extend(Ext.Window,{title:_("Add Connection"),iconCls:"x-deluge-add-window-icon",layout:"fit",width:300,height:195,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"),name:"host",anchor:"75%",value:""},{xtype:"spinnerfield",fieldLabel:_("Port"),name:"port",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:65535},value:"58846",anchor:"40%"},{fieldLabel:_("Username"),name:"username",anchor:"75%",value:""},{fieldLabel:_("Password"),anchor:"75%",name:"password",inputType:"password",value:""}]})},onAddClick:function(){var a=this.form.getForm().getValues();deluge.client.web.add_host(a.host,a.port,a.username,a.password,
-{success:function(a){a[0]?this.fireEvent("hostadded"):Ext.MessageBox.show({title:_("Error"),msg:"Unable to add host: "+a[1],buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.hide()},scope:this})},onHide:function(){this.form.getForm().reset()}});Ext.ns("Deluge");
-Deluge.AddTrackerWindow=Ext.extend(Ext.Window,{title:_("Add Tracker"),layout:"fit",width:375,height:150,plain:!0,closable:!0,resizable:!1,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"),name:"trackers",anchor:"100%"}]})},onAddClick:function(){var a=this.form.getForm().findField("trackers").getValue(),a=a.split("\n"),b=[];Ext.each(a,function(a){Ext.form.VTypes.url(a)&&b.push(a)},this);this.fireEvent("add",b);this.hide();this.form.getForm().findField("trackers").setValue("")},onCancelClick:function(){this.form.getForm().findField("trackers").setValue("");this.hide()}});Ext.namespace("Ext.ux.util");
-Ext.ux.util.RpcClient=Ext.extend(Ext.util.Observable,{_components:[],_methods:[],_requests:{},_url:null,_optionKeys:["scope","success","failure"],constructor:function(a){Ext.ux.util.RpcClient.superclass.constructor.call(this,a);this._url=a.url||null;this._id=0;this.addEvents("connected","error");this.reloadMethods()},reloadMethods:function(){this._execute("system.listMethods",{success:this._setMethods,scope:this})},_execute:function(a,b){b=b||{};b.params=b.params||[];b.id=this._id;var c=Ext.encode({method:a,
-params:b.params,id:b.id});this._id++;return Ext.Ajax.request({url:this._url,method:"POST",success:this._onSuccess,failure:this._onFailure,scope:this,jsonData:c,options:b})},_onFailure:function(a,b){var c=b.options;errorObj={id:c.id,result:null,error:{msg:"HTTP: "+a.status+" "+a.statusText,code:255}};this.fireEvent("error",errorObj,a,b);"function"==Ext.type(c.failure)&&(c.scope?c.failure.call(c.scope,errorObj,a,b):c.failure(errorObj,a,b))},_onSuccess:function(a,b){var c=Ext.decode(a.responseText),
-d=b.options;c.error?(this.fireEvent("error",c,a,b),"function"==Ext.type(d.failure)&&(d.scope?d.failure.call(d.scope,c,a,b):d.failure(c,a,b))):"function"==Ext.type(d.success)&&(d.scope?d.success.call(d.scope,c.result,c,a,b):d.success(c.result,c,a,b))},_parseArgs:function(a){var b=[];Ext.each(a,function(a){b.push(a)});a=b[b.length-1];if("object"==Ext.type(a)){var c=Ext.keys(a),d=!1;Ext.each(this._optionKeys,function(a){-1<c.indexOf(a)&&(d=!0)});d?b.remove(a):a={}}else a={};a.params=b;return a},_setMethods:function(a){var b=
-{},c=this;Ext.each(a,function(a){var d=a.split("."),e=b[d[0]]||{};e[d[1]]=function(){var b=c._parseArgs(arguments);return c._execute(a,b)};b[d[0]]=e});for(var d in b)c[d]=b[d];Ext.each(this._components,function(a){!a in b&&delete this[a]},this);this._components=Ext.keys(b);this.fireEvent("connected",this)}});
-Deluge.ConnectionManager=Ext.extend(Ext.Window,{layout:"fit",width:300,height:220,bodyStyle:"padding: 10px 5px;",buttonAlign:"right",closeAction:"hide",closable:!0,plain:!0,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:3},{name:"host",mapping:1},{name:"port",mapping:2},{name:"version",mapping:4}],id:0}),columns:[{header:_("Status"),width:.24,sortable:!0,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:.51,sortable:!0,tpl:"{host}:{port}",dataIndex:"host"},{header:_("Version"),width:.25,sortable:!0,tpl:'<tpl if="version">{version}</tpl>',dataIndex:"version"}],singleSelect:!0,listeners:{selectionchange:{fn:this.onSelectionChanged,scope:this}}});this.panel=this.add({autoScroll:!0,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-remove",cls:"x-btn-text-icon",
-text:_("Remove"),iconCls:"icon-remove",handler:this.onRemoveClick,disabled:!0,scope:this},"->",{id:"cm-stop",cls:"x-btn-text-icon",text:_("Stop Daemon"),iconCls:"icon-error",handler:this.onStopClick,disabled:!0,scope:this}]})});this.update=this.update.createDelegate(this)},checkConnected:function(){deluge.client.web.connected({success:function(a){a?deluge.events.fire("connect"):this.show()},scope:this})},disconnect:function(a){deluge.events.fire("disconnect");a&&!this.isVisible()&&this.show()},loadHosts:function(){deluge.client.web.get_hosts({success:this.onGetHosts,
-scope:this})},update:function(){this.list.getStore().each(function(a){deluge.client.web.get_host_status(a.id,{success:this.onGetHostStatus,scope:this})},this)},updateButtons:function(a){var b=this.buttons[1],c=a.get("status");"Connected"==c?(b.enable(),b.setText(_("Disconnect"))):"Offline"==c?b.disable():(b.enable(),b.setText(_("Connect")));"Offline"==c?"127.0.0.1"==a.get("host")||"localhost"==a.get("host")?(this.stopHostButton.enable(),this.stopHostButton.setText(_("Start Daemon"))):this.stopHostButton.disable():
-(this.stopHostButton.enable(),this.stopHostButton.setText(_("Stop Daemon")))},onAddClick:function(a,b){this.addWindow||(this.addWindow=new Deluge.AddConnectionWindow,this.addWindow.on("hostadded",this.onHostAdded,this));this.addWindow.show()},onHostAdded:function(){this.loadHosts()},onClose:function(a){this.hide()},onConnect:function(a){if(a=this.list.getSelectedRecords()[0])"Connected"==a.get("status")?deluge.client.web.disconnect({success:function(a){this.update(this);deluge.events.fire("disconnect")},
-scope:this}):(deluge.client.web.connect(a.id,{success:function(a){deluge.client.reloadMethods();deluge.client.on("connected",function(a){deluge.events.fire("connect")},this,{single:!0})}}),this.hide())},onGetHosts:function(a){this.list.getStore().loadData(a);Ext.each(a,function(a){deluge.client.web.get_host_status(a[0],{success:this.onGetHostStatus,scope:this})},this)},onGetHostStatus:function(a){var b=this.list.getStore().getById(a[0]);b.set("status",a[3]);b.set("version",a[4]);b.commit();this.list.getSelectedRecords()[0]==
-b&&this.updateButtons(b)},onHide:function(){this.running&&window.clearInterval(this.running)},onLogin:function(){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(a){this.checkConnected();"yes"==a&&(deluge.preferences.show(),deluge.preferences.selectPage("Interface"));deluge.client.web.set_config({first_login:!1})},this):this.checkConnected()},onLogout:function(){this.disconnect();
-!this.hidden&&this.rendered&&this.hide()},onRemoveClick:function(a){var b=this.list.getSelectedRecords()[0];b&&deluge.client.web.remove_host(b.id,{success:function(a){a?this.list.getStore().remove(b):Ext.MessageBox.show({title:_("Error"),msg:a[1],buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"})},scope:this})},onSelectionChanged:function(a,b){b[0]?(this.removeHostButton.enable(),this.stopHostButton.enable(),this.stopHostButton.setText(_("Stop Daemon")),this.updateButtons(this.list.getRecord(b[0]))):
-(this.removeHostButton.disable(),this.stopHostButton.disable())},onShow:function(){if(!this.addHostButton){var a=this.panel.getBottomToolbar();this.addHostButton=a.items.get("cm-add");this.removeHostButton=a.items.get("cm-remove");this.stopHostButton=a.items.get("cm-stop")}this.loadHosts();this.running||(this.running=window.setInterval(this.update,2E3,this))},onStopClick:function(a,b){var c=this.list.getSelectedRecords()[0];c&&("Offline"==c.get("status")?deluge.client.web.start_daemon(c.get("port")):
-deluge.client.web.stop_daemon(c.id,{success:function(a){a[0]||Ext.MessageBox.show({title:_("Error"),msg:a[1],buttons:Ext.MessageBox.OK,modal:!1,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"})}}))}});Ext.state.Manager.setProvider(new Ext.state.CookieProvider({expires:new Date((new Date).getTime()+31536E7)}));
-Ext.apply(Ext,{escapeHTML:function(a){a=String(a).replace("<","&lt;").replace(">","&gt;");return a.replace("&","&amp;")},isObjectEmpty:function(a){for(var b in a)return!1;return!0},areObjectsEqual:function(a,b){var c=!0;if(!a||!b)return!1;for(var d in a)a[d]!=b[d]&&(c=!1);return c},keys:function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c);return b},values:function(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(a[c]);return b},splat:function(a){var b=Ext.type(a);return b?"array"!=
-b?[a]:a:[]}});Ext.getKeys=Ext.keys;Ext.BLANK_IMAGE_URL=deluge.config.base+"images/s.gif";Ext.USE_NATIVE_JSON=!0;
-Ext.apply(Deluge,{pluginStore:{},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>',progressBar:function(a,b,c,d){d=Ext.value(d,10);a=(b/100*a).toFixed(0);return String.format(Deluge.progressTpl,
-c,b,a-1,0<a-d?a-d:0)},createPlugin:function(a){return new Deluge.pluginStore[a]},hasPlugin:function(a){return Deluge.pluginStore[a]?!0:!1},registerPlugin:function(a,b){Deluge.pluginStore[a]=b}});deluge.plugins={};FILE_PRIORITY={9:"Mixed",0:"Do Not Download",1:"Normal Priority",2:"High Priority",5:"High Priority",7:"Highest Priority",Mixed:9,"Do Not Download":0,"Normal Priority":1,"High Priority":5,"Highest Priority":7};
-FILE_PRIORITY_CSS={9:"x-mixed-download",0:"x-no-download",1:"x-normal-download",2:"x-high-download",5:"x-high-download",7:"x-highest-download"};Ext.ns("Deluge");
-Deluge.EditTrackerWindow=Ext.extend(Ext.Window,{title:_("Edit Tracker"),layout:"fit",width:375,height:110,plain:!0,closable:!0,resizable:!1,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"),name:"tracker",anchor:"100%"}]})},show:function(a){Deluge.EditTrackerWindow.superclass.show.call(this);this.record=a;this.form.getForm().findField("tracker").setValue(a.data.url)},onCancelClick:function(){this.hide()},onHide:function(){this.form.getForm().findField("tracker").setValue("")},onSaveClick:function(){var a=this.form.getForm().findField("tracker").getValue();this.record.set("url",a);this.record.commit();this.hide()}});Ext.ns("Deluge");
-Deluge.EditTrackersWindow=Ext.extend(Ext.Window,{title:_("Edit Trackers"),layout:"fit",width:350,height:220,plain:!0,closable:!0,resizable:!0,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:.1,dataIndex:"tier"},{header:_("Tracker"),width:.9,dataIndex:"url"}],columnSort:{sortClasses:["",""]},stripeRows:!0,singleSelect:!0,listeners:{dblclick:{fn:this.onListNodeDblClicked,scope:this},selectionchange:{fn:this.onSelect,
-scope:this}}});this.panel=this.add({margins:"0 0 0 0",items:[this.list],autoScroll:!0,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(a){var b=this.list.getStore();Ext.each(a,function(a){var d=!1,f=-1;b.each(function(b){b.get("tier")>f&&(f=b.get("tier"));if(a==b.get("tracker"))return d=!0,!1},this);d||b.add(new b.recordType({tier:f+1,url:a}))},this)},onCancelClick:function(){this.hide()},onEditClick:function(){this.editWindow.show(this.list.getSelectedRecords()[0])},onHide:function(){this.list.getStore().removeAll()},onListNodeDblClicked:function(a,b,c,d){this.editWindow.show(this.list.getRecord(c))},onOkClick:function(){var a=
-[];this.list.getStore().each(function(b){a.push({tier:b.get("tier"),url:b.get("url")})},this);deluge.client.core.set_torrent_trackers(this.torrentId,a,{failure:this.onSaveFail,scope:this});this.hide()},onRemoveClick:function(){this.list.getStore().remove(this.list.getSelectedRecords()[0])},onRequestComplete:function(a){this.list.getStore().loadData(a);this.list.getStore().sort("tier","ASC")},onSaveFail:function(){},onSelect:function(a){a.getSelectionCount()&&this.panel.getBottomToolbar().items.get(4).enable()},
-onShow:function(){this.panel.getBottomToolbar().items.get(4).disable();var a=deluge.torrents.getSelected();this.torrentId=a.id;deluge.client.core.get_torrent_status(a.id,["trackers"],{success:this.onRequestComplete,scope:this})},onDownClick:function(){var a=this.list.getSelectedRecords()[0];a&&(a.set("tier",a.get("tier")+1),a.store.sort("tier","ASC"),a.store.commitChanges(),this.list.select(a.store.indexOf(a)))},onUpClick:function(){var a=this.list.getSelectedRecords()[0];a&&0!=a.get("tier")&&(a.set("tier",
-a.get("tier")-1),a.store.sort("tier","ASC"),a.store.commitChanges(),this.list.select(a.store.indexOf(a)))}});
-Deluge.EventsManager=Ext.extend(Ext.util.Observable,{constructor:function(){this.toRegister=[];this.on("login",this.onLogin,this);Deluge.EventsManager.superclass.constructor.call(this)},addListener:function(a,b,c,d){this.addEvents(a);/[A-Z]/.test(a.substring(0,1))&&(deluge.client?deluge.client.web.register_event_listener(a):this.toRegister.push(a));Deluge.EventsManager.superclass.addListener.call(this,a,b,c,d)},getEvents:function(){deluge.client.web.get_events({success:this.onGetEventsSuccess,failure:this.onGetEventsFailure,
-scope:this})},start:function(){Ext.each(this.toRegister,function(a){deluge.client.web.register_event_listener(a)});this.running=!0;this.errorCount=0;this.getEvents()},stop:function(){this.running=!1},onLogin:function(){this.start()},onGetEventsSuccess:function(a){this.running&&(a&&Ext.each(a,function(a){var c=a[1];c.splice(0,0,a[0]);this.fireEvent.apply(this,c)},this),this.getEvents())},onGetEventsFailure:function(a,b){this.running&&(!b.isTimeout&&3<=this.errorCount++?this.stop():this.getEvents())}});
-Deluge.EventsManager.prototype.on=Deluge.EventsManager.prototype.addListener;Deluge.EventsManager.prototype.fire=Deluge.EventsManager.prototype.fireEvent;deluge.events=new Deluge.EventsManager;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"}]})}});Ext.ns("Deluge");
-Deluge.FilterPanel=Ext.extend(Ext.Panel,{autoScroll:!0,border:!1,show_zero:null,initComponent:function(){Deluge.FilterPanel.superclass.initComponent.call(this);this.filterType=this.initialConfig.filter;var a=this.filterType.replace("_"," "),b=a.split(" "),a="";Ext.each(b,function(b){fl=b.substring(0,1).toUpperCase();a+=fl+b.substring(1)+" "});this.setTitle(_(a));b=Deluge.FilterPanel.templates[this.filterType]?Deluge.FilterPanel.templates[this.filterType]:'<div class="x-deluge-filter x-deluge-{filter:lowercase}">{filter} ({count})</div>';
-this.list=this.add({xtype:"listview",singleSelect:!0,hideHeaders:!0,reserveScrollOffset:!0,store:new Ext.data.ArrayStore({idIndex:0,fields:["filter","count"]}),columns:[{id:"filter",sortable:!1,tpl:b,dataIndex:"filter"}]});this.relayEvents(this.list,["selectionchange"])},getState:function(){if(this.list.getSelectionCount()){var a=this.list.getSelectedRecords()[0];if("All"!=a.id)return a.id}},getStates:function(){return this.states},getStore:function(){return this.list.getStore()},updateStates:function(a){this.states=
-{};Ext.each(a,function(a){this.states[a[0]]=a[1]},this);if(null==this.show_zero?!deluge.config.sidebar_show_zero:!this.show_zero){var b=[];Ext.each(a,function(a){(0<a[1]||a[0]==_("All"))&&b.push(a)});a=b}var c=this.getStore(),d={};Ext.each(a,function(a,b){var e=c.getById(a[0]);e||(e=new c.recordType({filter:a[0],count:a[1]}),e.id=a[0],c.insert(b,e));e.beginEdit();e.set("filter",a[0]);e.set("count",a[1]);e.endEdit();d[a[0]]=!0},this);c.each(function(a){if(!d[a.id]){var b=this.list.getSelectedRecords()[0];
-c.remove(a);b.id==a.id&&this.list.select(0)}},this);c.commitChanges();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={date:function(a){function b(a,b){for(var f=a+"";f.length<b;)f="0"+f;return f}a=new Date(1E3*a);return String.format("{0}/{1}/{2} {3}:{4}:{5}",b(a.getDate(),2),b(a.getMonth()+1,2),a.getFullYear(),b(a.getHours(),2),b(a.getMinutes(),2),b(a.getSeconds(),2))},size:function(a,b){if(!a&&!b)return"";a/=1024;if(1024>a)return a.toFixed(1)+" KiB";a/=1024;return 1024>a?a.toFixed(1)+" MiB":(a/1024).toFixed(1)+" GiB"},sizeShort:function(a,b){if(!a&&!b)return"";a/=1024;if(1024>a)return a.toFixed(1)+
-" K";a/=1024;return 1024>a?a.toFixed(1)+" M":(a/1024).toFixed(1)+" G"},speed:function(a,b){return a||b?fsize(a,b)+"/s":""},timeRemaining:function(a){if(0==a)return"&infin;";a=a.toFixed(0);if(60>a)return a+"s";a/=60;if(60>a){var b=Math.floor(a);a=Math.round(60*(a-b));return 0<a?b+"m "+a+"s":b+"m"}a/=60;if(24>a){var c=Math.floor(a),b=Math.round(60*(a-c));return 0<b?c+"h "+b+"m":c+"h"}a/=24;b=Math.floor(a);c=Math.round(24*(a-b));return 0<c?b+"d "+c+"h":b+"d"},plain:function(a){return a},cssClassEscape:function(a){return a.toLowerCase().replace(".",
-"_")}};var fsize=Deluge.Formatters.size,fsize_short=Deluge.Formatters.sizeShort,fspeed=Deluge.Formatters.speed,ftime=Deluge.Formatters.timeRemaining,fdate=Deluge.Formatters.date,fplain=Deluge.Formatters.plain;Ext.util.Format.cssClassEscape=Deluge.Formatters.cssClassEscape;
-Deluge.Keys={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 save_path total_done total_uploaded max_download_speed max_upload_speed seeds_peers_ratio".split(" "),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 seed_rank".split(" "),
-Files:["files","file_progress","file_priorities"],Peers:["peers"],Details:"name save_path total_size num_files message tracker comment".split(" "),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".split(" ")};Ext.each(Deluge.Keys.Grid,function(a){Deluge.Keys.Status.push(a)});
-Deluge.LoginWindow=Ext.extend(Ext.Window,{firstShow:!0,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closable:!1,closeAction:"hide",iconCls:"x-deluge-login-window-icon",layout:"fit",modal:!0,plain:!0,resizable:!1,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"),grow:!0,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(a){this.show(!0)},scope:this})},show:function(a){this.firstShow&&(deluge.client.on("error",this.onClientError,
-this),this.firstShow=!1);if(a)return Deluge.LoginWindow.superclass.show.call(this);deluge.client.auth.check_session({success:function(a){a?deluge.events.fire("login"):this.show(!0)},failure:function(a){this.show(!0)},scope:this})},onSpecialKey:function(a,b){if(13==b.getKey())this.onLogin()},onLogin:function(){var a=this.passwordField;deluge.client.auth.login(a.getValue(),{success:function(b){b?(deluge.events.fire("login"),this.hide(),a.setRawValue("")):Ext.MessageBox.show({title:_("Login Failed"),
-msg:_("You entered an incorrect password"),buttons:Ext.MessageBox.OK,modal:!1,fn:function(){a.focus(!0,10)},icon:Ext.MessageBox.WARNING,iconCls:"x-deluge-icon-warning"})},scope:this})},onClientError:function(a,b,c){1==a.error.code&&(deluge.events.fire("logout"),this.show(!0))},onShow:function(){this.passwordField.focus(!0,300)}});
-deluge.menus={onTorrentAction:function(a,b){var c=deluge.torrents.getSelectedIds(),d=a.initialConfig.torrentAction;switch(d){case "pause":case "resume":deluge.client.core[d+"_torrent"](c,{success:function(){deluge.ui.update()}});break;case "top":case "up":case "down":case "bottom":deluge.client.core["queue_"+d](c,{success:function(){deluge.ui.update()}});break;case "edit_trackers":deluge.editTrackers.show();break;case "update":deluge.client.core.force_reannounce(c,{success:function(){deluge.ui.update()}});
-break;case "remove":deluge.removeWindow.show(c);break;case "recheck":deluge.client.core.force_recheck(c,{success:function(){deluge.ui.update()}});break;case "move":deluge.moveStorage.show(c)}}};
-deluge.menus.torrent=new Ext.menu.Menu({id:"torrentMenu",items:[{torrentAction:"pause",text:_("Pause"),iconCls:"icon-pause",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"resume",text:_("Resume"),iconCls:"icon-resume",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{text:_("Options"),iconCls:"icon-options",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("D/L Speed Limit"),iconCls:"x-deluge-downloading",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},
-{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("U/L Speed Limit"),iconCls:"x-deluge-seeding",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("5 KiB/s")},{text:_("10 KiB/s")},{text:_("30 KiB/s")},{text:_("80 KiB/s")},{text:_("300 KiB/s")},{text:_("Unlimited")}]})},{text:_("Connection Limit"),iconCls:"x-deluge-connections",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("50")},{text:_("100")},{text:_("200")},{text:_("300")},
-{text:_("500")},{text:_("Unlimited")}]})},{text:_("Upload Slot Limit"),iconCls:"icon-upload-slots",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{text:_("0")},{text:_("1")},{text:_("2")},{text:_("3")},{text:_("5")},{text:_("Unlimited")}]})},{id:"auto_managed",text:_("Auto Managed"),checked:!1}]})},"-",{text:_("Queue"),iconCls:"icon-queue",hideOnClick:!1,menu:new Ext.menu.Menu({items:[{torrentAction:"top",text:_("Top"),iconCls:"icon-top",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"up",
-text:_("Up"),iconCls:"icon-up",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"down",text:_("Down"),iconCls:"icon-down",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"bottom",text:_("Bottom"),iconCls:"icon-bottom",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]})},"-",{torrentAction:"update",text:_("Update Tracker"),iconCls:"icon-update-tracker",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"edit_trackers",text:_("Edit Trackers"),
-iconCls:"icon-edit-trackers",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"remove",text:_("Remove Torrent"),iconCls:"icon-remove",handler:deluge.menus.onTorrentAction,scope:deluge.menus},"-",{torrentAction:"recheck",text:_("Force Recheck"),iconCls:"icon-recheck",handler:deluge.menus.onTorrentAction,scope:deluge.menus},{torrentAction:"move",text:_("Move Storage"),iconCls:"icon-move",handler:deluge.menus.onTorrentAction,scope:deluge.menus}]});
-deluge.menus.filePriorities=new Ext.menu.Menu({id:"filePrioritiesMenu",items:[{id:"expandAll",text:_("Expand All"),iconCls:"icon-expand-all"},"-",{id:"no_download",text:_("Do Not Download"),iconCls:"icon-do-not-download",filePriority:FILE_PRIORITY["Do Not Download"]},{id:"normal",text:_("Normal Priority"),iconCls:"icon-normal",filePriority:FILE_PRIORITY["Normal Priority"]},{id:"high",text:_("High Priority"),iconCls:"icon-high",filePriority:FILE_PRIORITY["High Priority"]},{id:"highest",text:_("Highest Priority"),
-iconCls:"icon-highest",filePriority:FILE_PRIORITY["Highest Priority"]}]});Ext.namespace("Deluge");
-Deluge.MoveStorage=Ext.extend(Ext.Window,{constructor:function(a){a=Ext.apply({title:_("Move Storage"),width:375,height:110,layout:"fit",buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-move-storage",plain:!0,resizable:!1},a);Deluge.MoveStorage.superclass.constructor.call(this,a)},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:!1,defaultType:"textfield",width:300,bodyStyle:"padding: 5px"});this.moveLocation=this.form.add({fieldLabel:_("Location"),name:"location",width:240})},hide:function(){Deluge.MoveStorage.superclass.hide.call(this);this.torrentIds=null},show:function(a){Deluge.MoveStorage.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide()},onMove:function(){var a=this.moveLocation.getValue();deluge.client.core.move_storage(this.torrentIds,a);this.hide()}});deluge.moveStorage=new Deluge.MoveStorage;
-Deluge.MultiOptionsManager=Ext.extend(Deluge.OptionsManager,{constructor:function(a){this.currentId=null;this.stored={};Deluge.MultiOptionsManager.superclass.constructor.call(this,a)},changeId:function(a,b){var c=this.currentId;this.currentId=a;if(!b)for(var d in this.options)this.binds[d]&&Ext.each(this.binds[d],function(a){a.setValue(this.get(d))},this);return c},commit:function(){this.stored[this.currentId]=Ext.apply(this.stored[this.currentId],this.changed[this.currentId]);this.reset()},get:function(){if(1==
-arguments.length){var a=arguments[0];return this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)}if(0==arguments.length){var b={};for(a in this.options)b[a]=this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)}else b={},Ext.each(arguments,function(a){b[a]=this.isDirty(a)?this.changed[this.currentId][a]:this.getDefault(a)},this);return b},getDefault:function(a){return this.has(a)?this.stored[this.currentId][a]:this.options[a]},getDirty:function(){return this.changed[this.currentId]?
-this.changed[this.currentId]:{}},isDirty:function(a){return this.changed[this.currentId]&&!Ext.isEmpty(this.changed[this.currentId][a])},has:function(a){return this.stored[this.currentId]&&!Ext.isEmpty(this.stored[this.currentId][a])},reset:function(){this.changed[this.currentId]&&delete this.changed[this.currentId];this.stored[this.currentId]&&delete this.stored[this.currentId]},resetAll:function(){this.changed={};this.stored={};this.changeId(null)},setDefault:function(a,b){if(void 0!==a)if(void 0===
-b)for(var c in a)this.setDefault(c,a[c]);else c=this.getDefault(a),b=this.convertValueType(c,b),c!=b&&(this.stored[this.currentId]||(this.stored[this.currentId]={}),this.stored[this.currentId][a]=b,this.isDirty(a)||this.fireEvent("changed",a,b,c))},update:function(a,b){if(void 0!==a)if(void 0===b)for(var c in a)this.update(c,a[c]);else{this.changed[this.currentId]||(this.changed[this.currentId]={});c=this.getDefault(a);b=this.convertValueType(c,b);var d=this.get(a);d!=b&&(c==b?this.isDirty(a)&&delete this.changed[this.currentId][a]:
-this.changed[this.currentId][a]=b,this.fireEvent("changed",a,b,d))}}});Ext.ns("Deluge");
-Deluge.OtherLimitWindow=Ext.extend(Ext.Window,{layout:"fit",width:210,height:100,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"}]});this.initialConfig.unit?this.form.add({border:!1,baseCls:"x-plain",bodyStyle:"padding: 5px",html:this.initialConfig.unit}):this.setSize(180,100);this.addButton(_("Cancel"),
-this.onCancelClick,this);this.addButton(_("Ok"),this.onOkClick,this);this.afterMethod("show",this.doFocusField,this)},setValue:function(a){this.form.getForm().setValues({limit:a})},onCancelClick:function(){this.form.getForm().reset();this.hide()},onOkClick:function(){var a={};a[this.group]=this.form.getForm().getValues().limit;deluge.client.core.set_config(a,{success:function(){deluge.ui.update()}});this.hide()},doFocusField:function(){this.form.getForm().findField("limit").focus(!0,10)}});Ext.ns("Deluge");
-Deluge.Plugin=Ext.extend(Ext.util.Observable,{name:null,constructor:function(a){this.isDelugePlugin=!0;this.addEvents({enabled:!0,disabled:!0});Deluge.Plugin.superclass.constructor.call(this,a)},disable:function(){this.fireEvent("disabled",this);if(this.onDisable)this.onDisable()},enable:function(){deluge.client.reloadMethods();this.fireEvent("enable",this);if(this.onEnable)this.onEnable()},registerTorrentStatus:function(a,b,c){c=c||{};var d=c.colCfg||{};c=c.storeCfg||{};c=Ext.apply(c,{name:a});deluge.torrents.meta.fields.push(c);
-deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);d=Ext.apply(d,{header:b,dataIndex:a});b=deluge.torrents.columns.slice(0);b.push(d);deluge.torrents.colModel.setConfig(b);deluge.torrents.columns=b;Deluge.Keys.Grid.push(a);deluge.torrents.getView().refresh(!0)},deregisterTorrentStatus:function(a){var b=[];Ext.each(deluge.torrents.meta.fields,function(c){c.name!=a&&b.push(c)});deluge.torrents.meta.fields=b;deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);var c=
-[];Ext.each(deluge.torrents.columns,function(b){b.dataIndex!=a&&c.push(b)});deluge.torrents.colModel.setConfig(c);deluge.torrents.columns=c;var d=[];Ext.each(Deluge.Keys.Grid,function(b){b==a&&d.push(b)});Deluge.Keys.Grid=d;deluge.torrents.getView().refresh(!0)}});Ext.ns("Deluge.plugins");
-Deluge.RemoveWindow=Ext.extend(Ext.Window,{title:_("Remove Torrent"),layout:"fit",width:350,height:100,buttonAlign:"right",closeAction:"hide",closable:!0,iconCls:"x-deluge-remove-window-icon",plain:!0,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(a){Ext.each(this.torrentIds,function(b){deluge.client.core.remove_torrent(b,a,{success:function(){this.onRemoved(b)},scope:this,torrentId:b})},this)},show:function(a){Deluge.RemoveWindow.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide();this.torrentIds=null},onRemove:function(){this.remove(!1)},onRemoveData:function(){this.remove(!0)},onRemoved:function(a){deluge.events.fire("torrentRemoved",a);this.hide();deluge.ui.update()}});
-deluge.removeWindow=new Deluge.RemoveWindow;
-Deluge.Sidebar=Ext.extend(Ext.Panel,{panels:{},selected:null,constructor:function(a){a=Ext.apply({id:"sidebar",region:"west",cls:"deluge-sidebar",title:_("Filters"),layout:"accordion",split:!0,width:200,minSize:100,collapsible:!0,margins:"5 0 0 5",cmargins:"5 0 0 5"},a);Deluge.Sidebar.superclass.constructor.call(this,a)},initComponent:function(){Deluge.Sidebar.superclass.initComponent.call(this);deluge.events.on("disconnect",this.onDisconnect,this)},createFilter:function(a,b){var c=new Deluge.FilterPanel({filter:a});
-c.on("selectionchange",function(a,b){deluge.ui.update()});this.add(c);this.doLayout();this.panels[a]=c;c.header.on("click",function(a){deluge.config.sidebar_multiple_filters||deluge.ui.update();c.list.getSelectionCount()||c.list.select(0)});this.fireEvent("filtercreate",this,c);c.updateStates(b);this.fireEvent("afterfiltercreate",this,c)},getFilter:function(a){return this.panels[a]},getFilterStates:function(){var a={};if(deluge.config.sidebar_multiple_filters)this.items.each(function(b){var c=b.getState();
-null!=c&&(a[b.filterType]=c)},this);else{var b=this.getLayout().activeItem;if(b){var c=b.getState();if(null==!c)return;a[b.filterType]=c}}return a},hasFilter:function(a){return this.panels[a]?!0:!1},onDisconnect:function(){for(var a in this.panels)this.remove(this.panels[a]);this.panels={};this.selected=null},onFilterSelect:function(a,b,c){deluge.ui.update()},update:function(a){for(var b in a){var c=a[b];-1<Ext.getKeys(this.panels).indexOf(b)?this.panels[b].updateStates(c):this.createFilter(b,c)}Ext.each(Ext.keys(this.panels),
-function(b){-1==Ext.keys(a).indexOf(b)&&(this.remove(this.panels[b]),this.doLayout(),delete this.panels[b])},this)}});Ext.namespace("Deluge");
-Deluge.Statusbar=Ext.extend(Ext.ux.StatusBar,{constructor:function(a){a=Ext.apply({id:"deluge-statusbar",defaultIconCls:"x-deluge-statusbar x-not-connected",defaultText:_("Not Connected")},a);Deluge.Statusbar.superclass.constructor.call(this,a)},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:!1},{text:"100",value:"100",group:"max_connections_global",checked:!1},{text:"200",value:"200",group:"max_connections_global",checked:!1},{text:"300",value:"300",group:"max_connections_global",checked:!1},{text:"500",value:"500",group:"max_connections_global",checked:!1},{text:_("Unlimited"),value:"-1",group:"max_connections_global",
-checked:!1},"-",{text:_("Other"),value:"other",group:"max_connections_global",checked:!1}],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:!1},{value:"10",text:"10 KiB/s",group:"max_download_speed",checked:!1},{value:"30",text:"30 KiB/s",group:"max_download_speed",checked:!1},{value:"80",
-text:"80 KiB/s",group:"max_download_speed",checked:!1},{value:"300",text:"300 KiB/s",group:"max_download_speed",checked:!1},{value:"-1",text:_("Unlimited"),group:"max_download_speed",checked:!1},"-",{value:"other",text:_("Other"),group:"max_download_speed",checked:!1}],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:!1},{value:"10",text:"10 KiB/s",group:"max_upload_speed",checked:!1},{value:"30",text:"30 KiB/s",group:"max_upload_speed",checked:!1},{value:"80",text:"80 KiB/s",group:"max_upload_speed",checked:!1},{value:"300",text:"300 KiB/s",group:"max_upload_speed",checked:!1},{value:"-1",text:_("Unlimited"),group:"max_upload_speed",checked:!1},"-",{value:"other",text:_("Other"),group:"max_upload_speed",checked:!1}],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-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 location"),handler:function(){deluge.preferences.show();
-deluge.preferences.selectPage("Downloads")}});this.created=!0},onConnect:function(){this.setStatus({iconCls:"x-connected",text:""});this.created?Ext.each(this.buttons,function(a){a.show();a.enable()}):this.createButtons();this.doLayout()},onDisconnect:function(){this.clearStatus({useDefaults:!0});Ext.each(this.buttons,function(a){a.hide();a.disable()});this.doLayout()},update:function(a){function b(a){return a+" KiB/s"}if(a){var c=function(a,b){var c=this.items.get("statusbar-"+a);if(0<b.limit.value)var e=
-b.value.formatter?b.value.formatter(b.value.value,!0):b.value.value,h=b.limit.formatter?b.limit.formatter(b.limit.value,!0):b.limit.value,e=String.format(b.format,e,h);else e=b.value.formatter?b.value.formatter(b.value.value,!0):b.value.value;c.setText(e);c.menu&&c.menu.setValue(b.limit.value)}.createDelegate(this);c("connections",{value:{value:a.num_connections},limit:{value:a.max_num_connections},format:"{0} ({1})"});c("downspeed",{value:{value:a.download_rate,formatter:Deluge.Formatters.speed},
-limit:{value:a.max_download,formatter:b},format:"{0} ({1})"});c("upspeed",{value:{value:a.upload_rate,formatter:Deluge.Formatters.speed},limit:{value:a.max_upload,formatter:b},format:"{0} ({1})"});c("traffic",{value:{value:a.download_protocol_rate,formatter:Deluge.Formatters.speed},limit:{value:a.upload_protocol_rate,formatter:Deluge.Formatters.speed},format:"{0}/{1}"});this.items.get("statusbar-dht").setText(a.dht_nodes);this.items.get("statusbar-freespace").setText(fsize(a.free_space))}}});
-Deluge.Toolbar=Ext.extend(Ext.Toolbar,{constructor:function(a){a=Ext.apply({items:[{id:"tbar-deluge-text",disabled:!0,text:_("Deluge"),iconCls:"x-deluge-main-panel"},new Ext.Toolbar.Separator,{id:"create",disabled:!0,hidden:!0,text:_("Create"),iconCls:"icon-create",handler:this.onTorrentAction},{id:"add",disabled:!0,text:_("Add"),iconCls:"icon-add",handler:this.onTorrentAdd},{id:"remove",disabled:!0,text:_("Remove"),iconCls:"icon-remove",handler:this.onTorrentAction},new Ext.Toolbar.Separator,{id:"pause",
-disabled:!0,text:_("Pause"),iconCls:"icon-pause",handler:this.onTorrentAction},{id:"resume",disabled:!0,text:_("Resume"),iconCls:"icon-resume",handler:this.onTorrentAction},new Ext.Toolbar.Separator,{id:"up",cls:"x-btn-text-icon",disabled:!0,text:_("Up"),iconCls:"icon-up",handler:this.onTorrentAction},{id:"down",disabled:!0,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:!0,text:_("Logout"),handler:this.onLogout,scope:this}]},a);Deluge.Toolbar.superclass.constructor.call(this,a)},connectedButtons:"add remove pause resume up down".split(" "),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(a){this.items.get(a).enable()},this)},onDisconnect:function(){Ext.each(this.connectedButtons,function(a){this.items.get(a).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")},
-onPreferencesClick:function(){deluge.preferences.show()},onTorrentAction:function(a){var b=deluge.torrents.getSelections(),c=[];Ext.each(b,function(a){c.push(a.id)});switch(a.id){case "remove":deluge.removeWindow.show(c);break;case "pause":case "resume":deluge.client.core[a.id+"_torrent"](c,{success:function(){deluge.ui.update()}});break;case "up":case "down":deluge.client.core["queue_"+a.id](c,{success:function(){deluge.ui.update()}})}},onTorrentAdd:function(){deluge.add.show()}});
-(function(){function a(a){if(a)return fspeed(a)}function b(a){return-1==a?"":fspeed(1024*a)}function c(a,b,c){return 0>a?"&infin;":parseFloat((new Number(a)).toFixed(3))}Deluge.TorrentGrid=Ext.extend(Ext.grid.GridPanel,{torrents:{},columns:[{id:"queue",header:_("#"),width:30,sortable:!0,renderer:function(a){return-1==a?"":a+1},dataIndex:"queue"},{id:"name",header:_("Name"),width:150,sortable:!0,renderer:function(a,b,c){return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>',c.data.state.toLowerCase(),
-a)},dataIndex:"name"},{header:_("Size"),width:75,sortable:!0,renderer:fsize,dataIndex:"total_wanted"},{header:_("Progress"),width:150,sortable:!0,renderer:function(a,b,c){a=new Number(a);c=c.data.state+" "+a.toFixed(2)+"%";b=new Number((this.style?this.style:b.style).match(/\w+:\s*(\d+)\w+/)[1]);return Deluge.progressBar(a,b-8,c)},dataIndex:"progress"},{header:_("Down Speed"),width:80,sortable:!0,renderer:a,dataIndex:"download_payload_rate"},{header:_("Up Speed"),width:80,sortable:!0,renderer:a,dataIndex:"upload_payload_rate"},
-{header:_("ETA"),width:60,sortable:!0,renderer:ftime,dataIndex:"eta"},{header:_("Seeders"),hidden:!0,width:60,sortable:!0,renderer:function(a,b,c){return-1<c.data.total_seeds?String.format("{0} ({1})",a,c.data.total_seeds):a},dataIndex:"num_seeds"},{header:_("Peers"),hidden:!0,width:60,sortable:!0,renderer:function(a,b,c){return-1<c.data.total_peers?String.format("{0} ({1})",a,c.data.total_peers):a},dataIndex:"num_peers"},{header:_("Ratio"),hidden:!0,width:60,sortable:!0,renderer:c,dataIndex:"ratio"},
-{header:_("Avail"),hidden:!0,width:60,sortable:!0,renderer:c,dataIndex:"distributed_copies"},{header:_("Added"),hidden:!0,width:80,sortable:!0,renderer:fdate,dataIndex:"time_added"},{header:_("Tracker"),hidden:!0,width:120,sortable:!0,renderer:function(a,b,c){return String.format('<div style="background: url('+deluge.config.base+'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',a)},dataIndex:"tracker_host"},{header:_("Save Path"),hidden:!0,width:120,sortable:!0,renderer:fplain,dataIndex:"save_path"},
-{header:_("Downloaded"),hidden:!0,width:75,sortable:!0,renderer:fsize,dataIndex:"total_done"},{header:_("Uploaded"),hidden:!0,width:75,sortable:!0,renderer:fsize,dataIndex:"total_uploaded"},{header:_("Down Limit"),hidden:!0,width:75,sortable:!0,renderer:b,dataIndex:"max_download_speed"},{header:_("Up Limit"),hidden:!0,width:75,sortable:!0,renderer:b,dataIndex:"max_upload_speed"},{header:_("Seeders")+"/"+_("Peers"),hidden:!0,width:75,sortable:!0,renderer:c,dataIndex:"seeds_peers_ratio"}],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:function(a){return-1*a}},{name:"ratio",type:"float"},
-{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host"},{name:"save_path"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]},keys:[{key:"a",ctrl:!0,stopEvent:!0,handler:function(){deluge.torrents.getSelectionModel().selectAll()}},{key:[46],stopEvent:!0,handler:function(){ids=deluge.torrents.getSelectedIds();deluge.removeWindow.show(ids)}}],
-constructor:function(a){a=Ext.apply({id:"torrentGrid",store:new Ext.data.JsonStore(this.meta),columns:this.columns,keys:this.keys,region:"center",cls:"deluge-torrents",stripeRows:!0,autoExpandColumn:"name",autoExpandMin:150,deferredRender:!1,autoScroll:!0,margins:"5 5 0 0",stateful:!0,view:new Ext.ux.grid.BufferView({rowHeight:26,scrollDelay:!1})},a);Deluge.TorrentGrid.superclass.constructor.call(this,a)},initComponent:function(){Deluge.TorrentGrid.superclass.initComponent.call(this);deluge.events.on("torrentRemoved",
-this.onTorrentRemoved,this);deluge.events.on("disconnect",this.onDisconnect,this);this.on("rowcontextmenu",function(a,b,c){c.stopEvent();a=a.getSelectionModel();a.isSelected(b)||a.selectRow(b);deluge.menus.torrent.showAt(c.getPoint())})},getTorrent:function(a){return this.getStore().getAt(a)},getSelected:function(){return this.getSelectionModel().getSelected()},getSelections:function(){return this.getSelectionModel().getSelections()},getSelectedId:function(){return this.getSelectionModel().getSelected().id},
-getSelectedIds:function(){var a=[];Ext.each(this.getSelectionModel().getSelections(),function(b){a.push(b.id)});return a},update:function(a,b){var c=this.getStore();b&&(c.removeAll(),this.torrents={});var e=[],h;for(h in a){var k=a[h];if(this.torrents[h]){var l=c.getById(h);l.beginEdit();for(var m in k)l.get(m)!=k[m]&&l.set(m,k[m]);l.endEdit()}else l=new Deluge.data.Torrent(k),l.id=h,this.torrents[h]=1,e.push(l)}c.add(e);c.each(function(b){a[b.id]||(c.remove(b),delete this.torrents[b.id])},this);
-c.commitChanges();(e=c.getSortState())&&c.sort(e.field,e.direction)},onDisconnect:function(){this.getStore().removeAll();this.torrents={}},onTorrentRemoved:function(a){var b=this.getSelectionModel();Ext.each(a,function(a){var c=this.getStore().getById(a);b.isSelected(c)&&b.deselectRow(this.getStore().indexOf(c));this.getStore().remove(c);delete this.torrents[a]},this)}});deluge.torrents=new Deluge.TorrentGrid})();
-deluge.ui={errorCount:0,filters:null,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:!0,height:215,minSize:100,collapsible:!0,margins:"0 5 5 5",cmargins:"0 5 5 5",layout:"fit",items:[deluge.details]});this.MainPanel=new Ext.Panel({id:"mainPanel",iconCls:"x-deluge-main-panel",layout:"border",border:!1,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"});for(var a in Deluge.pluginStore)a=Deluge.createPlugin(a),a.enable(),deluge.plugins[a.name]=a;Ext.QuickTips.init();deluge.client.on("connected",function(a){deluge.login.show()},this,{single:!0});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 a=deluge.sidebar.getFilterStates();this.oldFilters=this.filters;this.filters=a;deluge.client.web.update_ui(Deluge.Keys.Grid,a,{success:this.onUpdate,failure:this.onUpdateError,scope:this});deluge.details.update()},onConnectionError:function(a){},onConnectionSuccess:function(a){deluge.statusbar.setStatus({iconCls:"x-deluge-statusbar icon-ok",
-text:_("Connection restored")});clearInterval(this.checking);a||deluge.connectionManager.show()},onUpdateError:function(a){2==this.errorCount&&(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,2E3));this.errorCount++},onUpdate:function(a){a.connected?(deluge.config.show_session_speed&&
-(document.title="D: "+fsize_short(a.stats.download_rate,!0)+" U: "+fsize_short(a.stats.upload_rate,!0)+" - "+this.originalTitle),Ext.areObjectsEqual(this.filters,this.oldFilters)?deluge.torrents.update(a.torrents):deluge.torrents.update(a.torrents,!0),deluge.statusbar.update(a.stats),deluge.sidebar.update(a.filters),this.errorCount=0):deluge.connectionManager.disconnect(!0)},onConnect:function(){this.running||(this.running=setInterval(this.update,2E3),this.update());deluge.client.web.get_plugins({success:this.onGotPlugins,
-scope:this})},onDisconnect:function(){this.stop()},onGotPlugins:function(a){Ext.each(a.enabled_plugins,function(a){deluge.plugins[a]||deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})},this)},onPluginEnabled:function(a){deluge.plugins[a]?deluge.plugins[a].enable():deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})},onGotPluginResources:function(a){Ext.each(Deluge.debug?a.debug_scripts:a.scripts,function(b){Ext.ux.JSLoader({url:deluge.config.base+
-b,onLoad:this.onPluginLoaded,pluginName:a.name})},this)},onPluginDisabled:function(a){deluge.plugins[a]&&deluge.plugins[a].disable()},onPluginLoaded:function(a){Deluge.hasPlugin(a.pluginName)&&(plugin=Deluge.createPlugin(a.pluginName),plugin.enable(),deluge.plugins[plugin.name]=plugin)},stop:function(){this.running&&(clearInterval(this.running),this.running=!1,deluge.torrents.getStore().removeAll())}};Ext.onReady(function(a){deluge.ui.initialize()});
+/*
+ * Deluge.data.SortTypes.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.data");Deluge.data.SortTypes={asIPAddress:function(a){var b=a.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\:(\d+)/);return((((((+b[1])*256)+(+b[2]))*256)+(+b[3]))*256)+(+b[4])},asQueuePosition:function(a){return(a>-1)?a:Number.MAX_VALUE},asName:function(a){return String(a).toLowerCase()}}
+/*
+ * Deluge.data.PeerRecord.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+;Ext.namespace("Deluge.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.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:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]);
+/*
+ * Deluge.details.DetailsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.details");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(a){if(a.clear){a.clear.defer(100,a);a.disable()}})},update:function(a){var b=deluge.torrents.getSelected();if(!b){this.clear();return}this.items.each(function(c){if(c.disabled){c.enable()}});a=a||this.getActiveTab();if(a.update){a.update(b.id)}},onRender:function(b,a){Deluge.details.DetailsPanel.superclass.onRender.call(this,b,a);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(c){if(!c.hasSelection()){this.clear()}},this)},onTabChange:function(a,b){this.update(b)},onTorrentsClick:function(a,c,b){this.update()}});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",_("Path"));this.addItem("size",_("Total Size"));this.addItem("files",_("# of files"));this.addItem("comment",_("Comment"));this.addItem("status",_("Status"));this.addItem("tracker",_("Tracker"))},onRender:function(b,a){Deluge.details.DetailsTab.superclass.onRender.call(this,b,a);this.body.setStyle("padding","10px");this.dl=Ext.DomHelper.append(this.body,{tag:"dl"},true);for(var c in this.queuedItems){this.doAddItem(c,this.queuedItems[c])}},addItem:function(b,a){if(!this.rendered){this.queuedItems[b]=a}else{this.doAddItem(b,a)}},doAddItem:function(b,a){Ext.DomHelper.append(this.dl,{tag:"dt",cls:b,html:a+":"});this.fields[b]=Ext.DomHelper.append(this.dl,{tag:"dd",cls:b,html:""},true)},clear:function(){if(!this.fields){return}for(var a in this.fields){this.fields[a].dom.innerHTML=""}this.oldData={}},update:function(a){deluge.client.web.get_torrent_status(a,Deluge.Keys.Details,{success:this.onRequestComplete,scope:this,torrentId:a})},onRequestComplete:function(e,c,a,b){var d={torrent_name:e.name,hash:b.options.torrentId,path:e.save_path,size:fsize(e.total_size),files:e.num_files,status:e.message,tracker:e.tracker,comment:e.comment};for(var f in this.fields){if(!Ext.isDefined(d[f])){continue}if(d[f]==this.oldData[f]){continue}this.fields[f].dom.innerHTML=Ext.escapeHTML(d[f])}this.oldData=d}});
+/*
+ * Deluge.details.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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(a){return fsize(a)}})},{xtype:"tgrendercolumn",header:_("Progress"),width:150,dataIndex:"progress",renderer:function(a){var b=a*100;return Deluge.progressBar(b,this.col.width,b.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(a){return FILE_PRIORITY_CSS[a]},getName:function(a){return _(FILE_PRIORITY[a])}})}],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 a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(c){var b=c.parentNode;if(!b){return}if(!b.ownerTree){return}b.removeChild(c)})},createFileTree:function(c){function b(g,d){for(var e in g.contents){var f=g.contents[e];if(f.type=="dir"){b(f,d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,size:f.size,progress:f.progress,priority:f.priority})))}else{d.appendChild(new Ext.tree.TreeNode({text:e,filename:e,fileIndex:f.index,size:f.size,progress:f.progress,priority:f.priority,leaf:true,iconCls:"x-deluge-file",uiProvider:Ext.ux.tree.TreeGridNodeUI}))}}}var a=this.getRootNode();b(c,a);a.firstChild.expand()},update:function(a){if(this.torrentId!=a){this.clear();this.torrentId=a}deluge.client.web.get_torrent_files(a,{success:this.onRequestComplete,scope:this,torrentId:a})},updateFileTree:function(b){function a(g,c){for(var d in g.contents){var f=g.contents[d];var e=c.findChild("filename",d);e.attributes.size=f.size;e.attributes.progress=f.progress;e.attributes.priority=f.priority;e.ui.updateColumns();if(f.type=="dir"){a(f,e)}}}a(b,this.getRootNode())},onRender:function(b,a){Deluge.details.FilesTab.superclass.onRender.call(this,b,a);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(b,c){c.stopEvent();var a=this.getSelectionModel();if(a.getSelectedNodes().length<2){a.clearSelections();b.select()}deluge.menus.filePriorities.showAt(c.getPoint())},onItemClick:function(h,g){switch(h.id){case"expandAll":this.expandAll();break;default:var f={};function a(e){if(Ext.isEmpty(e.attributes.fileIndex)){return}f[e.attributes.fileIndex]=e.attributes.priority}this.getRootNode().cascade(a);var b=this.getSelectionModel().getSelectedNodes();Ext.each(b,function(i){if(!i.isLeaf()){function e(j){if(Ext.isEmpty(j.attributes.fileIndex)){return}f[j.attributes.fileIndex]=h.filePriority}i.cascade(e)}else{if(!Ext.isEmpty(i.attributes.fileIndex)){f[i.attributes.fileIndex]=h.filePriority;return}}});var d=new Array(Ext.keys(f).length);for(var c in f){d[c]=f[c]}deluge.client.core.set_torrent_file_priorities(this.torrentId,d,{success:function(){Ext.each(b,function(e){e.setColumnValue(3,h.filePriority)})},scope:this});break}},onRequestComplete:function(b,a){if(!this.getRootNode().hasChildNodes()){this.createFileTree(b)}else{this.updateFileTree(b)}}});
+/*
+ * Deluge.details.OptionsTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.details.OptionsTab=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=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")},a);Deluge.details.OptionsTab.superclass.constructor.call(this,a)},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,remove_at_ratio:false,move_completed:false,move_completed_path:"","private":false,prioritize_first_last:false}});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});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"});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"});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});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});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,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});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"});for(var a in this.fields){this.optionsManager.bind(a,this.fields[a])}this.buttonPanel=this.rightColumn.add({layout:"hbox",xtype:"panel",border:false});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});this.buttonPanel.add({id:"apply",xtype:"button",text:_("Apply"),style:"margin-left: 10px;",border:false,width:100,handler:this.onApply,scope:this})},onRender:function(b,a){Deluge.details.OptionsTab.superclass.onRender.call(this,b,a);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(a){if(this.torrentId&&!a){this.clear()}if(!a){return}if(this.torrentId!=a){this.torrentId=a;this.optionsManager.changeId(a)}deluge.client.web.get_torrent_status(a,Deluge.Keys.Options,{success:this.onRequestComplete,scope:this})},onApply:function(){var b=this.optionsManager.getDirty();if(!Ext.isEmpty(b.prioritize_first_last)){var a=b.prioritize_first_last;deluge.client.core.set_torrent_prioritize_first_last(this.torrentId,a,{success:function(){this.optionsManager.set("prioritize_first_last",a)},scope:this})}deluge.client.core.set_torrent_options([this.torrentId],b,{success:function(){this.optionsManager.commit()},scope:this})},onEditTrackers:function(){deluge.editTrackers.show()},onMoveCompletedChecked:function(b,a){this.fields.move_completed_path.setDisabled(!a);if(!a){return}this.fields.move_completed_path.focus()},onStopRatioChecked:function(b,a){this.fields.remove_at_ratio.setDisabled(!a);this.fields.stop_ratio.setDisabled(!a)},onRequestComplete:function(c,b){this.fields["private"].setValue(c["private"]);this.fields["private"].setDisabled(true);delete c["private"];c.auto_managed=c.is_auto_managed;this.optionsManager.setDefault(c);var a=this.optionsManager.get("stop_at_ratio");this.fields.remove_at_ratio.setDisabled(!a);this.fields.stop_ratio.setDisabled(!a);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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+(function(){function a(d){if(!d.replace(" ","").replace(" ","")){return""}return String.format('<img src="{0}flag/{1}" />',deluge.config.base,d)}function b(h,i,f){var e=(f.data.seed==1024)?"x-deluge-seed":"x-deluge-peer";var d=h.split(":");if(d.length>2){var g=d.pop();var j=d.join(":");h="["+j+"]:"+g}return String.format('<div class="{0}">{1}</div>',e,h)}function c(e){var d=(e*100).toFixed(0);return Deluge.progressBar(d,this.width-8,d+"%")}Deluge.details.PeersTab=Ext.extend(Ext.grid.GridPanel,{peers:{},constructor:function(d){d=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:a,dataIndex:"country"},{header:"Address",width:125,sortable:true,renderer:b,dataIndex:"ip"},{header:"Client",width:125,sortable:true,renderer:fplain,dataIndex:"client"},{header:"Progress",width:150,sortable:true,renderer:c,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},d);Deluge.details.PeersTab.superclass.constructor.call(this,d)},clear:function(){this.getStore().removeAll();this.peers={}},update:function(d){deluge.client.web.get_torrent_status(d,Deluge.Keys.Peers,{success:this.onRequestComplete,scope:this})},onRequestComplete:function(h,g){if(!h){return}var f=this.getStore();var e=[];var i={};Ext.each(h.peers,function(m){if(this.peers[m.ip]){var j=f.getById(m.ip);j.beginEdit();for(var l in m){if(j.get(l)!=m[l]){j.set(l,m[l])}}j.endEdit()}else{this.peers[m.ip]=1;e.push(new Deluge.data.Peer(m,m.ip))}i[m.ip]=1},this);f.add(e);f.each(function(j){if(!i[j.id]){f.remove(j);delete this.peers[j.id]}},this);f.commitChanges();var d=f.getSortState();if(!d){return}f.sort(d.field,d.direction)}})})();
+/*
+ * Deluge.details.StatusTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.details");Deluge.details.StatusTab=Ext.extend(Ext.Panel,{title:_("Status"),autoScroll:true,onRender:function(b,a){Deluge.details.StatusTab.superclass.onRender.call(this,b,a);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(c){c.load({url:deluge.config.base+"render/tab_status.html",text:_("Loading")+"..."});c.getUpdater().on("update",this.onPanelUpdate,this)},scope:this}}})},clear:function(){this.progressBar.updateProgress(0," ");for(var a in this.fields){this.fields[a].innerHTML=""}},update:function(a){if(!this.fields){this.getFields()}deluge.client.web.get_torrent_status(a,Deluge.Keys.Status,{success:this.onRequestComplete,scope:this})},onPanelUpdate:function(b,a){this.fields={};Ext.each(Ext.query("dd",this.status.body.dom),function(c){this.fields[c.className]=c},this)},onRequestComplete:function(a){seeders=a.total_seeds>-1?a.num_seeds+" ("+a.total_seeds+")":a.num_seeds;peers=a.total_peers>-1?a.num_peers+" ("+a.total_peers+")":a.num_peers;var b={downloaded:fsize(a.total_done,true),uploaded:fsize(a.total_uploaded,true),share:(a.ratio==-1)?"&infin;":a.ratio.toFixed(3),announce:ftime(a.next_announce),tracker_status:a.tracker_status,downspeed:(a.download_payload_rate)?fspeed(a.download_payload_rate):"0.0 KiB/s",upspeed:(a.upload_payload_rate)?fspeed(a.upload_payload_rate):"0.0 KiB/s",eta:ftime(a.eta),pieces:a.num_pieces+" ("+fsize(a.piece_length)+")",seeders:seeders,peers:peers,avail:a.distributed_copies.toFixed(3),active_time:ftime(a.active_time),seeding_time:ftime(a.seeding_time),seed_rank:a.seed_rank,time_added:fdate(a.time_added)};b.auto_managed=_((a.is_auto_managed)?"True":"False");b.downloaded+=" ("+((a.total_payload_download)?fsize(a.total_payload_download):"0.0 KiB")+")";b.uploaded+=" ("+((a.total_payload_upload)?fsize(a.total_payload_upload):"0.0 KiB")+")";for(var c in this.fields){this.fields[c].innerHTML=b[c]}var d=a.state+" "+a.progress.toFixed(2)+"%";this.progressBar.updateProgress(a.progress/100,d)}});
+/*
+ * Deluge.add.Window.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.add");Deluge.add.Window=Ext.extend(Ext.Window,{initComponent:function(){Deluge.add.Window.superclass.initComponent.call(this);this.addEvents("beforeadd","add","addfailed")},createTorrentId:function(){return new Date().getTime()}});
+/*
+ * Deluge.add.AddWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.add");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 a(c,d,b){if(b.data.info_hash){return String.format('<div class="x-deluge-add-torrent-name">{0}</div>',c)}else{return String.format('<div class="x-deluge-add-torrent-name-loading">{0}</div>',c)}}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:a,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],margins:"5 5 5 5",bbar:new Ext.Toolbar({items:[{iconCls:"x-deluge-add-file",text:_("File"),handler:this.onFile,scope:this},{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.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()},onAddClick:function(){var a=[];if(!this.list){return}this.list.getStore().each(function(b){var c=b.get("info_hash");a.push({path:this.optionsPanel.getFilename(c),options:this.optionsPanel.getOptions(c)})},this);deluge.client.web.add_torrents(a,{success:function(b){}});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 a=this.list.getSelectedRecords()[0];this.list.getStore().remove(a);this.optionsPanel.clear();if(this.torrents&&this.torrents[a.id]){delete this.torrents[a.id]}},onSelect:function(c,b){if(b.length){var a=this.list.getRecord(b[0]);this.optionsPanel.setTorrent(a.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.url.on("addfailed",this.onTorrentAddFailed,this)}if(!this.file){this.file=new Deluge.add.FileWindow();this.file.on("beforeadd",this.onTorrentBeforeAdd,this);this.file.on("add",this.onTorrentAdd,this);this.file.on("addfailed",this.onTorrentAddFailed,this)}this.optionsPanel.form.getDefaults()},onTorrentBeforeAdd:function(b,c){var a=this.list.getStore();a.loadData([[b,null,c]],true)},onTorrentAdd:function(a,c){var b=this.list.getStore().getById(a);if(!c){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(b)}else{b.set("info_hash",c.info_hash);b.set("text",c.name);this.list.getStore().commitChanges();this.optionsPanel.addTorrent(c);this.list.select(b)}},onTorrentAddFailed:function(c){var b=this.list.getStore();var a=b.getById(c);if(a){b.remove(a)}},onUrl:function(a,b){this.url.show()}});
+/*
+ * Deluge.add.File.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.add");Deluge.add.FileWindow=Ext.extend(Deluge.add.Window,{title:_("Add from File"),layout:"fit",width:350,height:115,modal:true,plain:true,buttonAlign:"center",closeAction:"hide",bodyStyle:"padding: 10px 5px;",iconCls:"x-deluge-add-file",initComponent:function(){Deluge.add.FileWindow.superclass.initComponent.call(this);this.addButton(_("Add"),this.onAddClick,this);this.form=this.add({xtype:"form",baseCls:"x-plain",labelWidth:35,autoHeight:true,fileUpload:true,items:[{xtype:"fileuploadfield",id:"torrentFile",width:280,height:24,emptyText:_("Select a torrent"),fieldLabel:_("File"),name:"file",buttonCfg:{text:_("Browse")+"..."}}]})},onAddClick:function(c,b){if(this.form.getForm().isValid()){this.torrentId=this.createTorrentId();this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your torrent..."),failure:this.onUploadFailure,success:this.onUploadSuccess,scope:this});var a=this.form.getForm().findField("torrentFile").value;a=a.split("\\").slice(-1)[0];this.fireEvent("beforeadd",this.torrentId,a)}},onGotInfo:function(d,c,a,b){d.filename=b.options.filename;this.fireEvent("add",this.torrentId,d)},onUploadFailure:function(a,b){this.hide();Ext.MessageBox.show({title:_("Error"),msg:_("Failed to upload torrent"),buttons:Ext.MessageBox.OK,modal:false,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",this.torrentId)},onUploadSuccess:function(c,b){this.hide();if(b.result.success){var a=b.result.files[0];this.form.getForm().findField("torrentFile").setValue("");deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a})}}});
+/*
+ * Deluge.add.FilesTab.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.add");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(a){return fsize(a)}})},{header:_("Download"),width:65,dataIndex:"download",tpl:new Ext.XTemplate("{download:this.format}",{format:function(a){return'<div rel="chkbox" class="x-grid3-check-col'+(a?"-on":"")+'"> </div>'}})}],initComponent:function(){Deluge.add.FilesTab.superclass.initComponent.call(this);this.on("click",this.onNodeClick,this)},clearFiles:function(){var a=this.getRootNode();if(!a.hasChildNodes()){return}a.cascade(function(b){if(!b.parentNode||!b.getOwnerTree()){return}b.remove()})},setDownload:function(b,c,d){b.attributes.download=c;b.ui.updateColumns();if(b.isLeaf()){if(!d){return this.fireEvent("fileschecked",[b],c,!c)}}else{var a=[b];b.cascade(function(e){e.attributes.download=c;e.ui.updateColumns();a.push(e)},this);if(!d){return this.fireEvent("fileschecked",a,c,!c)}}},onNodeClick:function(b,c){var a=new Ext.Element(c.target);if(a.getAttribute("rel")=="chkbox"){this.setDownload(b,!b.attributes.download)}}});
+/*
+ * Deluge.add.Infohash.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Ext.deluge.add");
+/*
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.add");Deluge.add.OptionsPanel=Ext.extend(Ext.TabPanel,{torrents:{},region:"south",margins:"5 5 5 5",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(c){this.torrents[c.info_hash]=c;var b={};this.walkFileTree(c.files_tree,function(e,g,h,f){if(g!="file"){return}b[h.index]=h.download},this);var a=[];Ext.each(Ext.keys(b),function(e){a[e]=b[e]});var d=this.form.optionsManager.changeId(c.info_hash,true);this.form.optionsManager.setDefault("file_priorities",a);this.form.optionsManager.changeId(d,true)},clear:function(){this.files.clearFiles();this.form.optionsManager.resetAll()},getFilename:function(a){return this.torrents[a]["filename"]},getOptions:function(a){var c=this.form.optionsManager.changeId(a,true);var b=this.form.optionsManager.get();this.form.optionsManager.changeId(c,true);Ext.each(b.file_priorities,function(e,d){b.file_priorities[d]=(e)?1:0});return b},setTorrent:function(b){if(!b){return}this.torrentId=b;this.form.optionsManager.changeId(b);this.files.clearFiles();var a=this.files.getRootNode();var c=this.form.optionsManager.get("file_priorities");this.form.setDisabled(false);if(this.torrents[b]["files_tree"]){this.walkFileTree(this.torrents[b]["files_tree"],function(e,f,h,d){var g=new Ext.tree.TreeNode({download:(h.index)?c[h.index]:true,filename:e,fileindex:h.index,leaf:f!="dir",size:h.length});d.appendChild(g);if(f=="dir"){return g}},this,a);a.firstChild.expand();this.files.setDisabled(false);this.files.show()}else{this.form.show();this.files.setDisabled(true)}},walkFileTree:function(g,h,e,a){for(var b in g.contents){var f=g.contents[b];var d=f.type;if(e){var c=h.apply(e,[b,d,f,a])}else{var c=h(b,d,f,a)}if(d=="dir"){this.walkFileTree(f,h,e,c)}}},onFilesChecked:function(a,c,b){if(this.form.optionsManager.get("compact_allocation")){Ext.Msg.show({title:_("Unable to set file priority!"),msg:_("File prioritization is unavailable when using Compact allocation. Would you like to switch to Full allocation?"),buttons:Ext.Msg.YESNO,fn:function(d){if(d=="yes"){this.form.optionsManager.update("compact_allocation",false);Ext.each(a,function(f){if(f.attributes.fileindex<0){return}var e=this.form.optionsManager.get("file_priorities");e[f.attributes.fileindex]=c;this.form.optionsManager.update("file_priorities",e)},this)}else{this.files.setDownload(a[0],b,true)}},scope:this,icon:Ext.MessageBox.QUESTION})}else{Ext.each(a,function(e){if(e.attributes.fileindex<0){return}var d=this.form.optionsManager.get("file_priorities");d[e.attributes.fileindex]=c;this.form.optionsManager.update("file_priorities",d)},this)}}});
+/*
+ * Deluge.add.OptionsPanel.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.add");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 a=this.add({xtype:"fieldset",title:_("Download Location"),border:false,autoHeight:true,defaultType:"textfield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});this.optionsManager.bind("download_location",a.add({fieldLabel:"",name:"download_location",width:400,labelSeparator:""}));var a=this.add({xtype:"fieldset",title:_("Move Completed Location"),border:false,autoHeight:true,defaultType:"togglefield",labelWidth:1,fieldLabel:"",style:"padding-bottom: 5px; margin-bottom: 0px;"});var c=a.add({fieldLabel:"",name:"move_completed_path",width:425});this.optionsManager.bind("move_completed",c.toggle);this.optionsManager.bind("move_completed_path",c.input);var b=this.add({border:false,layout:"column",defaultType:"fieldset"});a=b.add({title:_("Allocation"),border:false,autoHeight:true,defaultType:"radio"});this.optionsManager.bind("compact_allocation",a.add({xtype:"radiogroup",columns:1,vertical:true,labelSeparator:"",width:80,items:[{name:"compact_allocation",value:false,inputValue:false,boxLabel:_("Full"),fieldLabel:"",labelSeparator:""},{name:"compact_allocation",value:true,inputValue:true,boxLabel:_("Compact"),fieldLabel:"",labelSeparator:""}]}));a=b.add({title:_("Bandwidth"),border:false,autoHeight:true,bodyStyle:"margin-left: 7px",labelWidth:105,width:200,defaultType:"spinnerfield"});this.optionsManager.bind("max_download_speed",a.add({fieldLabel:_("Max Down Speed"),name:"max_download_speed",width:60}));this.optionsManager.bind("max_upload_speed",a.add({fieldLabel:_("Max Up Speed"),name:"max_upload_speed",width:60}));this.optionsManager.bind("max_connections",a.add({fieldLabel:_("Max Connections"),name:"max_connections",width:60}));this.optionsManager.bind("max_upload_slots",a.add({fieldLabel:_("Max Upload Slots"),name:"max_upload_slots",width:60}));a=b.add({title:_("General"),border:false,autoHeight:true,defaultType:"checkbox"});this.optionsManager.bind("add_paused",a.add({name:"add_paused",boxLabel:_("Add In Paused State"),fieldLabel:"",labelSeparator:""}));this.optionsManager.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",boxLabel:_("Prioritize First/Last Pieces"),fieldLabel:"",labelSeparator:""}))},getDefaults:function(){var a=["add_paused","compact_allocation","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"];deluge.client.core.get_config_values(a,{success:function(c){var b={file_priorities:[],add_paused:c.add_paused,compact_allocation:c.compact_allocation,download_location:c.download_location,move_completed:c.move_completed,move_completed_path:c.move_completed_path,max_connections:c.max_connections_per_torrent,max_download_speed:c.max_download_speed_per_torrent,max_upload_slots:c.max_upload_slots_per_torrent,max_upload_speed:c.max_upload_speed_per_torrent,prioritize_first_last_pieces:c.prioritize_first_last_pieces};this.optionsManager.options=b;this.optionsManager.resetAll()},scope:this})}});
+/*
+ * Deluge.add.UrlWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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 a=this.add({xtype:"form",defaultType:"textfield",baseCls:"x-plain",labelWidth:55});this.urlField=a.add({fieldLabel:_("Url"),id:"url",name:"url",width:"97%"});this.urlField.on("specialkey",this.onAdd,this);this.cookieField=a.add({fieldLabel:_("Cookies"),id:"cookies",name:"cookies",width:"97%"});this.cookieField.on("specialkey",this.onAdd,this)},onAddClick:function(f,d){if((f.id=="url"||f.id=="cookies")&&d.getKey()!=d.ENTER){return}var f=this.urlField;var b=f.getValue();var c=this.cookieField.getValue();var a=this.createTorrentId();if(b.indexOf("magnet:?")==0&&b.indexOf("xt=urn:btih")>-1){deluge.client.web.get_magnet_info(b,{success:this.onGotInfo,scope:this,filename:b,torrentId:a})}else{deluge.client.web.download_torrent_from_url(b,c,{success:this.onDownload,failure:this.onDownloadFailed,scope:this,torrentId:a})}this.hide();this.urlField.setValue("");this.fireEvent("beforeadd",a,b)},onDownload:function(a,c,d,b){deluge.client.web.get_torrent_info(a,{success:this.onGotInfo,scope:this,filename:a,torrentId:b.options.torrentId})},onDownloadFailed:function(b,c,a){Ext.MessageBox.show({title:_("Error"),msg:_("Failed to download torrent"),buttons:Ext.MessageBox.OK,modal:false,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"});this.fireEvent("addfailed",a.options.torrentId)},onGotInfo:function(d,c,a,b){d.filename=b.options.filename;this.fireEvent("add",b.options.torrentId,d)}});
+/*
+ * Deluge.preferences.BandwidthPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Bandwidth=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Bandwidth"),layout:"form",labelWidth:10},a);Deluge.preferences.Bandwidth.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Bandwidth.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=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});b.bind("max_connections_global",a.add({name:"max_connections_global",fieldLabel:_("Maximum Connections"),width:80,value:-1,decimalPrecision:0}));b.bind("max_upload_slots_global",a.add({name:"max_upload_slots_global",fieldLabel:_("Maximum Upload Slots"),width:80,value:-1,decimalPrecision:0}));b.bind("max_download_speed",a.add({name:"max_download_speed",fieldLabel:_("Maximum Download Speed (KiB/s)"),width:80,value:-1,decimalPrecision:1}));b.bind("max_upload_speed",a.add({name:"max_upload_speed",fieldLabel:_("Maximum Upload Speed (KiB/s)"),width:80,value:-1,decimalPrecision:1}));b.bind("max_half_open_connections",a.add({name:"max_half_open_connections",fieldLabel:_("Maximum Half-Open Connections"),width:80,value:-1,decimalPrecision:0}));b.bind("max_connections_per_second",a.add({name:"max_connections_per_second",fieldLabel:_("Maximum Connection Attempts per Second"),width:80,value:-1,decimalPrecision:0}));a=this.add({xtype:"fieldset",border:false,title:"",defaultType:"checkbox",style:"padding-top: 0px; padding-bottom: 5px; margin-top: 0px; margin-bottom: 0px;",autoHeight:true});b.bind("ignore_limits_on_local_network",a.add({name:"ignore_limits_on_local_network",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Ignore limits on local network")}));b.bind("rate_limit_ip_overhead",a.add({name:"rate_limit_ip_overhead",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Rate limit IP overhead")}));a=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});b.bind("max_connections_per_torrent",a.add({name:"max_connections_per_torrent",fieldLabel:_("Maximum Connections"),width:80,value:-1,decimalPrecision:0}));b.bind("max_upload_slots_per_torrent",a.add({name:"max_upload_slots_per_torrent",fieldLabel:_("Maximum Upload Slots"),width:80,value:-1,decimalPrecision:0}));b.bind("max_download_speed_per_torrent",a.add({name:"max_download_speed_per_torrent",fieldLabel:_("Maximum Download Speed (KiB/s)"),width:80,value:-1,decimalPrecision:0}));b.bind("max_upload_speed_per_torrent",a.add({name:"max_upload_speed_per_torrent",fieldLabel:_("Maximum Upload Speed (KiB/s)"),width:80,value:-1,decimalPrecision:0}))}});
+/*
+ * Deluge.preferences.CachePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Cache=Ext.extend(Ext.form.FormPanel,{border:false,title:_("Cache"),layout:"form",initComponent:function(){Deluge.preferences.Cache.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("Settings"),autoHeight:true,labelWidth:180,defaultType:"spinnerfield",defaults:{decimalPrecision:0,minValue:-1,maxValue:999999}});b.bind("cache_size",a.add({fieldLabel:_("Cache Size (16 KiB Blocks)"),name:"cache_size",width:60,value:512}));b.bind("cache_expiry",a.add({fieldLabel:_("Cache Expiry (seconds)"),name:"cache_expiry",width:60,value:60}))}});
+/*
+ * Deluge.preferences.DaemonPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Daemon=Ext.extend(Ext.form.FormPanel,{border:false,title:_("Daemon"),layout:"form",initComponent:function(){Deluge.preferences.Daemon.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("Port"),autoHeight:true,defaultType:"spinnerfield"});b.bind("daemon_port",a.add({fieldLabel:_("Daemon port"),name:"daemon_port",value:58846,decimalPrecision:0,minValue:-1,maxValue:99999}));a=this.add({xtype:"fieldset",border:false,title:_("Connections"),autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("allow_remote",a.add({fieldLabel:"",height:22,labelSeparator:"",boxLabel:_("Allow Remote Connections"),name:"allow_remote"}));a=this.add({xtype:"fieldset",border:false,title:_("Other"),autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("new_release_check",a.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Downloads=Ext.extend(Ext.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Downloads"),layout:"form",autoHeight:true,width:320},a);Deluge.preferences.Downloads.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Downloads.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=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;"});b.bind("download_location",a.add({xtype:"textfield",name:"download_location",fieldLabel:_("Download to"),width:280}));var c=a.add({name:"move_completed_path",fieldLabel:_("Move completed to"),width:280});b.bind("move_completed",c.toggle);b.bind("move_completed_path",c.input);c=a.add({name:"torrentfiles_location",fieldLabel:_("Copy of .torrent files to"),width:280});b.bind("copy_torrent_file",c.toggle);b.bind("torrentfiles_location",c.input);c=a.add({name:"autoadd_location",fieldLabel:_("Autoadd .torrent files from"),width:280});b.bind("autoadd_enable",c.toggle);b.bind("autoadd_location",c.input);a=this.add({xtype:"fieldset",border:false,title:_("Allocation"),autoHeight:true,labelWidth:1,defaultType:"radiogroup",style:"margin-bottom: 5px; margin-top: 0; padding-bottom: 5px; padding-top: 0;",width:240});b.bind("compact_allocation",a.add({name:"compact_allocation",width:200,labelSeparator:"",defaults:{width:80,height:22,name:"compact_allocation"},items:[{boxLabel:_("Use Full"),inputValue:false},{boxLabel:_("Use Compact"),inputValue:true}]}));a=this.add({xtype:"fieldset",border:false,title:_("Options"),autoHeight:true,labelWidth:1,defaultType:"checkbox",style:"margin-bottom: 0; padding-bottom: 0;",width:280});b.bind("prioritize_first_last_pieces",a.add({name:"prioritize_first_last_pieces",labelSeparator:"",height:22,boxLabel:_("Prioritize first and last pieces of torrent")}));b.bind("add_paused",a.add({name:"add_paused",labelSeparator:"",height:22,boxLabel:_("Add torrents in Paused state")}))}});
+/*
+ * Deluge.preferences.EncryptionPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Encryption=Ext.extend(Ext.form.FormPanel,{border:false,title:_("Encryption"),initComponent:function(){Deluge.preferences.Encryption.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("Settings"),autoHeight:true,defaultType:"combo",width:300});b.bind("enc_in_policy",a.add({fieldLabel:_("Inbound"),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"}));b.bind("enc_out_policy",a.add({fieldLabel:_("Outbound"),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"}));b.bind("enc_level",a.add({fieldLabel:_("Level"),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"}));b.bind("enc_prefer_rc4",a.add({xtype:"checkbox",name:"enc_prefer_rc4",height:40,hideLabel:true,boxLabel:_("Encrypt entire stream")}))}});
+/*
+ * Deluge.preferences.InstallPluginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.InstallPluginWindow=Ext.extend(Ext.Window,{title:_("Install Plugin"),layout:"fit",height:115,width:350,bodyStyle:"padding: 10px 5px;",buttonAlign:"center",closeAction:"hide",iconCls:"x-deluge-install-plugin",modal:true,plain:true,initComponent:function(){Deluge.add.FileWindow.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(b,a){this.form.getForm().submit({url:deluge.config.base+"upload",waitMsg:_("Uploading your plugin..."),success:this.onUploadSuccess,scope:this})},onUploadPlugin:function(d,c,a,b){this.fireEvent("pluginadded")},onUploadSuccess:function(c,b){this.hide();if(b.result.success){var a=this.form.getForm().getFieldValues().file;a=a.split("\\").slice(-1)[0];var d=b.result.files[0];this.form.getForm().setValues({file:""});deluge.client.web.upload_plugin(a,d,{success:this.onUploadPlugin,scope:this,filename:a})}}});
+/*
+ * Deluge.preferences.InterfacePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Interface=Ext.extend(Ext.form.FormPanel,{border:false,title:_("Interface"),layout:"form",initComponent:function(){Deluge.preferences.Interface.superclass.initComponent.call(this);var c=this.optionsManager=new Deluge.OptionsManager();this.on("show",this.onPageShow,this);var a=this.add({xtype:"fieldset",border:false,title:_("Interface"),style:"margin-bottom: 0px; padding-bottom: 5px; padding-top: 5px",autoHeight:true,labelWidth:1,defaultType:"checkbox"});c.bind("show_session_speed",a.add({name:"show_session_speed",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Show session speed in titlebar")}));c.bind("sidebar_show_zero",a.add({name:"sidebar_show_zero",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Show filters with zero torrents")}));c.bind("sidebar_multiple_filters",a.add({name:"sidebar_multiple_filters",height:22,fieldLabel:"",labelSeparator:"",boxLabel:_("Allow the use of multiple filters at once")}));a=this.add({xtype:"fieldset",border:false,title:_("Password"),style:"margin-bottom: 0px; padding-bottom: 0px; padding-top: 5px",autoHeight:true,labelWidth:110,defaultType:"textfield",defaults:{width:180,inputType:"password"}});this.oldPassword=a.add({name:"old_password",fieldLabel:_("Old Password")});this.newPassword=a.add({name:"new_password",fieldLabel:_("New Password")});this.confirmPassword=a.add({name:"confirm_password",fieldLabel:_("Confirm Password")});var b=a.add({xtype:"panel",autoHeight:true,border:false,width:320,bodyStyle:"padding-left: 230px"});b.add({xtype:"button",text:_("Change"),listeners:{click:{fn:this.onPasswordChange,scope:this}}});a=this.add({xtype:"fieldset",border:false,title:_("Server"),style:"margin-top: 0px; padding-top: 0px; margin-bottom: 0px; padding-bottom: 0px",autoHeight:true,labelWidth:110,defaultType:"spinnerfield",defaults:{width:80}});c.bind("session_timeout",a.add({name:"session_timeout",fieldLabel:_("Session Timeout"),decimalPrecision:0,minValue:-1,maxValue:99999}));c.bind("port",a.add({name:"port",fieldLabel:_("Port"),decimalPrecision:0,minValue:-1,maxValue:99999}));this.httpsField=c.bind("https",a.add({xtype:"checkbox",name:"https",hideLabel:true,width:280,height:22,boxLabel:_("Use SSL (paths relative to Deluge config folder)")}));this.httpsField.on("check",this.onSSLCheck,this);this.pkeyField=c.bind("pkey",a.add({xtype:"textfield",disabled:true,name:"pkey",width:180,fieldLabel:_("Private Key")}));this.certField=c.bind("cert",a.add({xtype:"textfield",disabled:true,name:"cert",width:180,fieldLabel:_("Certificate")}))},onApply:function(){var b=this.optionsManager.getDirty();if(!Ext.isObjectEmpty(b)){deluge.client.web.set_config(b,{success:this.onSetConfig,scope:this});for(var a in deluge.config){deluge.config[a]=this.optionsManager.get(a)}}},onGotConfig:function(a){this.optionsManager.set(a)},onPasswordChange:function(){var b=this.newPassword.getValue();if(b!=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 a=this.oldPassword.getValue();deluge.client.auth.change_password(a,b,{success:function(c){if(!c){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})},onSSLCheck:function(b,a){this.pkeyField.setDisabled(!a);this.certField.setDisabled(!a)}});
+/*
+ * Deluge.preferences.NetworkPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Network=Ext.extend(Ext.form.FormPanel,{border:false,layout:"form",title:_("Network"),initComponent:function(){Deluge.preferences.Network.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("Incoming Ports"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("random_port",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Ports"),name:"random_port",height:22,listeners:{check:{fn:function(d,c){this.listenPorts.setDisabled(c)},scope:this}}}));this.listenPorts=a.add({xtype:"spinnergroup",name:"listen_ports",fieldLabel:"",labelSeparator:"",colCfg:{labelWidth:40,style:"margin-right: 10px;"},items:[{fieldLabel:"From",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}},{fieldLabel:"To",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}}]});b.bind("listen_ports",this.listenPorts);a=this.add({xtype:"fieldset",border:false,title:_("Outgoing Ports"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("random_outgoing_ports",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Use Random Ports"),name:"random_outgoing_ports",height:22,listeners:{check:{fn:function(d,c){this.outgoingPorts.setDisabled(c)},scope:this}}}));this.outgoingPorts=a.add({xtype:"spinnergroup",name:"outgoing_ports",fieldLabel:"",labelSeparator:"",colCfg:{labelWidth:40,style:"margin-right: 10px;"},items:[{fieldLabel:"From",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}},{fieldLabel:"To",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:99999}}]});b.bind("outgoing_ports",this.outgoingPorts);a=this.add({xtype:"fieldset",border:false,title:_("Network Interface"),style:"margin-bottom: 5px; padding-bottom: 0px;",autoHeight:true,labelWidth:1,defaultType:"textfield"});b.bind("listen_interface",a.add({name:"listen_interface",fieldLabel:"",labelSeparator:"",width:200}));a=this.add({xtype:"fieldset",border:false,title:_("TOS"),style:"margin-bottom: 5px; padding-bottom: 0px;",bodyStyle:"margin: 0px; padding: 0px",autoHeight:true,defaultType:"textfield"});b.bind("peer_tos",a.add({name:"peer_tos",fieldLabel:_("Peer TOS Byte"),width:80}));a=this.add({xtype:"fieldset",border:false,title:_("Network Extras"),autoHeight:true,layout:"table",layoutConfig:{columns:3},defaultType:"checkbox"});b.bind("upnp",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("UPnP"),name:"upnp"}));b.bind("natpmp",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("NAT-PMP"),ctCls:"x-deluge-indent-checkbox",name:"natpmp"}));b.bind("utpex",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("Peer Exchange"),ctCls:"x-deluge-indent-checkbox",name:"utpex"}));b.bind("lsd",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("LSD"),name:"lsd"}));b.bind("dht",a.add({fieldLabel:"",labelSeparator:"",boxLabel:_("DHT"),ctCls:"x-deluge-indent-checkbox",name:"dht"}))}});
+/*
+ * Deluge.preferences.OtherPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Other=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Other"),layout:"form"},a);Deluge.preferences.Other.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Other.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("Updates"),autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("new_release_check",a.add({fieldLabel:"",labelSeparator:"",height:22,name:"new_release_check",boxLabel:_("Be alerted about new releases")}));a=this.add({xtype:"fieldset",border:false,title:_("System Information"),autoHeight:true,labelWidth:1,defaultType:"checkbox"});a.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.")}});b.bind("send_info",a.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Yes, please send anonymous statistics"),name:"send_info"}));a=this.add({xtype:"fieldset",border:false,title:_("GeoIP Database"),autoHeight:true,labelWidth:80,defaultType:"textfield"});b.bind("geoip_db_location",a.add({name:"geoip_db_location",fieldLabel:_("Location"),width:200}))}});
+/*
+ * Deluge.preferences.PluginsPage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Plugins=Ext.extend(Ext.Panel,{layout:"border",title:_("Plugins"),border:false,height:400,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>{details}</dd></dl>'),initComponent:function(){Deluge.preferences.Plugins.superclass.initComponent.call(this);this.defaultValues={version:"",email:"",homepage:"",details:""};this.pluginTemplate.compile();var c=function(e,f,d){f.css+=" x-grid3-check-col-td";return'<div class="x-grid3-check-col'+(e?"-on":"")+'"> </div>'};this.list=this.add({xtype:"listview",store:new Ext.data.ArrayStore({fields:[{name:"enabled",mapping:0},{name:"plugin",mapping:1}]}),columns:[{id:"enabled",header:_("Enabled"),width:0.2,sortable:true,tpl:new Ext.XTemplate("{enabled:this.getCheckbox}",{getCheckbox:function(d){return'<div class="x-grid3-check-col'+(d?"-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,margins:"5 5 5 5",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 b=this.pluginInfo=this.add({xtype:"panel",border:true,height:160,region:"south",margins:"0 5 5 5"});var a=b.add({xtype:"fieldset",title:_("Info"),border:false,autoHeight:true,labelWidth:1,style:"margin-top: 5px;"});this.pluginInfo=a.add({xtype:"panel",border:false,bodyCfg:{style:"margin-left: 10px"}});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(a){deluge.client.core.disable_plugin(a)},enablePlugin:function(a){deluge.client.core.enable_plugin(a)},setInfo:function(b){if(!this.pluginInfo.rendered){return}var a=b||this.defaultValues;this.pluginInfo.body.dom.innerHTML=this.pluginTemplate.apply(a)},updatePlugins:function(){deluge.client.web.get_plugins({success:this.onGotPlugins,scope:this})},updatePluginsGrid:function(){var a=[];Ext.each(this.availablePlugins,function(b){if(this.enabledPlugins.indexOf(b)>-1){a.push([true,b])}else{a.push([false,b])}},this);this.list.getStore().loadData(a)},onNodeClick:function(b,a,f,g){var c=new Ext.Element(g.target);if(c.getAttribute("rel")!="chkbox"){return}var d=b.getStore().getAt(a);d.set("enabled",!d.get("enabled"));d.commit();if(d.get("enabled")){this.enablePlugin(d.get("plugin"))}else{this.disablePlugin(d.get("plugin"))}},onFindMorePlugins:function(){window.open("http://dev.deluge-torrent.org/wiki/Plugins")},onGotPlugins:function(a){this.enabledPlugins=a.enabled_plugins;this.availablePlugins=a.available_plugins;this.setInfo();this.updatePluginsGrid()},onGotPluginInfo:function(b){var a={author:b.Author,version:b.Version,email:b["Author-email"],homepage:b["Home-page"],details:b.Description};this.setInfo(a);delete b},onInstallPluginWindow:function(){if(!this.installWindow){this.installWindow=new Deluge.preferences.InstallPluginWindow();this.installWindow.on("pluginadded",this.onPluginInstall,this)}this.installWindow.show()},onPluginEnabled:function(c){var a=this.list.getStore().find("plugin",c);if(a==-1){return}var b=this.list.getStore().getAt(a);b.set("enabled",true);b.commit()},onPluginDisabled:function(c){var a=this.list.getStore().find("plugin",c);if(a==-1){return}var b=this.list.getStore().getAt(a);b.set("enabled",false);b.commit()},onPluginInstall:function(){this.updatePlugins()},onPluginSelect:function(a,b){if(b.length==0){return}var c=a.getRecords(b)[0];deluge.client.web.get_plugin_info(c.get("plugin"),{success:this.onGotPluginInfo,scope:this})},onPreferencesShow:function(){this.updatePlugins()},onPluginInfoRender:function(b,a){this.setInfo()}});
+/*
+ * Deluge.preferences.PreferencesWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");PreferencesRecord=Ext.data.Record.create([{name:"name",type:"string"}]);Deluge.preferences.PreferencesWindow=Ext.extend(Ext.Window,{currentPage:null,title:_("Preferences"),layout:"border",width:485,height:500,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",title:_("Categories"),items:[this.list],width:120,margins:"5 0 5 5",cmargins:"5 0 5 5"});this.configPanel=this.add({type:"container",autoDestroy:false,region:"center",layout:"card",layoutConfig:{deferredRender:true},autoScroll:true,width:300,margins:"5 5 5 5",cmargins:"5 5 5 5"});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(b){var c=this.optionsManager.getDirty();if(!Ext.isObjectEmpty(c)){deluge.client.core.set_config(c,{success:this.onSetConfig,scope:this})}for(var a in this.pages){if(this.pages[a].onApply){this.pages[a].onApply()}}},getOptionsManager:function(){return this.optionsManager},addPage:function(c){var a=this.list.getStore();var b=c.title;a.add([new PreferencesRecord({name:b})]);c.bodyStyle="padding: 5px";c.preferences=this;this.pages[b]=this.configPanel.add(c);this.pages[b].index=-1;return this.pages[b]},removePage:function(c){var b=c.title;var a=this.list.getStore();a.removeAt(a.find("name",b));this.configPanel.remove(c);delete this.pages[c.title]},selectPage:function(a){if(this.pages[a].index<0){this.pages[a].index=this.configPanel.items.indexOf(this.pages[a])}this.list.select(this.pages[a].index)},doSelectPage:function(a){if(this.pages[a].index<0){this.pages[a].index=this.configPanel.items.indexOf(this.pages[a])}this.configPanel.getLayout().setActiveItem(this.pages[a].index);this.currentPage=a},onGotConfig:function(a){this.getOptionsManager().set(a)},onPageSelect:function(c,a){var b=c.getRecord(a[0]);this.doSelectPage(b.get("name"))},onSetConfig:function(){this.getOptionsManager().commit()},onAfterRender:function(){if(!this.list.getSelectionCount()){this.list.select(0)}this.configPanel.getLayout().setActiveItem(0)},onShow:function(){if(!deluge.client.core){return}deluge.client.core.get_config({success:this.onGotConfig,scope:this})},onClose:function(){this.hide()},onOk:function(){var b=this.optionsManager.getDirty();if(!Ext.isObjectEmpty(b)){deluge.client.core.set_config(b,{success:this.onSetConfig,scope:this})}for(var a in this.pages){if(this.pages[a].onOk){this.pages[a].onOk()}}this.hide()}});
+/*
+ * Deluge.preferences.ProxyField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge.preferences");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"),name:"proxytype",mode:"local",width:150,store:new Ext.data.ArrayStore({fields:["id","text"],data:[[0,_("None")],[1,_("Socksv4")],[2,_("Socksv5")],[3,_("Socksv5 with Auth")],[4,_("HTTP")],[5,_("HTTP with Auth")]]}),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"),width:220});this.hostname.on("change",this.onFieldChange,this);this.port=this.add({xtype:"spinnerfield",name:"port",fieldLabel:_("Port"),width:80,decimalPrecision:0,minValue:-1,maxValue:99999});this.port.on("change",this.onFieldChange,this);this.username=this.add({xtype:"textfield",name:"username",fieldLabel:_("Username"),width:220});this.username.on("change",this.onFieldChange,this);this.password=this.add({xtype:"textfield",name:"password",fieldLabel:_("Password"),inputType:"password",width:220});this.password.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()}},setValue:function(c){this.setting=true;this.proxyType.setValue(c.type);var b=this.proxyType.getStore().find("id",c.type);var a=this.proxyType.getStore().getAt(b);this.hostname.setValue(c.hostname);this.port.setValue(c.port);this.username.setValue(c.username);this.password.setValue(c.password);this.onTypeSelect(this.type,a,b);this.setting=false},onFieldChange:function(e,d,c){if(this.setting){return}var b=this.getValue();var a=Ext.apply({},b);a[e.getName()]=c;this.fireEvent("change",this,b,a)},onTypeSelect:function(d,a,b){var c=a.get("id");if(c>0){this.hostname.show();this.port.show()}else{this.hostname.hide();this.port.hide()}if(c==3||c==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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Proxy=Ext.extend(Ext.form.FormPanel,{constructor:function(a){a=Ext.apply({border:false,title:_("Proxy"),layout:"form",autoScroll:true},a);Deluge.preferences.Proxy.superclass.constructor.call(this,a)},initComponent:function(){Deluge.preferences.Proxy.superclass.initComponent.call(this);this.peer=this.add(new Deluge.preferences.ProxyField({title:_("Peer"),name:"peer"}));this.peer.on("change",this.onProxyChange,this);this.web_seed=this.add(new Deluge.preferences.ProxyField({title:_("Web Seed"),name:"web_seed"}));this.web_seed.on("change",this.onProxyChange,this);this.tracker=this.add(new Deluge.preferences.ProxyField({title:_("Tracker"),name:"tracker"}));this.tracker.on("change",this.onProxyChange,this);this.dht=this.add(new Deluge.preferences.ProxyField({title:_("DHT"),name:"dht"}));this.dht.on("change",this.onProxyChange,this);deluge.preferences.getOptionsManager().bind("proxies",this)},getValue:function(){return{dht:this.dht.getValue(),peer:this.peer.getValue(),tracker:this.tracker.getValue(),web_seed:this.web_seed.getValue()}},setValue:function(b){for(var a in b){this[a].setValue(b[a])}},onProxyChange:function(e,d,c){var b=this.getValue();var a=Ext.apply({},b);a[e.getName()]=c;this.fireEvent("change",this,b,a)}});
+/*
+ * Deluge.preferences.QueuePage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge.preferences");Deluge.preferences.Queue=Ext.extend(Ext.form.FormPanel,{border:false,title:_("Queue"),layout:"form",initComponent:function(){Deluge.preferences.Queue.superclass.initComponent.call(this);var b=deluge.preferences.getOptionsManager();var a=this.add({xtype:"fieldset",border:false,title:_("General"),style:"padding-top: 5px;",autoHeight:true,labelWidth:1,defaultType:"checkbox"});b.bind("queue_new_to_top",a.add({fieldLabel:"",labelSeparator:"",height:22,boxLabel:_("Queue new torrents to top"),name:"queue_new_to_top"}));a=this.add({xtype:"fieldset",border:false,title:_("Active Torrents"),autoHeight:true,labelWidth:150,defaultType:"spinnerfield",style:"margin-bottom: 0px; padding-bottom: 0px;"});b.bind("max_active_limit",a.add({fieldLabel:_("Total Active"),name:"max_active_limit",value:8,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));b.bind("max_active_downloading",a.add({fieldLabel:_("Total Active Downloading"),name:"max_active_downloading",value:3,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));b.bind("max_active_seeding",a.add({fieldLabel:_("Total Active Seeding"),name:"max_active_seeding",value:5,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));b.bind("dont_count_slow_torrents",a.add({xtype:"checkbox",name:"dont_count_slow_torrents",height:40,hideLabel:true,boxLabel:_("Do not count slow torrents")}));a=this.add({xtype:"fieldset",border:false,title:_("Seeding"),autoHeight:true,labelWidth:150,defaultType:"spinnerfield",style:"margin-bottom: 0px; padding-bottom: 0px; margin-top: 0; padding-top: 0;"});b.bind("share_ratio_limit",a.add({fieldLabel:_("Share Ratio Limit"),name:"share_ratio_limit",value:8,width:80,incrementValue:0.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));b.bind("seed_time_ratio_limit",a.add({fieldLabel:_("Share Time Ratio"),name:"seed_time_ratio_limit",value:3,width:80,incrementValue:0.1,minValue:-1,maxValue:99999,alternateIncrementValue:1,decimalPrecision:2}));b.bind("seed_time_limit",a.add({fieldLabel:_("Seed Time (m)"),name:"seed_time_limit",value:5,width:80,decimalPrecision:0,minValue:-1,maxValue:99999}));a=this.add({xtype:"fieldset",border:false,autoHeight:true,layout:"table",layoutConfig:{columns:2},labelWidth:0,defaultType:"checkbox",defaults:{fieldLabel:"",labelSeparator:""}});this.stopAtRatio=a.add({name:"stop_seed_at_ratio",boxLabel:_("Stop seeding when share ratio reaches:")});this.stopAtRatio.on("check",this.onStopRatioCheck,this);b.bind("stop_seed_at_ratio",this.stopAtRatio);this.stopRatio=a.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});b.bind("stop_seed_ratio",this.stopRatio);this.removeAtRatio=a.add({name:"remove_seed_at_ratio",ctCls:"x-deluge-indent-checkbox",boxLabel:_("Remove torrent when share ratio is reached"),disabled:true,colspan:2});b.bind("remove_seed_at_ratio",this.removeAtRatio)},onStopRatioCheck:function(b,a){this.stopRatio.setDisabled(!a);this.removeAtRatio.setDisabled(!a)}});
+/*
+ * Deluge.StatusbarMenu.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");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(a){if(a.getXType()!="menucheckitem"){return}if(a.value=="other"){a.on("click",this.onOtherClicked,this)}else{a.on("checkchange",this.onLimitChanged,this)}},this)},setValue:function(b){var c=false;this.value=b=(b==0)?-1:b;var a=null;this.items.each(function(d){if(d.setChecked){d.suspendEvents();if(d.value==b){d.setChecked(true);c=true}else{d.setChecked(false)}d.resumeEvents()}if(d.value=="other"){a=d}});if(c){return}a.suspendEvents();a.setChecked(true);a.resumeEvents()},onLimitChanged:function(c,b){if(!b||c.value=="other"){return}var a={};a[c.group]=c.value;deluge.client.core.set_config(a,{success:function(){deluge.ui.update()}})},onOtherClicked:function(a,b){this.otherWin.group=a.group;this.otherWin.setValue(this.value);this.otherWin.show()}});
+/*
+ * Deluge.OptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge");Deluge.OptionsManager=Ext.extend(Ext.util.Observable,{constructor:function(a){a=a||{};this.binds={};this.changed={};this.options=(a&&a.options)||{};this.focused=null;this.addEvents({add:true,changed:true,reset:true});this.on("changed",this.onChange,this);Deluge.OptionsManager.superclass.constructor.call(this)},addOptions:function(a){this.options=Ext.applyIf(this.options,a)},bind:function(a,b){this.binds[a]=this.binds[a]||[];this.binds[a].push(b);b._doption=a;b.on("focus",this.onFieldFocus,this);b.on("blur",this.onFieldBlur,this);b.on("change",this.onFieldChange,this);b.on("check",this.onFieldChange,this);b.on("spin",this.onFieldChange,this);return b},commit:function(){this.options=Ext.apply(this.options,this.changed);this.reset()},convertValueType:function(a,b){if(Ext.type(a)!=Ext.type(b)){switch(Ext.type(a)){case"string":b=String(b);break;case"number":b=Number(b);break;case"boolean":if(Ext.type(b)=="string"){b=b.toLowerCase();b=(b=="true"||b=="1"||b=="on")?true:false}else{b=Boolean(b)}break}}return b},get:function(){if(arguments.length==1){var b=arguments[0];return(this.isDirty(b))?this.changed[b]:this.options[b]}else{var a={};Ext.each(arguments,function(c){if(!this.has(c)){return}a[c]=(this.isDirty(c))?this.changed[c]:this.options[c]},this);return a}},getDefault:function(a){return this.options[a]},getDirty:function(){return this.changed},isDirty:function(a){return !Ext.isEmpty(this.changed[a])},has:function(a){return(this.options[a])},reset:function(){this.changed={}},set:function(b,c){if(b===undefined){return}else{if(typeof b=="object"){var a=b;this.options=Ext.apply(this.options,a);for(var b in a){this.onChange(b,a[b])}}else{this.options[b]=c;this.onChange(b,c)}}},update:function(d,e){if(d===undefined){return}else{if(e===undefined){for(var c in d){this.update(c,d[c])}}else{var a=this.getDefault(d);e=this.convertValueType(a,e);var b=this.get(d);if(b==e){return}if(a==e){if(this.isDirty(d)){delete this.changed[d]}this.fireEvent("changed",d,e,b);return}this.changed[d]=e;this.fireEvent("changed",d,e,b)}}},onFieldBlur:function(b,a){if(this.focused==b){this.focused=null}},onFieldChange:function(b,a){if(b.field){b=b.field}this.update(b._doption,b.getValue())},onFieldFocus:function(b,a){this.focused=b},onChange:function(b,c,a){if(Ext.isEmpty(this.binds[b])){return}Ext.each(this.binds[b],function(d){if(d==this.focused){return}d.setValue(c)},this)}});
+/*
+ * Deluge.AddConnectionWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");Deluge.AddConnectionWindow=Ext.extend(Ext.Window,{title:_("Add Connection"),iconCls:"x-deluge-add-window-icon",layout:"fit",width:300,height:195,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"),name:"host",anchor:"75%",value:""},{xtype:"spinnerfield",fieldLabel:_("Port"),name:"port",strategy:{xtype:"number",decimalPrecision:0,minValue:-1,maxValue:65535},value:"58846",anchor:"40%"},{fieldLabel:_("Username"),name:"username",anchor:"75%",value:""},{fieldLabel:_("Password"),anchor:"75%",name:"password",inputType:"password",value:""}]})},onAddClick:function(){var a=this.form.getForm().getValues();deluge.client.web.add_host(a.host,a.port,a.username,a.password,{success:function(b){if(!b[0]){Ext.MessageBox.show({title:_("Error"),msg:"Unable to add host: "+b[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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");Deluge.AddTrackerWindow=Ext.extend(Ext.Window,{title:_("Add Tracker"),layout:"fit",width:375,height:150,plain:true,closable:true,resizable:false,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"),name:"trackers",anchor:"100%"}]})},onAddClick:function(){var b=this.form.getForm().findField("trackers").getValue();b=b.split("\n");var a=[];Ext.each(b,function(c){if(Ext.form.VTypes.url(c)){a.push(c)}},this);this.fireEvent("add",a);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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Ext.ux.util");Ext.ux.util.RpcClient=Ext.extend(Ext.util.Observable,{_components:[],_methods:[],_requests:{},_url:null,_optionKeys:["scope","success","failure"],constructor:function(a){Ext.ux.util.RpcClient.superclass.constructor.call(this,a);this._url=a.url||null;this._id=0;this.addEvents("connected","error");this.reloadMethods()},reloadMethods:function(){this._execute("system.listMethods",{success:this._setMethods,scope:this})},_execute:function(c,a){a=a||{};a.params=a.params||[];a.id=this._id;var b=Ext.encode({method:c,params:a.params,id:a.id});this._id++;return Ext.Ajax.request({url:this._url,method:"POST",success:this._onSuccess,failure:this._onFailure,scope:this,jsonData:b,options:a})},_onFailure:function(b,a){var c=a.options;errorObj={id:c.id,result:null,error:{msg:"HTTP: "+b.status+" "+b.statusText,code:255}};this.fireEvent("error",errorObj,b,a);if(Ext.type(c.failure)!="function"){return}if(c.scope){c.failure.call(c.scope,errorObj,b,a)}else{c.failure(errorObj,b,a)}},_onSuccess:function(c,a){var b=Ext.decode(c.responseText);var d=a.options;if(b.error){this.fireEvent("error",b,c,a);if(Ext.type(d.failure)!="function"){return}if(d.scope){d.failure.call(d.scope,b,c,a)}else{d.failure(b,c,a)}}else{if(Ext.type(d.success)!="function"){return}if(d.scope){d.success.call(d.scope,b.result,b,c,a)}else{d.success(b.result,b,c,a)}}},_parseArgs:function(c){var e=[];Ext.each(c,function(f){e.push(f)});var b=e[e.length-1];if(Ext.type(b)=="object"){var d=Ext.keys(b),a=false;Ext.each(this._optionKeys,function(f){if(d.indexOf(f)>-1){a=true}});if(a){e.remove(b)}else{b={}}}else{b={}}b.params=e;return b},_setMethods:function(b){var d={},a=this;Ext.each(b,function(h){var g=h.split(".");var e=d[g[0]]||{};var f=function(){var i=a._parseArgs(arguments);return a._execute(h,i)};e[g[1]]=f;d[g[0]]=e});for(var c in d){a[c]=d[c]}Ext.each(this._components,function(e){if(!e in d){delete this[e]}},this);this._components=Ext.keys(d);this.fireEvent("connected",this)}});
+/*
+ * Deluge.ConnectionManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.ConnectionManager=Ext.extend(Ext.Window,{layout:"fit",width:300,height:220,bodyStyle:"padding: 10px 5px;",buttonAlign:"right",closeAction:"hide",closable:true,plain: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:3},{name:"host",mapping:1},{name:"port",mapping:2},{name:"version",mapping:4}],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:"{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-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)},checkConnected:function(){deluge.client.web.connected({success:function(a){if(a){deluge.events.fire("connect")}else{this.show()}},scope:this})},disconnect:function(a){deluge.events.fire("disconnect");if(a){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(a){deluge.client.web.get_host_status(a.id,{success:this.onGetHostStatus,scope:this})},this)},updateButtons:function(b){var c=this.buttons[1],a=b.get("status");if(a=="Connected"){c.enable();c.setText(_("Disconnect"))}else{if(a=="Offline"){c.disable()}else{c.enable();c.setText(_("Connect"))}}if(a=="Offline"){if(b.get("host")=="127.0.0.1"||b.get("host")=="localhost"){this.stopHostButton.enable();this.stopHostButton.setText(_("Start Daemon"))}else{this.stopHostButton.disable()}}else{this.stopHostButton.enable();this.stopHostButton.setText(_("Stop Daemon"))}},onAddClick:function(a,b){if(!this.addWindow){this.addWindow=new Deluge.AddConnectionWindow();this.addWindow.on("hostadded",this.onHostAdded,this)}this.addWindow.show()},onHostAdded:function(){this.loadHosts()},onClose:function(a){this.hide()},onConnect:function(b){var a=this.list.getSelectedRecords()[0];if(!a){return}if(a.get("status")=="Connected"){deluge.client.web.disconnect({success:function(d){this.update(this);deluge.events.fire("disconnect")},scope:this})}else{var c=a.id;deluge.client.web.connect(c,{success:function(d){deluge.client.reloadMethods();deluge.client.on("connected",function(f){deluge.events.fire("connect")},this,{single:true})}});this.hide()}},onGetHosts:function(a){this.list.getStore().loadData(a);Ext.each(a,function(b){deluge.client.web.get_host_status(b[0],{success:this.onGetHostStatus,scope:this})},this)},onGetHostStatus:function(b){var a=this.list.getStore().getById(b[0]);a.set("status",b[3]);a.set("version",b[4]);a.commit();if(this.list.getSelectedRecords()[0]==a){this.updateButtons(a)}},onHide:function(){if(this.running){window.clearInterval(this.running)}},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(a){this.checkConnected();if(a=="yes"){deluge.preferences.show();deluge.preferences.selectPage("Interface")}deluge.client.web.set_config({first_login:false})},this)}else{this.checkConnected()}},onLogout:function(){this.disconnect();if(!this.hidden&&this.rendered){this.hide()}},onRemoveClick:function(b){var a=this.list.getSelectedRecords()[0];if(!a){return}deluge.client.web.remove_host(a.id,{success:function(c){if(!c){Ext.MessageBox.show({title:_("Error"),msg:c[1],buttons:Ext.MessageBox.OK,modal:false,icon:Ext.MessageBox.ERROR,iconCls:"x-deluge-icon-error"})}else{this.list.getStore().remove(a)}},scope:this})},onSelectionChanged:function(b,a){if(a[0]){this.removeHostButton.enable();this.stopHostButton.enable();this.stopHostButton.setText(_("Stop Daemon"));this.updateButtons(this.list.getRecord(a[0]))}else{this.removeHostButton.disable();this.stopHostButton.disable()}},onShow:function(){if(!this.addHostButton){var a=this.panel.getBottomToolbar();this.addHostButton=a.items.get("cm-add");this.removeHostButton=a.items.get("cm-remove");this.stopHostButton=a.items.get("cm-stop")}this.loadHosts();if(this.running){return}this.running=window.setInterval(this.update,2000,this)},onStopClick:function(b,c){var a=this.list.getSelectedRecords()[0];if(!a){return}if(a.get("status")=="Offline"){deluge.client.web.start_daemon(a.get("port"))}else{deluge.client.web.stop_daemon(a.id,{success:function(d){if(!d[0]){Ext.MessageBox.show({title:_("Error"),msg:d[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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.state.Manager.setProvider(new Ext.state.CookieProvider({expires:new Date(new Date().getTime()+(1000*60*60*24*365*10))}));Ext.apply(Ext,{escapeHTML:function(a){a=String(a).replace("<","&lt;").replace(">","&gt;");return a.replace("&","&amp;")},isObjectEmpty:function(b){for(var a in b){return false}return true},areObjectsEqual:function(d,c){var b=true;if(!d||!c){return false}for(var a in d){if(d[a]!=c[a]){b=false}}return b},keys:function(c){var b=[];for(var a in c){if(c.hasOwnProperty(a)){b.push(a)}}return b},values:function(c){var a=[];for(var b in c){if(c.hasOwnProperty(b)){a.push(c[b])}}return a},splat:function(b){var a=Ext.type(b);return(a)?((a!="array")?[b]:b):[]}});Ext.getKeys=Ext.keys;Ext.BLANK_IMAGE_URL=deluge.config.base+"images/s.gif";Ext.USE_NATIVE_JSON=true;Ext.apply(Deluge,{pluginStore:{},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>',progressBar:function(c,e,g,a){a=Ext.value(a,10);var b=((e/100)*c).toFixed(0);var d=b-1;var f=((b-a)>0?b-a:0);return String.format(Deluge.progressTpl,g,e,d,f)},createPlugin:function(a){return new Deluge.pluginStore[a]()},hasPlugin:function(a){return(Deluge.pluginStore[a])?true:false},registerPlugin:function(a,b){Deluge.pluginStore[a]=b}});deluge.plugins={};FILE_PRIORITY={9:"Mixed",0:"Do Not Download",1:"Normal Priority",2:"High Priority",5:"High Priority",7:"Highest Priority",Mixed:9,"Do Not Download":0,"Normal Priority":1,"High Priority":5,"Highest Priority":7};FILE_PRIORITY_CSS={9:"x-mixed-download",0:"x-no-download",1:"x-normal-download",2:"x-high-download",5:"x-high-download",7:"x-highest-download"}
+/*
+ * Deluge.EditTrackerWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+;Ext.ns("Deluge");Deluge.EditTrackerWindow=Ext.extend(Ext.Window,{title:_("Edit Tracker"),layout:"fit",width:375,height:110,plain:true,closable:true,resizable:false,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"),name:"tracker",anchor:"100%"}]})},show:function(a){Deluge.EditTrackerWindow.superclass.show.call(this);this.record=a;this.form.getForm().findField("tracker").setValue(a.data.url)},onCancelClick:function(){this.hide()},onHide:function(){this.form.getForm().findField("tracker").setValue("")},onSaveClick:function(){var a=this.form.getForm().findField("tracker").getValue();this.record.set("url",a);this.record.commit();this.hide()}});
+/*
+ * Deluge.EditTrackers.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");Deluge.EditTrackersWindow=Ext.extend(Ext.Window,{title:_("Edit Trackers"),layout:"fit",width:350,height:220,plain:true,closable:true,resizable: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({margins:"0 0 0 0",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(b){var a=this.list.getStore();Ext.each(b,function(d){var e=false,c=-1;a.each(function(f){if(f.get("tier")>c){c=f.get("tier")}if(d==f.get("tracker")){e=true;return false}},this);if(e){return}a.add(new a.recordType({tier:c+1,url:d}))},this)},onCancelClick:function(){this.hide()},onEditClick:function(){this.editWindow.show(this.list.getSelectedRecords()[0])},onHide:function(){this.list.getStore().removeAll()},onListNodeDblClicked:function(c,a,b,d){this.editWindow.show(this.list.getRecord(b))},onOkClick:function(){var a=[];this.list.getStore().each(function(b){a.push({tier:b.get("tier"),url:b.get("url")})},this);deluge.client.core.set_torrent_trackers(this.torrentId,a,{failure:this.onSaveFail,scope:this});this.hide()},onRemoveClick:function(){this.list.getStore().remove(this.list.getSelectedRecords()[0])},onRequestComplete:function(a){this.list.getStore().loadData(a);this.list.getStore().sort("tier","ASC")},onSaveFail:function(){},onSelect:function(a){if(a.getSelectionCount()){this.panel.getBottomToolbar().items.get(4).enable()}},onShow:function(){this.panel.getBottomToolbar().items.get(4).disable();var a=deluge.torrents.getSelected();this.torrentId=a.id;deluge.client.core.get_torrent_status(a.id,["trackers"],{success:this.onRequestComplete,scope:this})},onDownClick:function(){var a=this.list.getSelectedRecords()[0];if(!a){return}a.set("tier",a.get("tier")+1);a.store.sort("tier","ASC");a.store.commitChanges();this.list.select(a.store.indexOf(a))},onUpClick:function(){var a=this.list.getSelectedRecords()[0];if(!a){return}if(a.get("tier")==0){return}a.set("tier",a.get("tier")-1);a.store.sort("tier","ASC");a.store.commitChanges();this.list.select(a.store.indexOf(a))}});
+/*
+ * Deluge.EventsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.EventsManager=Ext.extend(Ext.util.Observable,{constructor:function(){this.toRegister=[];this.on("login",this.onLogin,this);Deluge.EventsManager.superclass.constructor.call(this)},addListener:function(a,c,b,d){this.addEvents(a);if(/[A-Z]/.test(a.substring(0,1))){if(!deluge.client){this.toRegister.push(a)}else{deluge.client.web.register_event_listener(a)}}Deluge.EventsManager.superclass.addListener.call(this,a,c,b,d)},getEvents:function(){deluge.client.web.get_events({success:this.onGetEventsSuccess,failure:this.onGetEventsFailure,scope:this})},start:function(){Ext.each(this.toRegister,function(a){deluge.client.web.register_event_listener(a)});this.running=true;this.errorCount=0;this.getEvents()},stop:function(){this.running=false},onLogin:function(){this.start()},onGetEventsSuccess:function(a){if(!this.running){return}if(a){Ext.each(a,function(d){var c=d[0],b=d[1];b.splice(0,0,c);this.fireEvent.apply(this,b)},this)}this.getEvents()},onGetEventsFailure:function(a,b){if(!this.running){return}if(!b.isTimeout&&this.errorCount++>=3){this.stop();return}this.getEvents()}});Deluge.EventsManager.prototype.on=Deluge.EventsManager.prototype.addListener;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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");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 c=this.filterType.replace("_"," "),b=c.split(" "),c="";Ext.each(b,function(d){fl=d.substring(0,1).toUpperCase();c+=fl+d.substring(1)+" "});this.setTitle(_(c));if(Deluge.FilterPanel.templates[this.filterType]){var a=Deluge.FilterPanel.templates[this.filterType]}else{var a='<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:a,dataIndex:"filter"}]});this.relayEvents(this.list,["selectionchange"])},getState:function(){if(!this.list.getSelectionCount()){return}var a=this.list.getSelectedRecords()[0];if(a.id=="All"){return}return a.id},getStates:function(){return this.states},getStore:function(){return this.list.getStore()},updateStates:function(b){this.states={};Ext.each(b,function(f){this.states[f[0]]=f[1]},this);var e=(this.show_zero==null)?deluge.config.sidebar_show_zero:this.show_zero;if(!e){var c=[];Ext.each(b,function(f){if(f[1]>0||f[0]==_("All")){c.push(f)}});b=c}var a=this.getStore();var d={};Ext.each(b,function(h,g){var f=a.getById(h[0]);if(!f){f=new a.recordType({filter:h[0],count:h[1]});f.id=h[0];a.insert(g,f)}f.beginEdit();f.set("filter",h[0]);f.set("count",h[1]);f.endEdit();d[h[0]]=true},this);a.each(function(f){if(d[f.id]){return}var g=this.list.getSelectedRecords()[0];a.remove(f);if(g.id==f.id){this.list.select(0)}},this);a.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+;Deluge.Formatters={date:function(c){function b(d,e){var f=d+"";while(f.length<e){f="0"+f}return f}c=c*1000;var a=new Date(c);return String.format("{0}/{1}/{2} {3}:{4}:{5}",b(a.getDate(),2),b(a.getMonth()+1,2),a.getFullYear(),b(a.getHours(),2),b(a.getMinutes(),2),b(a.getSeconds(),2))},size:function(b,a){if(!b&&!a){return""}b=b/1024;if(b<1024){return b.toFixed(1)+" KiB"}else{b=b/1024}if(b<1024){return b.toFixed(1)+" MiB"}else{b=b/1024}return b.toFixed(1)+" GiB"},sizeShort:function(b,a){if(!b&&!a){return""}b=b/1024;if(b<1024){return b.toFixed(1)+" K"}else{b=b/1024}if(b<1024){return b.toFixed(1)+" M"}else{b=b/1024}return b.toFixed(1)+" G"},speed:function(b,a){return(!b&&!a)?"":fsize(b,a)+"/s"},timeRemaining:function(c){if(c==0){return"&infin;"}c=c.toFixed(0);if(c<60){return c+"s"}else{c=c/60}if(c<60){var b=Math.floor(c);var d=Math.round(60*(c-b));if(d>0){return b+"m "+d+"s"}else{return b+"m"}}else{c=c/60}if(c<24){var a=Math.floor(c);var b=Math.round(60*(c-a));if(b>0){return a+"h "+b+"m"}else{return a+"h"}}else{c=c/24}var e=Math.floor(c);var a=Math.round(24*(c-e));if(a>0){return e+"d "+a+"h"}else{return e+"d"}},plain:function(a){return a},cssClassEscape:function(a){return a.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.Keys={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","save_path","total_done","total_uploaded","max_download_speed","max_upload_speed","seeds_peers_ratio"],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","seed_rank"],Files:["files","file_progress","file_priorities"],Peers:["peers"],Details:["name","save_path","total_size","num_files","message","tracker","comment"],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"]};Ext.each(Deluge.Keys.Grid,function(a){Deluge.Keys.Status.push(a)});
+/*
+ * Deluge.LoginWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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"),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(a){this.show(true)},scope:this})},show:function(a){if(this.firstShow){deluge.client.on("error",this.onClientError,this);this.firstShow=false}if(a){return Deluge.LoginWindow.superclass.show.call(this)}deluge.client.auth.check_session({success:function(b){if(b){deluge.events.fire("login")}else{this.show(true)}},failure:function(b){this.show(true)},scope:this})},onSpecialKey:function(b,a){if(a.getKey()==13){this.onLogin()}},onLogin:function(){var a=this.passwordField;deluge.client.auth.login(a.getValue(),{success:function(b){if(b){deluge.events.fire("login");this.hide();a.setRawValue("")}else{Ext.MessageBox.show({title:_("Login Failed"),msg:_("You entered an incorrect password"),buttons:Ext.MessageBox.OK,modal:false,fn:function(){a.focus(true,10)},icon:Ext.MessageBox.WARNING,iconCls:"x-deluge-icon-warning"})}},scope:this})},onClientError:function(c,b,a){if(c.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+deluge.menus={onTorrentActionSetOpt:function(c,f){var a=deluge.torrents.getSelectedIds();var d=c.initialConfig.torrentAction;var b={};b[d[0]]=d[1];deluge.client.core.set_torrent_options(a,b)},onTorrentActionMethod:function(b,d){var a=deluge.torrents.getSelectedIds();var c=b.initialConfig.torrentAction;deluge.client.core[c](a,{success:function(){deluge.ui.update()}})},onTorrentActionShow:function(b,d){var a=deluge.torrents.getSelectedIds();var c=b.initialConfig.torrentAction;switch(c){case"edit_trackers":deluge.editTrackers.show();break;case"remove":deluge.removeWindow.show(a);break;case"move":deluge.moveStorage.show(a);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 Storage"),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:"no_download",text:_("Do Not Download"),iconCls:"icon-do-not-download",filePriority:FILE_PRIORITY["Do Not Download"]},{id:"normal",text:_("Normal Priority"),iconCls:"icon-normal",filePriority:FILE_PRIORITY["Normal Priority"]},{id:"high",text:_("High Priority"),iconCls:"icon-high",filePriority:FILE_PRIORITY["High Priority"]},{id:"highest",text:_("Highest Priority"),iconCls:"icon-highest",filePriority:FILE_PRIORITY["Highest Priority"]}]});
+/*
+ * Deluge.MoveStorage.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge");Deluge.MoveStorage=Ext.extend(Ext.Window,{constructor:function(a){a=Ext.apply({title:_("Move Storage"),width:375,height:110,layout:"fit",buttonAlign:"right",closeAction:"hide",closable:true,iconCls:"x-deluge-move-storage",plain:true,resizable:false},a);Deluge.MoveStorage.superclass.constructor.call(this,a)},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:_("Location"),name:"location",width:240})},hide:function(){Deluge.MoveStorage.superclass.hide.call(this);this.torrentIds=null},show:function(a){Deluge.MoveStorage.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide()},onMove:function(){var a=this.moveLocation.getValue();deluge.client.core.move_storage(this.torrentIds,a);this.hide()}});deluge.moveStorage=new Deluge.MoveStorage();
+/*
+ * Deluge.MultiOptionsManager.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.MultiOptionsManager=Ext.extend(Deluge.OptionsManager,{constructor:function(a){this.currentId=null;this.stored={};Deluge.MultiOptionsManager.superclass.constructor.call(this,a)},changeId:function(d,b){var c=this.currentId;this.currentId=d;if(!b){for(var a in this.options){if(!this.binds[a]){continue}Ext.each(this.binds[a],function(e){e.setValue(this.get(a))},this)}}return c},commit:function(){this.stored[this.currentId]=Ext.apply(this.stored[this.currentId],this.changed[this.currentId]);this.reset()},get:function(){if(arguments.length==1){var b=arguments[0];return(this.isDirty(b))?this.changed[this.currentId][b]:this.getDefault(b)}else{if(arguments.length==0){var a={};for(var b in this.options){a[b]=(this.isDirty(b))?this.changed[this.currentId][b]:this.getDefault(b)}return a}else{var a={};Ext.each(arguments,function(c){a[c]=(this.isDirty(c))?this.changed[this.currentId][c]:this.getDefault(c)},this);return a}}},getDefault:function(a){return(this.has(a))?this.stored[this.currentId][a]:this.options[a]},getDirty:function(){return(this.changed[this.currentId])?this.changed[this.currentId]:{}},isDirty:function(a){return(this.changed[this.currentId]&&!Ext.isEmpty(this.changed[this.currentId][a]))},has:function(a){return(this.stored[this.currentId]&&!Ext.isEmpty(this.stored[this.currentId][a]))},reset:function(){if(this.changed[this.currentId]){delete this.changed[this.currentId]}if(this.stored[this.currentId]){delete this.stored[this.currentId]}},resetAll:function(){this.changed={};this.stored={};this.changeId(null)},setDefault:function(c,d){if(c===undefined){return}else{if(d===undefined){for(var b in c){this.setDefault(b,c[b])}}else{var a=this.getDefault(c);d=this.convertValueType(a,d);if(a==d){return}if(!this.stored[this.currentId]){this.stored[this.currentId]={}}this.stored[this.currentId][c]=d;if(!this.isDirty(c)){this.fireEvent("changed",c,d,a)}}}},update:function(d,e){if(d===undefined){return}else{if(e===undefined){for(var c in d){this.update(c,d[c])}}else{if(!this.changed[this.currentId]){this.changed[this.currentId]={}}var a=this.getDefault(d);e=this.convertValueType(a,e);var b=this.get(d);if(b==e){return}if(a==e){if(this.isDirty(d)){delete this.changed[this.currentId][d]}this.fireEvent("changed",d,e,b);return}else{this.changed[this.currentId][d]=e;this.fireEvent("changed",d,e,b)}}}}});
+/*
+ * Deluge.OtherLimitWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");Deluge.OtherLimitWindow=Ext.extend(Ext.Window,{layout:"fit",width:210,height:100,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(a){this.form.getForm().setValues({limit:a})},onCancelClick:function(){this.form.getForm().reset();this.hide()},onOkClick:function(){var a={};a[this.group]=this.form.getForm().getValues().limit;deluge.client.core.set_config(a,{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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Deluge");Deluge.Plugin=Ext.extend(Ext.util.Observable,{name:null,constructor:function(a){this.isDelugePlugin=true;this.addEvents({enabled:true,disabled:true});Deluge.Plugin.superclass.constructor.call(this,a)},disable:function(){this.fireEvent("disabled",this);if(this.onDisable){this.onDisable()}},enable:function(){deluge.client.reloadMethods();this.fireEvent("enable",this);if(this.onEnable){this.onEnable()}},registerTorrentStatus:function(b,f,a){a=a||{};var e=a.colCfg||{},d=a.storeCfg||{};d=Ext.apply(d,{name:b});deluge.torrents.meta.fields.push(d);deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);e=Ext.apply(e,{header:f,dataIndex:b});var c=deluge.torrents.columns.slice(0);c.push(e);deluge.torrents.colModel.setConfig(c);deluge.torrents.columns=c;Deluge.Keys.Grid.push(b);deluge.torrents.getView().refresh(true)},deregisterTorrentStatus:function(b){var a=[];Ext.each(deluge.torrents.meta.fields,function(e){if(e.name!=b){a.push(e)}});deluge.torrents.meta.fields=a;deluge.torrents.getStore().reader.onMetaChange(deluge.torrents.meta);var d=[];Ext.each(deluge.torrents.columns,function(e){if(e.dataIndex!=b){d.push(e)}});deluge.torrents.colModel.setConfig(d);deluge.torrents.columns=d;var c=[];Ext.each(Deluge.Keys.Grid,function(e){if(e==b){c.push(e)}});Deluge.Keys.Grid=c;deluge.torrents.getView().refresh(true)}});Ext.ns("Deluge.plugins");
+/*
+ * Deluge.RemoveWindow.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.RemoveWindow=Ext.extend(Ext.Window,{title:_("Remove Torrent"),layout:"fit",width:350,height:100,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(a){Ext.each(this.torrentIds,function(b){deluge.client.core.remove_torrent(b,a,{success:function(){this.onRemoved(b)},scope:this,torrentId:b})},this)},show:function(a){Deluge.RemoveWindow.superclass.show.call(this);this.torrentIds=a},onCancel:function(){this.hide();this.torrentIds=null},onRemove:function(){this.remove(false)},onRemoveData:function(){this.remove(true)},onRemoved:function(a){deluge.events.fire("torrentRemoved",a);this.hide();deluge.ui.update()}});deluge.removeWindow=new Deluge.RemoveWindow();
+/*
+ * Deluge.Sidebar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.Sidebar=Ext.extend(Ext.Panel,{panels:{},selected:null,constructor:function(a){a=Ext.apply({id:"sidebar",region:"west",cls:"deluge-sidebar",title:_("Filters"),layout:"accordion",split:true,width:200,minSize:100,collapsible:true,margins:"5 0 0 5",cmargins:"5 0 0 5"},a);Deluge.Sidebar.superclass.constructor.call(this,a)},initComponent:function(){Deluge.Sidebar.superclass.initComponent.call(this);deluge.events.on("disconnect",this.onDisconnect,this)},createFilter:function(c,b){var a=new Deluge.FilterPanel({filter:c});a.on("selectionchange",function(d,e){deluge.ui.update()});this.add(a);this.doLayout();this.panels[c]=a;a.header.on("click",function(d){if(!deluge.config.sidebar_multiple_filters){deluge.ui.update()}if(!a.list.getSelectionCount()){a.list.select(0)}});this.fireEvent("filtercreate",this,a);a.updateStates(b);this.fireEvent("afterfiltercreate",this,a)},getFilter:function(a){return this.panels[a]},getFilterStates:function(){var b={};if(deluge.config.sidebar_multiple_filters){this.items.each(function(d){var e=d.getState();if(e==null){return}b[d.filterType]=e},this)}else{var a=this.getLayout().activeItem;if(a){var c=a.getState();if(!c==null){return}b[a.filterType]=c}}return b},hasFilter:function(a){return(this.panels[a])?true:false},onDisconnect:function(){for(var a in this.panels){this.remove(this.panels[a])}this.panels={};this.selected=null},onFilterSelect:function(b,c,a){deluge.ui.update()},update:function(c){for(var b in c){var a=c[b];if(Ext.getKeys(this.panels).indexOf(b)>-1){this.panels[b].updateStates(a)}else{this.createFilter(b,a)}}Ext.each(Ext.keys(this.panels),function(d){if(Ext.keys(c).indexOf(d)==-1){this.remove(this.panels[d]);this.doLayout();delete this.panels[d]}},this)}});
+/*
+ * Deluge.Statusbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Deluge");Deluge.Statusbar=Ext.extend(Ext.ux.StatusBar,{constructor:function(a){a=Ext.apply({id:"deluge-statusbar",defaultIconCls:"x-deluge-statusbar x-not-connected",defaultText:_("Not Connected")},a);Deluge.Statusbar.superclass.constructor.call(this,a)},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-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 location"),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(a){a.show();a.enable()})}this.doLayout()},onDisconnect:function(){this.clearStatus({useDefaults:true});Ext.each(this.buttons,function(a){a.hide();a.disable()});this.doLayout()},update:function(b){if(!b){return}function c(d){return d+" KiB/s"}var a=function(f,e){var g=this.items.get("statusbar-"+f);if(e.limit.value>0){var h=(e.value.formatter)?e.value.formatter(e.value.value,true):e.value.value;var d=(e.limit.formatter)?e.limit.formatter(e.limit.value,true):e.limit.value;var i=String.format(e.format,h,d)}else{var i=(e.value.formatter)?e.value.formatter(e.value.value,true):e.value.value}g.setText(i);if(!g.menu){return}g.menu.setValue(e.limit.value)}.createDelegate(this);a("connections",{value:{value:b.num_connections},limit:{value:b.max_num_connections},format:"{0} ({1})"});a("downspeed",{value:{value:b.download_rate,formatter:Deluge.Formatters.speed},limit:{value:b.max_download,formatter:c},format:"{0} ({1})"});a("upspeed",{value:{value:b.upload_rate,formatter:Deluge.Formatters.speed},limit:{value:b.max_upload,formatter:c},format:"{0} ({1})"});a("traffic",{value:{value:b.download_protocol_rate,formatter:Deluge.Formatters.speed},limit:{value:b.upload_protocol_rate,formatter:Deluge.Formatters.speed},format:"{0}/{1}"});this.items.get("statusbar-dht").setText(b.dht_nodes);this.items.get("statusbar-freespace").setText(fsize(b.free_space))}});
+/*
+ * Deluge.Toolbar.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Deluge.Toolbar=Ext.extend(Ext.Toolbar,{constructor:function(a){a=Ext.apply({items:[{id:"tbar-deluge-text",disabled:true,text:_("Deluge"),iconCls:"x-deluge-main-panel"},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}]},a);Deluge.Toolbar.superclass.constructor.call(this,a)},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(a){this.items.get(a).enable()},this)},onDisconnect:function(){Ext.each(this.connectedButtons,function(a){this.items.get(a).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")},onPreferencesClick:function(){deluge.preferences.show()},onTorrentAction:function(c){var b=deluge.torrents.getSelections();var a=[];Ext.each(b,function(d){a.push(d.id)});switch(c.id){case"remove":deluge.removeWindow.show(a);break;case"pause":case"resume":deluge.client.core[c.id+"_torrent"](a,{success:function(){deluge.ui.update()}});break;case"up":case"down":deluge.client.core["queue_"+c.id](a,{success:function(){deluge.ui.update()}});break}},onTorrentAdd:function(){deluge.add.show()}});
+/*
+ * Deluge.TorrentGrid.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+(function(){function c(k){return(k==-1)?"":k+1}function f(l,m,k){return String.format('<div class="torrent-name x-deluge-{0}">{1}</div>',k.data.state.toLowerCase(),l)}function g(k){if(!k){return}return fspeed(k)}function i(k){if(k==-1){return""}return fspeed(k*1024)}function j(o,q,n){o=new Number(o);var k=o;var s=n.data.state+" "+o.toFixed(2)+"%";if(this.style){var m=this.style}else{var m=q.style}var l=new Number(m.match(/\w+:\s*(\d+)\w+/)[1]);return Deluge.progressBar(o,l-8,s)}function a(l,m,k){if(k.data.total_seeds>-1){return String.format("{0} ({1})",l,k.data.total_seeds)}else{return l}}function e(l,m,k){if(k.data.total_peers>-1){return String.format("{0} ({1})",l,k.data.total_peers)}else{return l}}function b(l,m,k){return(l<0)?"&infin;":parseFloat(new Number(l).toFixed(3))}function d(l,m,k){return String.format('<div style="background: url('+deluge.config.base+'tracker/{0}) no-repeat; padding-left: 20px;">{0}</div>',l)}function h(k){return k*-1}Deluge.TorrentGrid=Ext.extend(Ext.grid.GridPanel,{torrents:{},columns:[{id:"queue",header:_("#"),width:30,sortable:true,renderer:c,dataIndex:"queue"},{id:"name",header:_("Name"),width:150,sortable:true,renderer:f,dataIndex:"name"},{header:_("Size"),width:75,sortable:true,renderer:fsize,dataIndex:"total_wanted"},{header:_("Progress"),width:150,sortable:true,renderer:j,dataIndex:"progress"},{header:_("Down Speed"),width:80,sortable:true,renderer:g,dataIndex:"download_payload_rate"},{header:_("Up Speed"),width:80,sortable:true,renderer:g,dataIndex:"upload_payload_rate"},{header:_("ETA"),width:60,sortable:true,renderer:ftime,dataIndex:"eta"},{header:_("Seeders"),hidden:true,width:60,sortable:true,renderer:a,dataIndex:"num_seeds"},{header:_("Peers"),hidden:true,width:60,sortable:true,renderer:e,dataIndex:"num_peers"},{header:_("Ratio"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"ratio"},{header:_("Avail"),hidden:true,width:60,sortable:true,renderer:b,dataIndex:"distributed_copies"},{header:_("Added"),hidden:true,width:80,sortable:true,renderer:fdate,dataIndex:"time_added"},{header:_("Tracker"),hidden:true,width:120,sortable:true,renderer:d,dataIndex:"tracker_host"},{header:_("Save Path"),hidden:true,width:120,sortable:true,renderer:fplain,dataIndex:"save_path"},{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:_("Down Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_download_speed"},{header:_("Up Limit"),hidden:true,width:75,sortable:true,renderer:i,dataIndex:"max_upload_speed"},{header:_("Seeders")+"/"+_("Peers"),hidden:true,width:75,sortable:true,renderer:b,dataIndex:"seeds_peers_ratio"}],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:h},{name:"ratio",type:"float"},{name:"distributed_copies",type:"float"},{name:"time_added",type:"int"},{name:"tracker_host"},{name:"save_path"},{name:"total_done",type:"int"},{name:"total_uploaded",type:"int"},{name:"max_download_speed",type:"int"},{name:"max_upload_speed",type:"int"},{name:"seeds_peers_ratio",type:"float"}]},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(k){k=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,margins:"5 5 0 0",stateful:true,view:new Ext.ux.grid.BufferView({rowHeight:26,scrollDelay:false})},k);Deluge.TorrentGrid.superclass.constructor.call(this,k)},initComponent:function(){Deluge.TorrentGrid.superclass.initComponent.call(this);deluge.events.on("torrentRemoved",this.onTorrentRemoved,this);deluge.events.on("disconnect",this.onDisconnect,this);this.on("rowcontextmenu",function(k,n,m){m.stopEvent();var l=k.getSelectionModel();if(!l.isSelected(n)){l.selectRow(n)}deluge.menus.torrent.showAt(m.getPoint())})},getTorrent:function(k){return this.getStore().getAt(k)},getSelected:function(){return this.getSelectionModel().getSelected()},getSelections:function(){return this.getSelectionModel().getSelections()},getSelectedId:function(){return this.getSelectionModel().getSelected().id},getSelectedIds:function(){var k=[];Ext.each(this.getSelectionModel().getSelections(),function(l){k.push(l.id)});return k},update:function(o,m){var q=this.getStore();if(m){q.removeAll();this.torrents={}}var p=[];for(var r in o){var u=o[r];if(this.torrents[r]){var n=q.getById(r);n.beginEdit();for(var l in u){if(n.get(l)!=u[l]){n.set(l,u[l])}}n.endEdit()}else{var n=new Deluge.data.Torrent(u);n.id=r;this.torrents[r]=1;p.push(n)}}q.add(p);q.each(function(k){if(!o[k.id]){q.remove(k);delete this.torrents[k.id]}},this);q.commitChanges();var s=q.getSortState();if(!s){return}q.sort(s.field,s.direction)},onDisconnect:function(){this.getStore().removeAll();this.torrents={}},onTorrentRemoved:function(l){var k=this.getSelectionModel();Ext.each(l,function(n){var m=this.getStore().getById(n);if(k.isSelected(m)){k.deselectRow(this.getStore().indexOf(m))}this.getStore().remove(m);delete this.torrents[n]},this)}});deluge.torrents=new Deluge.TorrentGrid()})();
+/*
+ * Deluge.UI.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+deluge.ui={errorCount:0,filters:null,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,margins:"0 5 5 5",cmargins:"0 5 5 5",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"});for(var a in Deluge.pluginStore){a=Deluge.createPlugin(a);a.enable();deluge.plugins[a.name]=a}Ext.QuickTips.init();deluge.client.on("connected",function(b){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 a=deluge.sidebar.getFilterStates();this.oldFilters=this.filters;this.filters=a;deluge.client.web.update_ui(Deluge.Keys.Grid,a,{success:this.onUpdate,failure:this.onUpdateError,scope:this});deluge.details.update()},onConnectionError:function(a){},onConnectionSuccess:function(a){deluge.statusbar.setStatus({iconCls:"x-deluge-statusbar icon-ok",text:_("Connection restored")});clearInterval(this.checking);if(!a){deluge.connectionManager.show()}},onUpdateError:function(a){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++},onUpdate:function(a){if(!a.connected){deluge.connectionManager.disconnect(true);return}if(deluge.config.show_session_speed){document.title="D: "+fsize_short(a.stats.download_rate,true)+" U: "+fsize_short(a.stats.upload_rate,true)+" - "+this.originalTitle}if(Ext.areObjectsEqual(this.filters,this.oldFilters)){deluge.torrents.update(a.torrents)}else{deluge.torrents.update(a.torrents,true)}deluge.statusbar.update(a.stats);deluge.sidebar.update(a.filters);this.errorCount=0},onConnect:function(){if(!this.running){this.running=setInterval(this.update,2000);this.update()}deluge.client.web.get_plugins({success:this.onGotPlugins,scope:this})},onDisconnect:function(){this.stop()},onGotPlugins:function(a){Ext.each(a.enabled_plugins,function(b){if(deluge.plugins[b]){return}deluge.client.web.get_plugin_resources(b,{success:this.onGotPluginResources,scope:this})},this)},onPluginEnabled:function(a){if(deluge.plugins[a]){deluge.plugins[a].enable()}else{deluge.client.web.get_plugin_resources(a,{success:this.onGotPluginResources,scope:this})}},onGotPluginResources:function(b){var a=(Deluge.debug)?b.debug_scripts:b.scripts;Ext.each(a,function(c){Ext.ux.JSLoader({url:deluge.config.base+c,onLoad:this.onPluginLoaded,pluginName:b.name})},this)},onPluginDisabled:function(a){if(deluge.plugins[a]){deluge.plugins[a].disable()}},onPluginLoaded:function(a){if(!Deluge.hasPlugin(a.pluginName)){return}plugin=Deluge.createPlugin(a.pluginName);plugin.enable();deluge.plugins[plugin.name]=plugin},stop:function(){if(this.running){clearInterval(this.running);this.running=false;deluge.torrents.getStore().removeAll()}}};Ext.onReady(function(a){deluge.ui.initialize()}); \ No newline at end of file
diff --git a/deluge/ui/web/js/ext-extensions-debug.js b/deluge/ui/web/js/ext-extensions-debug.js
index 1ef07ab15..b8ce7c26c 100644
--- a/deluge/ui/web/js/ext-extensions-debug.js
+++ b/deluge/ui/web/js/ext-extensions-debug.js
@@ -1,915 +1,4 @@
/*!
- * 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 {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 v = this.fileInput.dom.value;
- this.setValue(v);
- this.fireEvent('fileselected', this, v);
- }
- });
- },
-
- 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
- });
- },
-
- 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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-
-// 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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-
-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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-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)*.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 program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-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>
@@ -966,98 +55,6 @@ Ext.override(Ext.layout.FormLayout, {
}
});
/*!
- * Ext.ux.tree.MultiSelectionModelFix.js
- *
- * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, write to:
- * The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301, USA.
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the OpenSSL
- * library.
- * You must obey the GNU General Public License in all respects for all of
- * the code used other than OpenSSL. If you modify file(s) with this
- * exception, you may extend this exception to your version of the file(s),
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version. If you delete this exception
- * statement from all source files in the program, then also delete it here.
- */
-
-/**
- * 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
@@ -1949,6 +946,917 @@ Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]);
}
});
+/*!
+ * 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 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 {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 v = this.fileInput.dom.value;
+ this.setValue(v);
+ this.fireEvent('fileselected', this, v);
+ }
+ });
+ },
+
+ 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
+ });
+ },
+
+ 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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+
+// 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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+
+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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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)*.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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.ux.JSLoader = function(options) {
Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index] = {
url: options.url,
diff --git a/deluge/ui/web/js/ext-extensions.js b/deluge/ui/web/js/ext-extensions.js
index 412d4c633..be6f182cb 100644
--- a/deluge/ui/web/js/ext-extensions.js
+++ b/deluge/ui/web/js/ext-extensions.js
@@ -1,83 +1,269 @@
-Ext.ns("Ext.ux.form");
-Ext.ux.form.FileUploadField=Ext.extend(Ext.form.TextField,{buttonText:"Browse...",buttonOnly:!1,buttonOffset:3,readOnly:!0,autoSize:Ext.emptyFn,initComponent:function(){Ext.ux.form.FileUploadField.superclass.initComponent.call(this);this.addEvents("fileselected")},onRender:function(a,b){Ext.ux.form.FileUploadField.superclass.onRender.call(this,a,b);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 c=Ext.applyIf(this.buttonCfg||{},{text:this.buttonText});this.button=new Ext.Button(Ext.apply(c,{renderTo:this.wrap,cls:"x-form-file-btn"+(c.iconCls?" x-btn-icon":"")}));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 a=this.fileInput.dom.value;this.setValue(a);this.fireEvent("fileselected",this,a)}})},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})},reset:function(){this.rendered&&(this.fileInput.remove(),
-this.createFileInput(),this.bindListeners());Ext.ux.form.FileUploadField.superclass.reset.call(this)},getFileInputId:function(){return this.id+"-file"},onResize:function(a,b){Ext.ux.form.FileUploadField.superclass.onResize.call(this,a,b);this.wrap.setWidth(a);this.buttonOnly||(a=this.wrap.getWidth()-this.button.getEl().getWidth()-this.buttonOffset,this.el.setWidth(a))},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(!0)},onEnable:function(){Ext.ux.form.FileUploadField.superclass.onEnable.call(this);this.doDisable(!1)},doDisable:function(a){this.fileInput.dom.disabled=a;this.button.setDisabled(a)},preFocus:Ext.emptyFn,alignErrorIcon:function(){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}});Ext.reg("fileuploadfield",Ext.ux.form.FileUploadField);Ext.form.FileUploadField=Ext.ux.form.FileUploadField;
-Ext.override(Ext.form.RadioGroup,{afterRender:function(){this.items.each(function(a){this.relayEvents(a,["check"])},this);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(a){this.items.each?this.items.each(function(b){if(b.rendered){var c=b.el.getValue()==String(a);b.el.dom.checked=
-c;b.el.dom.defaultChecked=c;b.wrap[c?"addClass":"removeClass"](b.checkedCls)}}):(this.value=a,this.lazyValue=!0)}});Ext.ns("Ext.ux.form");
-Ext.ux.form.SpinnerField=Ext.extend(Ext.form.NumberField,{actionMode:"wrap",deferHeight:!0,autoSize:Ext.emptyFn,onBlur:Ext.emptyFn,adjustSize:Ext.BoxComponent.prototype.adjustSize,constructor:function(a){var b=Ext.copyTo({},a,"incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass"),b=this.spinner=new Ext.ux.Spinner(b),b=a.plugins?Ext.isArray(a.plugins)?a.plugins.push(b):[a.plugins,b]:b;Ext.ux.form.SpinnerField.superclass.constructor.call(this,Ext.apply(a,{plugins:b}))},
-getResizeEl:function(){return this.wrap},getPositionEl:function(){return this.wrap},alignErrorIcon:function(){this.wrap&&this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])},validateBlur:function(){return!0}});Ext.reg("spinnerfield",Ext.ux.form.SpinnerField);Ext.form.SpinnerField=Ext.ux.form.SpinnerField;Ext.override(Ext.ux.form.SpinnerField,{onBlur:Ext.form.Field.prototype.onBlur});Ext.ns("Ext.ux.form");
-Ext.ux.form.SpinnerGroup=Ext.extend(Ext.form.CheckboxGroup,{defaultType:"spinnerfield",anchor:"98%",groupCls:"x-form-spinner-group",colCfg:{},onRender:function(a,b){if(!this.el){var c={cls:this.groupCls,layout:"column",border:!1,renderTo:a},d=Ext.apply({defaultType:this.defaultType,layout:"form",border:!1,labelWidth:60,defaults:{hideLabel:!0,anchor:"60%"}},this.colCfg);if(this.items[0].items){Ext.apply(c,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=
-0,g=this.items.length;e<g;e++)Ext.applyIf(this.items[e],d)}else{var f,h=[];"string"==typeof this.columns&&(this.columns=this.items.length);if(!Ext.isArray(this.columns)){f=[];for(e=0;e<this.columns;e++)f.push(100/this.columns*.01);this.columns=f}f=this.columns.length;for(e=0;e<f;e++)g=Ext.apply({items:[]},d),g[1>=this.columns[e]?"columnWidth":"width"]=this.columns[e],this.defaults&&(g.defaults=Ext.apply(g.defaults||{},this.defaults)),h.push(g);if(this.vertical)for(var d=Math.ceil(this.items.length/
-f),k=0,e=0,g=this.items.length;e<g;e++)0<e&&0==e%d&&k++,this.items[e].fieldLabel&&(this.items[e].hideLabel=!1),h[k].items.push(this.items[e]);else for(e=0,g=this.items.length;e<g;e++)d=e%f,this.items[e].fieldLabel&&(this.items[e].hideLabel=!1),h[d].items.push(this.items[e]);Ext.apply(c,{layoutConfig:{columns:f},items:h})}this.panel=new Ext.Panel(c);this.el=this.panel.getEl();this.forId&&this.itemCls&&(c=this.el.up(this.itemCls).child("label",!0))&&c.setAttribute("htmlFor",this.forId);c=this.panel.findBy(function(a){return a.isFormField},
-this);this.items=new Ext.util.MixedCollection;this.items.addAll(c);this.items.each(function(a){a.on("spin",this.onFieldChange,this);a.on("change",this.onFieldChange,this)},this);this.lazyValueSet&&(this.setValue(this.value),delete this.value,delete this.lazyValueSet);this.lazyRawValueSet&&(this.setRawValue(this.rawValue),delete this.rawValue,delete this.lazyRawValueSet)}Ext.ux.form.SpinnerGroup.superclass.onRender.call(this,a,b)},onFieldChange:function(a){this.fireEvent("change",this,this.getValue())},
-initValue:Ext.emptyFn,getValue:function(){var a=[this.items.getCount()];this.items.each(function(b,c){a[c]=Number(b.getValue())});return a},getRawValue:function(){var a=[this.items.getCount()];this.items.each(function(b,c){a[c]=Number(b.getRawValue())});return a},setValue:function(a){this.rendered?this.items.each(function(b,c){b.setValue(a[c])}):(this.value=a,this.lazyValueSet=!0)},setRawValue:function(a){this.rendered?this.items.each(function(b,c){b.setRawValue(a[c])}):(this.rawValue=a,this.lazyRawValueSet=
-!0)}});Ext.reg("spinnergroup",Ext.ux.form.SpinnerGroup);Ext.namespace("Ext.ux.form");
-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:!0})},onRender:function(a,b){this.el||(this.panel=new Ext.Panel({cls:this.groupCls,layout:"table",layoutConfig:{columns:2},border:!1,renderTo:a}),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,a,b)},onResize:function(a,b){this.panel.setSize(a,b);this.panel.doLayout();var c=a-this.toggle.getSize().width-25;this.input.setSize(c,b)},onToggleCheck:function(a,b){this.input.setDisabled(!b)}});Ext.reg("togglefield",Ext.ux.form.ToggleField);Ext.ns("Ext.ux.grid");
-Ext.ux.grid.BufferView=Ext.extend(Ext.grid.GridView,{rowHeight:19,borderHeight:2,scrollDelay:100,cacheSize:20,cleanDelay:500,initTemplates:function(){Ext.ux.grid.BufferView.superclass.initTemplates.call(this);var a=this.templates;a.rowHolder=new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}"></div>');a.rowHolder.disableFormats=!0;a.rowHolder.compile();a.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>");a.rowBody.disableFormats=!0;a.rowBody.compile()},getStyleRowHeight:function(){return Ext.isBorderBox?this.rowHeight+this.borderHeight:this.rowHeight},getCalculatedRowHeight:function(){return this.rowHeight+this.borderHeight},getVisibleRowCount:function(){var a=this.getCalculatedRowHeight(),
-b=this.scroller.dom.clientHeight;return 1>b?0:Math.ceil(b/a)},getVisibleRows:function(){var a=this.getVisibleRowCount(),b=this.scroller.dom.scrollTop,b=0===b?0:Math.floor(b/this.getCalculatedRowHeight())-1;return{first:Math.max(b,0),last:Math.min(b+a+2,this.ds.getCount()-1)}},doRender:function(a,b,c,d,e,g,f){for(var h=this.templates,k=h.cell,l=h.row,u=h.rowBody,p=e-1,v=this.getStyleRowHeight(),z=this.getVisibleRows(),y=[],n,m={},q={tstyle:"width:"+this.getTotalWidth()+";height:"+v+"px;"},r,x=0,B=
-b.length;x<B;x++){r=b[x];var v=[],w=x+d,A=w>=z.first&&w<=z.last;if(A)for(var t=0;t<e;t++){n=a[t];m.id=n.id;m.css=0===t?"x-grid3-cell-first ":t==p?"x-grid3-cell-last ":"";m.attr=m.cellAttr="";m.value=n.renderer(r.data[n.name],m,r,w,t,c);m.style=n.style;if(void 0===m.value||""===m.value)m.value="&#160;";r.dirty&&"undefined"!==typeof r.modified[n.name]&&(m.css+=" x-grid3-dirty-cell");v[v.length]=k.apply(m)}n=[];g&&0===(w+1)%2&&(n[0]="x-grid3-row-alt");r.dirty&&(n[1]=" x-grid3-dirty-row");q.cols=e;this.getRowClass&&
-(n[2]=this.getRowClass(r,w,q,c));q.alt=n.join(" ");q.cells=v.join("");y[y.length]=A?f?u.apply(q):l.apply(q):h.rowHolder.apply(q)}return y.join("")},isRowRendered:function(a){return(a=this.getRow(a))&&0<a.childNodes.length},syncScroll:function(){Ext.ux.grid.BufferView.superclass.syncScroll.apply(this,arguments);this.update()},update:function(){this.scrollDelay?(this.renderTask||(this.renderTask=new Ext.util.DelayedTask(this.doUpdate,this)),this.renderTask.delay(this.scrollDelay)):this.doUpdate()},
-onRemove:function(a,b,c,d){Ext.ux.grid.BufferView.superclass.onRemove.apply(this,arguments);!0!==d&&this.update()},doUpdate:function(){if(0<this.getVisibleRowCount()){for(var a=this.grid,b=a.colModel,c=a.store,d=this.getColumnData(),e=this.getVisibleRows(),g,f=e.first;f<=e.last;f++)if(!this.isRowRendered(f)&&(g=this.getRow(f))){var h=this.doRender(d,[c.getAt(f)],c,f,b.getColumnCount(),a.stripeRows,!0);g.innerHTML=h}this.clean()}},clean:function(){this.cleanTask||(this.cleanTask=new Ext.util.DelayedTask(this.doClean,
-this));this.cleanTask.delay(this.cleanDelay)},doClean:function(){if(0<this.getVisibleRowCount()){var a=this.getVisibleRows();a.first-=this.cacheSize;a.last+=this.cacheSize;var b=0,c=this.getRows();0>=a.first&&(b=a.last+1);for(var d=this.ds.getCount();b<d;b++)(b<a.first||b>a.last)&&c[b].innerHTML&&(c[b].innerHTML="")}},removeTask:function(a){var b=this[a];b&&b.cancel&&(b.cancel(),this[a]=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.override(Ext.layout.FormLayout,{renderItem:function(a,b,c){if(a&&!a.rendered&&(a.isFormField||a.fieldLabel)&&"hidden"!=a.inputType){var d=this.getTemplateArgs(a);"number"==typeof b&&(b=c.dom.childNodes[b]||null);a.formItem=b?this.fieldTpl.insertBefore(b,d,!0):this.fieldTpl.append(c,d,!0);a.actionMode="formItem";a.render("x-form-el-"+a.id);a.container=a.formItem;a.actionMode="container"}else Ext.layout.FormLayout.superclass.renderItem.apply(this,arguments)}});
-Ext.override(Ext.tree.MultiSelectionModel,{onNodeClick:function(a,b){if(b.ctrlKey&&this.isSelected(a))this.unselect(a);else if(b.shiftKey&&!this.isSelected(a)){var c=a.parentNode;if(this.lastSelNode.parentNode.id==c.id){var d=c.indexOf(a),e=c.indexOf(this.lastSelNode);this.select(this.lastSelNode,b,!1,!0);d>e&&(d+=e,e=d-e,d-=e);c.eachChild(function(a){var f=c.indexOf(a);d<f&&f<e&&this.select(a,b,!0,!0)},this);this.select(a,b,!0)}}else this.select(a,b,b.ctrlKey)},select:function(a,b,c,d){!0!==c&&this.clearSelections(!0);
-if(this.isSelected(a))return this.lastSelNode=a;this.selNodes.push(a);this.lastSelNode=this.selMap[a.id]=a;a.ui.onSelectedChange(!0);!0!==d&&this.fireEvent("selectionchange",this,this.selNodes);return a}});Ext.ns("Ext.ux.tree");
-Ext.ux.tree.TreeGrid=Ext.extend(Ext.tree.TreePanel,{rootVisible:!1,useArrows:!0,lines:!1,borderWidth:Ext.isBorderBox?0:2,cls:"x-treegrid",columnResize:!0,enableSort:!0,reserveScrollOffset:!0,enableHdMenu:!0,columnsText:"Columns",initComponent:function(){this.root||(this.root=new Ext.tree.AsyncTreeNode({text:"Root"}));var a=this.loader;a?Ext.isObject(a)&&!a.load&&(a=new Ext.ux.tree.TreeGridLoader(a)):a=new Ext.ux.tree.TreeGridLoader({dataUrl:this.dataUrl,requestMethod:this.requestMethod,store:this.store});
-this.loader=a;Ext.ux.tree.TreeGrid.superclass.initComponent.call(this);this.initColumns();this.enableSort&&(this.treeGridSorter=new Ext.ux.tree.TreeGridSorter(this,this.enableSort));this.columnResize&&(this.colResizer=new Ext.tree.ColumnResizer(this.columnResize),this.colResizer.init(this));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>"));this.colgroupTpl||(this.colgroupTpl=new Ext.XTemplate('<colgroup><tpl for="columns"><col style="width: {width}px"/></tpl></colgroup>'))},initColumns:function(){var a=this.columns,b=a.length,c=[],d,e;for(d=0;d<b;d++)e=a[d],e.isColumn||(e.xtype=e.xtype?/^tg/.test(e.xtype)?e.xtype:"tg"+e.xtype:"tgcolumn",e=Ext.create(e)),e.init(this),c.push(e),!1!==this.enableSort&&!1!==e.sortable&&(this.enableSort=e.sortable=!0);this.columns=c},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});
-this.hideHeaders?this.el.child(".x-grid3-header").setDisplayed("none"):!1!==this.enableHdMenu&&(this.hmenu=new Ext.menu.Menu({id:this.id+"-hctx"}),!1!==this.enableColumnHide&&(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:!1,text:this.columnsText,menu:this.colMenu,iconCls:"x-cols-icon"})),this.hmenu.on("itemclick",this.handleHdMenuClick,this))},
-setRootNode:function(a){a.attributes.uiProvider=Ext.ux.tree.TreeGridRootNodeUI;a=Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this,a);this.innerCt&&this.colgroupTpl.insertFirst(this.innerCt,{columns:this.columns});return a},clearInnerCt:function(){if(Ext.isIE)for(var a=this.innerCt.dom;a.firstChild;)a.removeChild(a.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(a,b){Ext.ux.tree.TreeGrid.superclass.onResize.apply(this,arguments);var c=this.innerBody.dom,d=this.innerHd.dom;if(c&&(Ext.isNumber(b)&&(c.style.height=this.body.getHeight(!0)-d.offsetHeight+"px"),Ext.isNumber(a))){var e=Ext.num(this.scrollOffset,Ext.getScrollBarWidth());if(this.reserveScrollOffset||10<c.offsetWidth-
-c.clientWidth)this.setScrollOffset(e);else{var g=this;setTimeout(function(){g.setScrollOffset(10<c.offsetWidth-c.clientWidth?e:0)},10)}}},updateColumnWidths:function(){var a=this.columns,b=a.length,c=this.outerCt.query("colgroup"),d=c.length,e,g,f,h;for(f=0;f<b;f++)for(e=a[f],h=0;h<d;h++)g=c[h],g.childNodes[f].style.width=(e.hidden?0:e.width)+"px";f=0;c=this.innerHd.query("td");for(len=c.length;f<len;f++)e=Ext.fly(c[f]),a[f]&&a[f].hidden?e.addClass("x-treegrid-hd-hidden"):e.removeClass("x-treegrid-hd-hidden");
-a=this.getTotalColumnWidth();Ext.fly(this.innerHd.dom.firstChild).setWidth(a+(this.scrollOffset||0));this.outerCt.select("table").setWidth(a);this.syncHeaderScroll()},getVisibleColumns:function(){var a=[],b=this.columns,c=b.length,d;for(d=0;d<c;d++)b[d].hidden||a.push(b[d]);return a},getTotalColumnWidth:function(){for(var a=0,b=0,c=this.getVisibleColumns(),d=c.length;b<d;b++)a+=c[b].width;return a},setScrollOffset:function(a){this.scrollOffset=a;this.updateColumnWidths()},handleHdDown:function(a,
-b){var c=a.getTarget(".x-treegrid-hd");if(c&&Ext.fly(b).hasClass("x-grid3-hd-btn")){var d=this.hmenu.items,e=this.columns,g=this.findHeaderIndex(c),e=e[g];a.stopEvent();Ext.fly(c).addClass("x-grid3-hd-menu-open");this.hdCtxIndex=g;this.fireEvent("headerbuttonclick",d,e,c,g);this.hmenu.on("hide",function(){Ext.fly(c).removeClass("x-grid3-hd-menu-open")},this,{single:!0});this.hmenu.show(b,"tl-bl?")}else c&&(g=this.findHeaderIndex(c),this.fireEvent("headerclick",this.columns[g],c,g))},handleHdOver:function(a,
-b){var c=a.getTarget(".x-treegrid-hd");if(c&&!this.headersDisabled){index=this.findHeaderIndex(c);this.activeHdRef=b;this.activeHdIndex=index;var d=Ext.get(c);this.activeHdRegion=d.getRegion();d.addClass("x-grid3-hd-over");if(this.activeHdBtn=d.child(".x-grid3-hd-btn"))this.activeHdBtn.dom.style.height=c.firstChild.offsetHeight-1+"px"}},handleHdOut:function(a,b){var c=a.getTarget(".x-treegrid-hd");!c||Ext.isIE&&a.within(c,!0)||(this.activeHdRef=null,Ext.fly(c).removeClass("x-grid3-hd-over"),c.style.cursor=
-"")},findHeaderIndex:function(a){a=a.dom||a;for(var b=a.parentNode.childNodes,c=0,d;d=b[c];c++)if(d==a)return c;return-1},beforeColMenuShow:function(){var a=this.columns,b=a.length,c,d;this.colMenu.removeAll();for(c=1;c<b;c++)d=a[c],!1!==d.hideable&&this.colMenu.add(new Ext.menu.CheckItem({itemId:"col-"+c,text:d.header,checked:!d.hidden,hideOnClick:!1,disabled:!1===d.hideable}))},handleHdMenuClick:function(a){var b=this.hdCtxIndex,c=a.getItemId();!1!==this.fireEvent("headermenuclick",this.columns[b],
-c,b)&&(b=c.substr(4),0<b&&this.columns[b]&&this.setColumnVisible(b,!a.checked));return!0},setColumnVisible:function(a,b){this.columns[a].hidden=!b;this.updateColumnWidths()},scrollToTop:function(){this.innerBody.dom.scrollTop=0;this.innerBody.dom.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.innerBody.dom;this.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerBody.dom;this.innerHd.dom.scrollLeft=a.scrollLeft;this.innerHd.dom.scrollLeft=
-a.scrollLeft},registerNode:function(a){Ext.ux.tree.TreeGrid.superclass.registerNode.call(this,a);a.uiProvider||a.isRoot||a.ui.isTreeGridNodeUI||(a.ui=new Ext.ux.tree.TreeGridNodeUI(a))}});Ext.reg("treegrid",Ext.ux.tree.TreeGrid);
-Ext.tree.ColumnResizer=Ext.extend(Ext.util.Observable,{minWidth:14,constructor:function(a){Ext.apply(this,a);Ext.tree.ColumnResizer.superclass.constructor.call(this)},init:function(a){this.tree=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(a,b){var c=a.getPageX(),d=a.getTarget(".x-treegrid-hd",3,!0);if(d){var e=d.getRegion(),g=d.dom.style,f=d.dom.parentNode;if(5>=c-e.left&&d.dom!==f.firstChild){for(c=d.dom.previousSibling;c&&Ext.fly(c).hasClass("x-treegrid-hd-hidden");)c=c.previousSibling;c&&(this.activeHd=Ext.get(c),g.cursor=Ext.isWebKit?"e-resize":"col-resize")}else if(5>=e.right-c){for(c=d.dom;c&&
-Ext.fly(c).hasClass("x-treegrid-hd-hidden");)c=c.previousSibling;c&&(this.activeHd=Ext.get(c),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(a){this.dragHeadersDisabled=this.tree.headersDisabled;this.tree.headersDisabled=!0;this.proxy=this.tree.body.createChild({cls:"x-treegrid-resizer"});this.proxy.setHeight(this.tree.body.getHeight());a=this.tracker.getXY()[0];this.hdX=
-this.dragHd.getX();this.hdIndex=this.tree.findHeaderIndex(this.dragHd);this.proxy.setX(this.hdX);this.proxy.setWidth(a-this.hdX);this.maxWidth=this.tree.outerCt.getWidth()-this.tree.innerBody.translatePoints(this.hdX).left},onDrag:function(a){a=this.tracker.getXY()[0];this.proxy.setWidth((a-this.hdX).constrain(this.minWidth,this.maxWidth))},onEnd:function(a){a=this.proxy.getWidth();var b=this.tree,c=this.dragHeadersDisabled;this.proxy.remove();delete this.dragHd;b.columns[this.hdIndex].width=a;b.updateColumnWidths();
-setTimeout(function(){b.headersDisabled=c},100)}});
-(function(){Ext.override(Ext.list.Column,{init:function(){var a=Ext.data.Types,b=this.sortType;this.type?Ext.isString(this.type)&&(this.type=Ext.data.Types[this.type.toUpperCase()]||a.AUTO):this.type=a.AUTO;Ext.isString(b)?this.sortType=Ext.data.SortTypes[b]:Ext.isEmpty(b)&&(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.ux.tree.TreeGridLoader=Ext.extend(Ext.tree.TreeLoader,{createNode:function(a){a.uiProvider||(a.uiProvider=Ext.ux.tree.TreeGridNodeUI);return Ext.tree.TreeLoader.prototype.createNode.call(this,a)}});
-Ext.ux.tree.TreeGridNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:!0,renderElements:function(a,b,c,d){var e=a.getOwnerTree(),g=e.columns,f=g[0],h,k,l;this.indentMarkup=a.parentNode?a.parentNode.ui.getChildIndent():"";k=['<tbody class="x-tree-node">','<tr ext:tree-node-id="',a.id,'" class="x-tree-node-el x-tree-node-leaf ',b.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="',b.icon||this.emptyIcon,'" class="x-tree-node-icon',b.icon?" x-tree-node-inline-icon":"",b.iconCls?" "+b.iconCls:"",'" unselectable="on" />','<a hidefocus="on" class="x-tree-node-anchor" href="',b.href?b.href:"#",'" tabIndex="1" ',b.hrefTarget?' target="'+b.hrefTarget+'"':"",">",'<span unselectable="on">',f.tpl?f.tpl.apply(b):b[f.dataIndex]||f.text,"</span></a>","</td>"];h=1;for(l=g.length;h<l;h++)f=g[h],k.push('<td class="x-treegrid-col ',f.cls?f.cls:"",'">','<div unselectable="on" class="x-treegrid-text"',
-f.align?' style="text-align: '+f.align+';"':"",">",f.tpl?f.tpl.apply(b):b[f.dataIndex],"</div>","</td>");k.push('</tr><tr class="x-tree-node-ct"><td colspan="',g.length,'">','<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',e.innerCt.getWidth(),'px;"><colgroup>');h=0;for(l=g.length;h<l;h++)k.push('<col style="width: ',g[h].hidden?0:g[h].width,'px;" />');k.push("</colgroup></table></td></tr></tbody>");!0!==d&&a.nextSibling&&
-a.nextSibling.ui.getEl()?this.wrap=Ext.DomHelper.insertHtml("beforeBegin",a.nextSibling.ui.getEl(),k.join("")):this.wrap=Ext.DomHelper.insertHtml("beforeEnd",c,k.join(""));this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1].firstChild.firstChild;a=this.elNode.firstChild.childNodes;this.indentNode=a[0];this.ecNode=a[1];this.iconNode=a[2];this.anchor=a[3];this.textNode=a[3].firstChild},animExpand:function(a){this.ctNode.style.display="";Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this,
-a)}});Ext.ux.tree.TreeGridRootNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:!0,render:function(){this.rendered||(this.wrap=this.ctNode=this.node.ownerTree.innerCt.dom,this.node.expanded=!0);if(Ext.isWebKit){var a=this.ctNode;a.style.tableLayout=null;(function(){a.style.tableLayout="fixed"}).defer(1)}},destroy:function(){this.elNode&&Ext.dd.Registry.unregister(this.elNode.id);delete this.node},collapse:Ext.emptyFn,expand:Ext.emptyFn});
-Ext.override(Ext.ux.tree.TreeGridNodeUI,{updateColumns:function(){if(this.rendered){var a=this.node.attributes,b=this.node.getOwnerTree().columns,c=b[0];this.anchor.firstChild.innerHTML=c.tpl?c.tpl.apply(a):a[c.dataIndex]||c.text;i=1;for(len=b.length;i<len;i++)c=b[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(a){a.tpl=a.tpl||new Ext.XTemplate("{"+a.dataIndex+":this.format}");a.tpl.format=a.renderer;a.tpl.col=this;Ext.tree.RenderColumn.superclass.constructor.call(this,a)}});Ext.reg("tgrendercolumn",Ext.tree.RenderColumn);Ext.ns("Ext.ux.tree");
-Ext.ux.tree.TreeGridSorter=Ext.extend(Ext.tree.TreeSorter,{sortClasses:["sort-asc","sort-desc"],sortAscText:"Sort Ascending",sortDescText:"Sort Descending",constructor:function(a,b){Ext.isObject(b)||(b={property:a.columns[0].dataIndex||"text",folderSort:!0});Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this,arguments);this.tree=a;a.on("headerclick",this.onHeaderClick,this);a.ddAppendOnly=!0;var c=this;this.defaultSortFn=function(a,b){var g=c.dir&&"desc"==c.dir.toLowerCase(),f=c.property||
-"text",h=c.sortType,k=!0===c.caseSensitive,l=c.leafAttr||"leaf",u=a.attributes,p=b.attributes;if(c.folderSort){if(u[l]&&!p[l])return 1;if(!u[l]&&p[l])return-1}l=u[f];f=p[f];p=h?h(l):k?l:l.toUpperCase();v2=h?h(f):k?f:f.toUpperCase();return p<v2?g?1:-1:p>v2?g?-1:1:0};a.on("afterrender",this.onAfterTreeRender,this,{single:!0});a.on("headermenuclick",this.onHeaderMenuClick,this)},onAfterTreeRender:function(){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(a,b,c){if("asc"===b||"desc"===b)return this.onHeaderClick(a,null,c),!1},onHeaderClick:function(a,b,c){if(a&&!this.tree.headersDisabled){var d=this;d.property=a.dataIndex;d.dir=a.dir="desc"===a.dir?"asc":"desc";d.sortType=a.sortType;d.caseSensitive===Ext.isBoolean(a.caseSensitive)?a.caseSensitive:this.caseSensitive;d.sortFn=a.sortFn||this.defaultSortFn;this.tree.root.cascade(function(a){a.isLeaf()||
-d.updateSort(d.tree,a)});this.updateSortIcon(c,a.dir)}},updateSortIcon:function(a,b){var c=this.sortClasses;this.tree.innerHd.select("td").removeClass(c).item(a).addClass(c["desc"==b?1:0])}});
-Ext.ux.JSLoader=function(a){Ext.ux.JSLoader.scripts[++Ext.ux.JSLoader.index]={url:a.url,success:!0,jsLoadObj:null,options:a,onLoad:a.onLoad||Ext.emptyFn,onError:a.onError||Ext.ux.JSLoader.stdError,scope:a.scope||this};Ext.Ajax.request({url:a.url,scriptIndex:Ext.ux.JSLoader.index,success:function(a,c){var d=Ext.ux.JSLoader.scripts[c.scriptIndex];try{eval(a.responseText)}catch(e){d.success=!1,d.onError(d.options,e)}d.success&&d.onLoad.call(d.scope,d.options)},failure:function(a,c){var d=Ext.ux.JSLoader.scripts[c.scriptIndex];
-d.success=!1;d.onError(d.options,a.status)}})};Ext.ux.JSLoader.index=0;Ext.ux.JSLoader.scripts=[];Ext.ux.JSLoader.stdError=function(a,b){window.alert("Error loading script:\n\n"+a.url+"\n\nstatus: "+b)};
-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:!1,constructor:function(a){Ext.ux.Spinner.superclass.constructor.call(this,a);Ext.apply(this,a);this.mimicing=!1},init:function(a){this.field=a;a.afterMethod("onRender",this.doRender,this);a.afterMethod("onEnable",this.doEnable,this);a.afterMethod("onDisable",this.doDisable,
-this);a.afterMethod("afterRender",this.doAfterRender,this);a.afterMethod("onResize",this.doResize,this);a.afterMethod("onFocus",this.doFocus,this);a.beforeMethod("onDestroy",this.doDestroy,this)},doRender:function(a,b){var c=this.el=this.field.getEl(),d=this.field;d.wrap?this.wrap=d.wrap.addClass("x-form-field-wrap"):d.wrap=this.wrap=c.wrap({cls:"x-form-field-wrap"});this.trigger=this.wrap.createChild({tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});d.width||this.wrap.setWidth(c.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,!0);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 a;
-Ext.isIE&&this.el.getY()!=(a=this.trigger.getY())&&(this.el.position(),this.el.setY(a))},doEnable:function(){this.wrap&&(this.disabled=!1,this.wrap.removeClass(this.field.disabledClass))},doDisable:function(){this.wrap&&(this.disabled=!0,this.wrap.addClass(this.field.disabledClass),this.el.removeClass(this.field.disabledClass))},doResize:function(a,b){"number"==typeof a&&this.el.setWidth(a-this.trigger.getWidth());this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth())},doFocus:function(){this.mimicing||
-(this.wrap.addClass("x-trigger-wrap-focus"),this.mimicing=!0,Ext.get(Ext.isIE?document.body:document).on("mousedown",this.mimicBlur,this,{delay:10}),this.el.on("keydown",this.checkTab,this))},checkTab:function(a){a.getKey()==a.TAB&&this.triggerBlur()},mimicBlur:function(a){!this.wrap.contains(a.target)&&this.field.validateBlur(a)&&this.triggerBlur()},triggerBlur:function(){this.mimicing=!1;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:!0,spinup:!0,spindown:!0});this.keyNav=new Ext.KeyNav(this.el,{up:function(a){a.preventDefault();this.onSpinUp()},down:function(a){a.preventDefault();this.onSpinDown()},pageUp:function(a){a.preventDefault();this.onSpinUpAlternate()},
-pageDown:function(a){a.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:!0});this.field.mon(this.trigger,{mouseover:this.onMouseOver,mouseout:this.onMouseOut,mousemove:this.onMouseMove,mousedown:this.onMouseDown,mouseup:this.onMouseUp,scope:this,preventDefault:!0});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){var a=this.getMiddle();this.tmpHoverClass=Ext.EventObject.getPageY()<a?"x-form-spinner-overup":"x-form-spinner-overdown";this.trigger.addClass(this.tmpHoverClass)}},onMouseOut:function(){this.trigger.removeClass(this.tmpHoverClass)},onMouseMove:function(){if(!this.disabled){var a=
-this.getMiddle();Ext.EventObject.getPageY()>a&&"x-form-spinner-overup"==this.tmpHoverClass||Ext.EventObject.getPageY()}},onMouseDown:function(){if(!this.disabled){var a=this.getMiddle();this.tmpClickClass=Ext.EventObject.getPageY()<a?"x-form-spinner-clickup":"x-form-spinner-clickdown";this.trigger.addClass(this.tmpClickClass)}},onMouseUp:function(){this.trigger.removeClass(this.tmpClickClass)},onTriggerClick:function(){if(!this.disabled&&!this.el.dom.readOnly){var a=this.getMiddle();this["onSpin"+
-(Ext.EventObject.getPageY()<a?"Up":"Down")]()}},getMiddle:function(){var a=this.trigger.getTop(),b=this.trigger.getHeight();return a+b/2},isSpinnable:function(){return this.disabled||this.el.dom.readOnly?(Ext.EventObject.preventDefault(),!1):!0},handleMouseWheel:function(a){if(0!=this.wrap.hasClass("x-trigger-wrap-focus")){var b=a.getWheelDelta();0<b?(this.onSpinUp(),a.stopEvent()):0>b&&(this.onSpinDown(),a.stopEvent())}},startDrag:function(){this.proxy.show();this._previousY=Ext.fly(this.dd.getDragEl()).getTop()},
-endDrag:function(){this.proxy.hide()},onDrag:function(){if(!this.disabled){var a=Ext.fly(this.dd.getDragEl()).getTop(),b="";this._previousY>a&&(b="Up");this._previousY<a&&(b="Down");if(""!=b)this["onSpin"+b]();this._previousY=a}},onSpinUp:function(){if(0!=this.isSpinnable())if(1==Ext.EventObject.shiftKey)this.onSpinUpAlternate();else this.spin(!1,!1),this.field.fireEvent("spin",this),this.field.fireEvent("spinup",this)},onSpinDown:function(){if(0!=this.isSpinnable())if(1==Ext.EventObject.shiftKey)this.onSpinDownAlternate();
-else this.spin(!0,!1),this.field.fireEvent("spin",this),this.field.fireEvent("spindown",this)},onSpinUpAlternate:function(){0!=this.isSpinnable()&&(this.spin(!1,!0),this.field.fireEvent("spin",this),this.field.fireEvent("spinup",this))},onSpinDownAlternate:function(){0!=this.isSpinnable()&&(this.spin(!0,!0),this.field.fireEvent("spin",this),this.field.fireEvent("spindown",this))},spin:function(a,b){var c=parseFloat(this.field.getValue()),d=1==b?this.alternateIncrementValue:this.incrementValue;1==
-a?c-=d:c+=d;c=isNaN(c)?this.defaultValue:c;c=this.fixBoundries(c);this.field.setRawValue(c)},fixBoundries:function(a){void 0!=this.field.minValue&&a<this.field.minValue&&(a=this.field.minValue);void 0!=this.field.maxValue&&a>this.field.maxValue&&(a=this.field.maxValue);return this.fixPrecision(a)},fixPrecision:function(a){var b=isNaN(a);return this.field.allowDecimals&&-1!=this.field.decimalPrecision&&!b&&a?parseFloat(parseFloat(a).toFixed(this.field.decimalPrecision)):b?"":a},doDestroy:function(){this.trigger&&
-this.trigger.remove();this.wrap&&(this.wrap.remove(),delete this.field.wrap);this.splitter&&this.splitter.remove();this.dd&&(this.dd.unreg(),this.dd=null);this.proxy&&this.proxy.remove();this.repeater&&this.repeater.purgeListeners();this.mimicing&&Ext.get(Ext.isIE?document.body:document).un("mousedown",this.mimicBlur,this)}});Ext.form.Spinner=Ext.ux.Spinner;
-Ext.ux.StatusBar=Ext.extend(Ext.Toolbar,{cls:"x-statusbar",busyIconCls:"x-status-busy",busyText:"Loading...",autoClear:5E3,emptyText:"&nbsp;",activeThreadId:0,initComponent:function(){"right"==this.statusAlign&&(this.cls+=" x-status-right");Ext.ux.StatusBar.superclass.initComponent.call(this)},afterRender:function(){Ext.ux.StatusBar.superclass.afterRender.call(this);var a="right"==this.statusAlign;this.currIconCls=this.iconCls||this.defaultIconCls;this.statusEl=new Ext.Toolbar.TextItem({cls:"x-status-text "+
-(this.currIconCls||""),text:this.text||this.defaultText||""});a?(this.add("->"),this.add(this.statusEl)):(this.insert(0,this.statusEl),this.insert(1,"->"));this.doLayout()},setStatus:function(a){a=a||{};"string"==typeof a&&(a={text:a});void 0!==a.text&&this.setText(a.text);void 0!==a.iconCls&&this.setIcon(a.iconCls);if(a.clear){a=a.clear;var b=this.autoClear,c={useDefaults:!0,anim:!0};"object"==typeof a?(a=Ext.applyIf(a,c),a.wait&&(b=a.wait)):"number"==typeof a?(b=a,a=c):"boolean"==typeof a&&(a=c);
-a.threadId=this.activeThreadId;this.clearStatus.defer(b,this,[a])}return this},clearStatus:function(a){a=a||{};if(a.threadId&&a.threadId!==this.activeThreadId)return this;var b=a.useDefaults?this.defaultText:this.emptyText,c=a.useDefaults?this.defaultIconCls?this.defaultIconCls:"":"";a.anim?this.statusEl.el.fadeOut({remove:!1,useDisplay:!0,scope:this,callback:function(){this.setStatus({text:b,iconCls:c});this.statusEl.el.show()}}):(this.statusEl.hide(),this.setStatus({text:b,iconCls:c}),this.statusEl.show());
-return this},setText:function(a){this.activeThreadId++;this.text=a||"";this.rendered&&this.statusEl.setText(this.text);return this},getText:function(){return this.text},setIcon:function(a){this.activeThreadId++;a=a||"";this.rendered?(this.currIconCls&&(this.statusEl.removeClass(this.currIconCls),this.currIconCls=null),0<a.length&&(this.statusEl.addClass(a),this.currIconCls=a)):this.currIconCls=a;return this},showBusy:function(a){"string"==typeof a&&(a={text:a});a=Ext.applyIf(a||{},{text:this.busyText,
-iconCls:this.busyIconCls});return this.setStatus(a)}});Ext.reg("statusbar",Ext.ux.StatusBar);
+/*
+ * Ext.ux.layout.FormLayoutFix.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.override(Ext.layout.FormLayout,{renderItem:function(e,a,d){if(e&&!e.rendered&&(e.isFormField||e.fieldLabel)&&e.inputType!="hidden"){var b=this.getTemplateArgs(e);if(typeof a=="number"){a=d.dom.childNodes[a]||null}if(a){e.formItem=this.fieldTpl.insertBefore(a,b,true)}else{e.formItem=this.fieldTpl.append(d,b,true)}e.actionMode="formItem";e.render("x-form-el-"+e.id);e.container=e.formItem;e.actionMode="container"}else{Ext.layout.FormLayout.superclass.renderItem.apply(this,arguments)}}});
+/*
+ * 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");Ext.ux.tree.TreeGrid=Ext.extend(Ext.tree.TreePanel,{rootVisible:false,useArrows:true,lines:false,borderWidth:Ext.isBorderBox?0:2,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"})}var a=this.loader;if(!a){a=new Ext.ux.tree.TreeGridLoader({dataUrl:this.dataUrl,requestMethod:this.requestMethod,store:this.store})}else{if(Ext.isObject(a)&&!a.load){a=new Ext.ux.tree.TreeGridLoader(a)}}this.loader=a;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 b=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 e=this.columns,a=e.length,d=[],b,f;for(b=0;b<a;b++){f=e[b];if(!f.isColumn){f.xtype=f.xtype?(/^tg/.test(f.xtype)?f.xtype:"tg"+f.xtype):"tgcolumn";f=Ext.create(f)}f.init(this);d.push(f);if(this.enableSort!==false&&f.sortable!==false){f.sortable=true;this.enableSort=true}}this.columns=d},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(a){a.attributes.uiProvider=Ext.ux.tree.TreeGridRootNodeUI;a=Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this,a);if(this.innerCt){this.colgroupTpl.insertFirst(this.innerCt,{columns:this.columns})}return a},clearInnerCt:function(){if(Ext.isIE){var a=this.innerCt.dom;while(a.firstChild){a.removeChild(a.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(b,c){Ext.ux.tree.TreeGrid.superclass.onResize.apply(this,arguments);var e=this.innerBody.dom;var f=this.innerHd.dom;if(!e){return}if(Ext.isNumber(c)){e.style.height=this.body.getHeight(true)-f.offsetHeight+"px"}if(Ext.isNumber(b)){var a=Ext.num(this.scrollOffset,Ext.getScrollBarWidth());if(this.reserveScrollOffset||((e.offsetWidth-e.clientWidth)>10)){this.setScrollOffset(a)}else{var d=this;setTimeout(function(){d.setScrollOffset(e.offsetWidth-e.clientWidth>10?a:0)},10)}}},updateColumnWidths:function(){var k=this.columns,m=k.length,a=this.outerCt.query("colgroup"),l=a.length,h,e,d,b;for(d=0;d<m;d++){h=k[d];for(b=0;b<l;b++){e=a[b];e.childNodes[d].style.width=(h.hidden?0:h.width)+"px"}}for(d=0,a=this.innerHd.query("td"),len=a.length;d<len;d++){h=Ext.fly(a[d]);if(k[d]&&k[d].hidden){h.addClass("x-treegrid-hd-hidden")}else{h.removeClass("x-treegrid-hd-hidden")}}var f=this.getTotalColumnWidth();Ext.fly(this.innerHd.dom.firstChild).setWidth(f+(this.scrollOffset||0));this.outerCt.select("table").setWidth(f);this.syncHeaderScroll()},getVisibleColumns:function(){var c=[],d=this.columns,a=d.length,b;for(b=0;b<a;b++){if(!d[b].hidden){c.push(d[b])}}return c},getTotalColumnWidth:function(){var d=0;for(var b=0,c=this.getVisibleColumns(),a=c.length;b<a;b++){d+=c[b].width}return d},setScrollOffset:function(a){this.scrollOffset=a;this.updateColumnWidths()},handleHdDown:function(j,f){var h=j.getTarget(".x-treegrid-hd");if(h&&Ext.fly(f).hasClass("x-grid3-hd-btn")){var b=this.hmenu.items,g=this.columns,a=this.findHeaderIndex(h),k=g[a],d=k.sortable;j.stopEvent();Ext.fly(h).addClass("x-grid3-hd-menu-open");this.hdCtxIndex=a;this.fireEvent("headerbuttonclick",b,k,h,a);this.hmenu.on("hide",function(){Ext.fly(h).removeClass("x-grid3-hd-menu-open")},this,{single:true});this.hmenu.show(f,"tl-bl?")}else{if(h){var a=this.findHeaderIndex(h);this.fireEvent("headerclick",this.columns[a],h,a)}}},handleHdOver:function(d,a){var c=d.getTarget(".x-treegrid-hd");if(c&&!this.headersDisabled){index=this.findHeaderIndex(c);this.activeHdRef=a;this.activeHdIndex=index;var b=Ext.get(c);this.activeHdRegion=b.getRegion();b.addClass("x-grid3-hd-over");this.activeHdBtn=b.child(".x-grid3-hd-btn");if(this.activeHdBtn){this.activeHdBtn.dom.style.height=(c.firstChild.offsetHeight-1)+"px"}}},handleHdOut:function(c,a){var b=c.getTarget(".x-treegrid-hd");if(b&&(!Ext.isIE||!c.within(b,true))){this.activeHdRef=null;Ext.fly(b).removeClass("x-grid3-hd-over");b.style.cursor=""}},findHeaderIndex:function(d){d=d.dom||d;var b=d.parentNode.childNodes;for(var a=0,e;e=b[a];a++){if(e==d){return a}}return -1},beforeColMenuShow:function(){var d=this.columns,b=d.length,a,e;this.colMenu.removeAll();for(a=1;a<b;a++){e=d[a];if(e.hideable!==false){this.colMenu.add(new Ext.menu.CheckItem({itemId:"col-"+a,text:e.header,checked:!e.hidden,hideOnClick:false,disabled:e.hideable===false}))}}},handleHdMenuClick:function(b){var a=this.hdCtxIndex,c=b.getItemId();if(this.fireEvent("headermenuclick",this.columns[a],c,a)!==false){a=c.substr(4);if(a>0&&this.columns[a]){this.setColumnVisible(a,!b.checked)}}return true},setColumnVisible:function(a,b){this.columns[a].hidden=!b;this.updateColumnWidths()},scrollToTop:function(){this.innerBody.dom.scrollTop=0;this.innerBody.dom.scrollLeft=0},syncScroll:function(){this.syncHeaderScroll();var a=this.innerBody.dom;this.fireEvent("bodyscroll",a.scrollLeft,a.scrollTop)},syncHeaderScroll:function(){var a=this.innerBody.dom;this.innerHd.dom.scrollLeft=a.scrollLeft;this.innerHd.dom.scrollLeft=a.scrollLeft},registerNode:function(a){Ext.ux.tree.TreeGrid.superclass.registerNode.call(this,a);if(!a.uiProvider&&!a.isRoot&&!a.ui.isTreeGridNodeUI){a.ui=new Ext.ux.tree.TreeGridNodeUI(a)}}});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
+ */
+Ext.tree.ColumnResizer=Ext.extend(Ext.util.Observable,{minWidth:14,constructor:function(a){Ext.apply(this,a);Ext.tree.ColumnResizer.superclass.constructor.call(this)},init:function(a){this.tree=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(f,k){var g=5,j=f.getPageX(),d=f.getTarget(".x-treegrid-hd",3,true);if(d){var b=d.getRegion(),l=d.dom.style,c=d.dom.parentNode;if(j-b.left<=g&&d.dom!==c.firstChild){var a=d.dom.previousSibling;while(a&&Ext.fly(a).hasClass("x-treegrid-hd-hidden")){a=a.previousSibling}if(a){this.activeHd=Ext.get(a);l.cursor=Ext.isWebKit?"e-resize":"col-resize"}}else{if(b.right-j<=g){var h=d.dom;while(h&&Ext.fly(h).hasClass("x-treegrid-hd-hidden")){h=h.previousSibling}if(h){this.activeHd=Ext.get(h);l.cursor=Ext.isWebKit?"w-resize":"col-resize"}}else{delete this.activeHd;l.cursor=""}}}},onBeforeStart:function(a){this.dragHd=this.activeHd;return !!this.dragHd},onStart:function(b){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 a=this.tracker.getXY()[0];this.hdX=this.dragHd.getX();this.hdIndex=this.tree.findHeaderIndex(this.dragHd);this.proxy.setX(this.hdX);this.proxy.setWidth(a-this.hdX);this.maxWidth=this.tree.outerCt.getWidth()-this.tree.innerBody.translatePoints(this.hdX).left},onDrag:function(b){var a=this.tracker.getXY()[0];this.proxy.setWidth((a-this.hdX).constrain(this.minWidth,this.maxWidth))},onEnd:function(d){var b=this.proxy.getWidth(),a=this.tree,c=this.dragHeadersDisabled;this.proxy.remove();delete this.dragHd;a.columns[this.hdIndex].width=b;a.updateColumnWidths();setTimeout(function(){a.headersDisabled=c},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 b=Ext.data.Types,a=this.sortType;if(this.type){if(Ext.isString(this.type)){this.type=Ext.data.Types[this.type.toUpperCase()]||b.AUTO}}else{this.type=b.AUTO}if(Ext.isString(a)){this.sortType=Ext.data.SortTypes[a]}else{if(Ext.isEmpty(a)){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
+ */
+Ext.ux.tree.TreeGridLoader=Ext.extend(Ext.tree.TreeLoader,{createNode:function(a){if(!a.uiProvider){a.uiProvider=Ext.ux.tree.TreeGridNodeUI}return Ext.tree.TreeLoader.prototype.createNode.call(this,a)}});
+/*
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ux.tree.TreeGridNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:true,renderElements:function(d,l,h,m){var o=d.getOwnerTree(),k=o.columns,j=k[0],e,b,g;this.indentMarkup=d.parentNode?d.parentNode.ui.getChildIndent():"";b=['<tbody class="x-tree-node">','<tr ext:tree-node-id="',d.id,'" class="x-tree-node-el x-tree-node-leaf ',l.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="',l.icon||this.emptyIcon,'" class="x-tree-node-icon',(l.icon?" x-tree-node-inline-icon":""),(l.iconCls?" "+l.iconCls:""),'" unselectable="on" />','<a hidefocus="on" class="x-tree-node-anchor" href="',l.href?l.href:"#",'" tabIndex="1" ',l.hrefTarget?' target="'+l.hrefTarget+'"':"",">",'<span unselectable="on">',(j.tpl?j.tpl.apply(l):l[j.dataIndex]||j.text),"</span></a>","</td>"];for(e=1,g=k.length;e<g;e++){j=k[e];b.push('<td class="x-treegrid-col ',(j.cls?j.cls:""),'">','<div unselectable="on" class="x-treegrid-text"',(j.align?' style="text-align: '+j.align+';"':""),">",(j.tpl?j.tpl.apply(l):l[j.dataIndex]),"</div>","</td>")}b.push('</tr><tr class="x-tree-node-ct"><td colspan="',k.length,'">','<table class="x-treegrid-node-ct-table" cellpadding="0" cellspacing="0" style="table-layout: fixed; display: none; width: ',o.innerCt.getWidth(),'px;"><colgroup>');for(e=0,g=k.length;e<g;e++){b.push('<col style="width: ',(k[e].hidden?0:k[e].width),'px;" />')}b.push("</colgroup></table></td></tr></tbody>");if(m!==true&&d.nextSibling&&d.nextSibling.ui.getEl()){this.wrap=Ext.DomHelper.insertHtml("beforeBegin",d.nextSibling.ui.getEl(),b.join(""))}else{this.wrap=Ext.DomHelper.insertHtml("beforeEnd",h,b.join(""))}this.elNode=this.wrap.childNodes[0];this.ctNode=this.wrap.childNodes[1].firstChild.firstChild;var f=this.elNode.firstChild.childNodes;this.indentNode=f[0];this.ecNode=f[1];this.iconNode=f[2];this.anchor=f[3];this.textNode=f[3].firstChild},animExpand:function(a){this.ctNode.style.display="";Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this,a)}});Ext.ux.tree.TreeGridRootNodeUI=Ext.extend(Ext.tree.TreeNodeUI,{isTreeGridNodeUI:true,render:function(){if(!this.rendered){this.wrap=this.ctNode=this.node.ownerTree.innerCt.dom;this.node.expanded=true}if(Ext.isWebKit){var a=this.ctNode;a.style.tableLayout=null;(function(){a.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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.override(Ext.ux.tree.TreeGridNodeUI,{updateColumns:function(){if(!this.rendered){return}var b=this.node.attributes,d=this.node.getOwnerTree(),e=d.columns,f=e[0];this.anchor.firstChild.innerHTML=(f.tpl?f.tpl.apply(b):b[f.dataIndex]||f.text);for(i=1,len=e.length;i<len;i++){f=e[i];this.elNode.childNodes[i].firstChild.innerHTML=(f.tpl?f.tpl.apply(b):b[f.dataIndex]||f.text)}}});Ext.tree.RenderColumn=Ext.extend(Ext.tree.Column,{constructor:function(a){a.tpl=a.tpl||new Ext.XTemplate("{"+a.dataIndex+":this.format}");a.tpl.format=a.renderer;a.tpl.col=this;Ext.tree.RenderColumn.superclass.constructor.call(this,a)}});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");Ext.ux.tree.TreeGridSorter=Ext.extend(Ext.tree.TreeSorter,{sortClasses:["sort-asc","sort-desc"],sortAscText:"Sort Ascending",sortDescText:"Sort Descending",constructor:function(a,b){if(!Ext.isObject(b)){b={property:a.columns[0].dataIndex||"text",folderSort:true}}Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this,arguments);this.tree=a;a.on("headerclick",this.onHeaderClick,this);a.ddAppendOnly=true;var c=this;this.defaultSortFn=function(l,k){var j=c.dir&&c.dir.toLowerCase()=="desc",d=c.property||"text",f=c.sortType,n=c.caseSensitive===true,e=c.leafAttr||"leaf",o=l.attributes,m=k.attributes;if(c.folderSort){if(o[e]&&!m[e]){return 1}if(!o[e]&&m[e]){return -1}}var h=o[d],g=m[d],p=f?f(h):(n?h:h.toUpperCase());v2=f?f(g):(n?g:g.toUpperCase());if(p<v2){return j?+1:-1}else{if(p>v2){return j?-1:+1}else{return 0}}};a.on("afterrender",this.onAfterTreeRender,this,{single:true});a.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(d,b,a){if(b==="asc"||b==="desc"){this.onHeaderClick(d,null,a);return false}},onHeaderClick:function(e,b,a){if(e&&!this.tree.headersDisabled){var d=this;d.property=e.dataIndex;d.dir=e.dir=(e.dir==="desc"?"asc":"desc");d.sortType=e.sortType;d.caseSensitive===Ext.isBoolean(e.caseSensitive)?e.caseSensitive:this.caseSensitive;d.sortFn=e.sortFn||this.defaultSortFn;this.tree.root.cascade(function(c){if(!c.isLeaf()){d.updateSort(d.tree,c)}});this.updateSortIcon(a,e.dir)}},updateSortIcon:function(b,a){var d=this.sortClasses,c=this.tree.innerHd.select("td").removeClass(d);c.item(b).addClass(d[a=="desc"?1:0])}});
+/*
+ * 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");Ext.ux.grid.BufferView=Ext.extend(Ext.grid.GridView,{rowHeight:19,borderHeight:2,scrollDelay:100,cacheSize:20,cleanDelay:500,initTemplates:function(){Ext.ux.grid.BufferView.superclass.initTemplates.call(this);var a=this.templates;a.rowHolder=new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}"></div>');a.rowHolder.disableFormats=true;a.rowHolder.compile();a.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>");a.rowBody.disableFormats=true;a.rowBody.compile()},getStyleRowHeight:function(){return Ext.isBorderBox?(this.rowHeight+this.borderHeight):this.rowHeight},getCalculatedRowHeight:function(){return this.rowHeight+this.borderHeight},getVisibleRowCount:function(){var b=this.getCalculatedRowHeight(),a=this.scroller.dom.clientHeight;return(a<1)?0:Math.ceil(a/b)},getVisibleRows:function(){var a=this.getVisibleRowCount(),b=this.scroller.dom.scrollTop,c=(b===0?0:Math.floor(b/this.getCalculatedRowHeight())-1);return{first:Math.max(c,0),last:Math.min(c+a+2,this.ds.getCount()-1)}},doRender:function(g,k,u,a,s,A,l){var b=this.templates,f=b.cell,h=b.row,x=b.rowBody,n=s-1,t=this.getStyleRowHeight(),z=this.getVisibleRows(),d="width:"+this.getTotalWidth()+";height:"+t+"px;",D=[],w,E,v={},m={tstyle:d},q;for(var y=0,C=k.length;y<C;y++){q=k[y];w=[];var o=(y+a),e=o>=z.first&&o<=z.last;if(e){for(var B=0;B<s;B++){E=g[B];v.id=E.id;v.css=B===0?"x-grid3-cell-first ":(B==n?"x-grid3-cell-last ":"");v.attr=v.cellAttr="";v.value=E.renderer(q.data[E.name],v,q,o,B,u);v.style=E.style;if(v.value===undefined||v.value===""){v.value="&#160;"}if(q.dirty&&typeof q.modified[E.name]!=="undefined"){v.css+=" x-grid3-dirty-cell"}w[w.length]=f.apply(v)}}var F=[];if(A&&((o+1)%2===0)){F[0]="x-grid3-row-alt"}if(q.dirty){F[1]=" x-grid3-dirty-row"}m.cols=s;if(this.getRowClass){F[2]=this.getRowClass(q,o,m,u)}m.alt=F.join(" ");m.cells=w.join("");D[D.length]=!e?b.rowHolder.apply(m):(l?x.apply(m):h.apply(m))}return D.join("")},isRowRendered:function(a){var b=this.getRow(a);return b&&b.childNodes.length>0},syncScroll:function(){Ext.ux.grid.BufferView.superclass.syncScroll.apply(this,arguments);this.update()},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(d,a,b,c){Ext.ux.grid.BufferView.superclass.onRemove.apply(this,arguments);if(c!==true){this.update()}},doUpdate:function(){if(this.getVisibleRowCount()>0){var f=this.grid,b=f.colModel,h=f.store,e=this.getColumnData(),a=this.getVisibleRows(),j;for(var d=a.first;d<=a.last;d++){if(!this.isRowRendered(d)&&(j=this.getRow(d))){var c=this.doRender(e,[h.getAt(d)],h,d,b.getColumnCount(),f.stripeRows,true);j.innerHTML=c}}this.clean()}},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 b=this.getVisibleRows();b.first-=this.cacheSize;b.last+=this.cacheSize;var c=0,d=this.getRows();if(b.first<=0){c=b.last+1}for(var a=this.ds.getCount();c<a;c++){if((c<b.first||c>b.last)&&d[c].innerHTML){d[c].innerHTML=""}}}},removeTask:function(b){var a=this[b];if(a&&a.cancel){a.cancel();this[b]=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 JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+Ext.ns("Ext.ux.form");Ext.ux.form.FileUploadField=Ext.extend(Ext.form.TextField,{buttonText:"Browse...",buttonOnly:false,buttonOffset:3,readOnly:true,autoSize:Ext.emptyFn,initComponent:function(){Ext.ux.form.FileUploadField.superclass.initComponent.call(this);this.addEvents("fileselected")},onRender:function(c,a){Ext.ux.form.FileUploadField.superclass.onRender.call(this,c,a);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 b=Ext.applyIf(this.buttonCfg||{},{text:this.buttonText});this.button=new Ext.Button(Ext.apply(b,{renderTo:this.wrap,cls:"x-form-file-btn"+(b.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 a=this.fileInput.dom.value;this.setValue(a);this.fireEvent("fileselected",this,a)}})},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})},reset:function(){if(this.rendered){this.fileInput.remove();this.createFileInput();this.bindListeners()}Ext.ux.form.FileUploadField.superclass.reset.call(this)},getFileInputId:function(){return this.id+"-file"},onResize:function(a,b){Ext.ux.form.FileUploadField.superclass.onResize.call(this,a,b);this.wrap.setWidth(a);if(!this.buttonOnly){var a=this.wrap.getWidth()-this.button.getEl().getWidth()-this.buttonOffset;this.el.setWidth(a)}},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)},doDisable:function(a){this.fileInput.dom.disabled=a;this.button.setDisabled(a)},preFocus:Ext.emptyFn,alignErrorIcon:function(){this.errorIcon.alignTo(this.wrap,"tl-tr",[2,0])}});Ext.reg("fileuploadfield",Ext.ux.form.FileUploadField);Ext.form.FileUploadField=Ext.ux.form.FileUploadField;
+/*
+ * Ext.ux.form.RadioGroup.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.override(Ext.form.RadioGroup,{afterRender:function(){this.items.each(function(a){this.relayEvents(a,["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(a){if(!this.items.each){this.value=a;this.lazyValue=true;return}this.items.each(function(c){if(c.rendered){var b=(c.el.getValue()==String(a));c.el.dom.checked=b;c.el.dom.defaultChecked=b;c.wrap[b?"addClass":"removeClass"](c.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");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(c){var b=Ext.copyTo({},c,"incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass");var d=this.spinner=new Ext.ux.Spinner(b);var a=c.plugins?(Ext.isArray(c.plugins)?c.plugins.push(d):[c.plugins,d]):d;Ext.ux.form.SpinnerField.superclass.constructor.call(this,Ext.apply(c,{plugins:a}))},getResizeEl:function(){return this.wrap},getPositionEl:function(){return this.wrap},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);Ext.form.SpinnerField=Ext.ux.form.SpinnerField;
+/*
+ * Ext.ux.form.SpinnerField.js
+ *
+ * Copyright (c) Damien Churchill 2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+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 program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.ns("Ext.ux.form");Ext.ux.form.SpinnerGroup=Ext.extend(Ext.form.CheckboxGroup,{defaultType:"spinnerfield",anchor:"98%",groupCls:"x-form-spinner-group",colCfg:{},onRender:function(h,f){if(!this.el){var o={cls:this.groupCls,layout:"column",border:false,renderTo:h};var a=Ext.apply({defaultType:this.defaultType,layout:"form",border:false,labelWidth:60,defaults:{hideLabel:true,anchor:"60%"}},this.colCfg);if(this.items[0].items){Ext.apply(o,{layoutConfig:{columns:this.items.length},defaults:this.defaults,items:this.items});for(var e=0,k=this.items.length;e<k;e++){Ext.applyIf(this.items[e],a)}}else{var d,m=[];if(typeof this.columns=="string"){this.columns=this.items.length}if(!Ext.isArray(this.columns)){var j=[];for(var e=0;e<this.columns;e++){j.push((100/this.columns)*0.01)}this.columns=j}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)}m.push(b)}if(this.vertical){var q=Math.ceil(this.items.length/d),n=0;for(var e=0,k=this.items.length;e<k;e++){if(e>0&&e%q==0){n++}if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[n].items.push(this.items[e])}}else{for(var e=0,k=this.items.length;e<k;e++){var p=e%d;if(this.items[e].fieldLabel){this.items[e].hideLabel=false}m[p].items.push(this.items[e])}}Ext.apply(o,{layoutConfig:{columns:d},items:m})}this.panel=new Ext.Panel(o);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 g=this.panel.findBy(function(l){return l.isFormField},this);this.items=new Ext.util.MixedCollection();this.items.addAll(g);this.items.each(function(l){l.on("spin",this.onFieldChange,this);l.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,h,f)},onFieldChange:function(a){this.fireEvent("change",this,this.getValue())},initValue:Ext.emptyFn,getValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getValue())});return a},getRawValue:function(){var a=[this.items.getCount()];this.items.each(function(c,b){a[b]=Number(c.getRawValue())});return a},setValue:function(a){if(!this.rendered){this.value=a;this.lazyValueSet=true}else{this.items.each(function(c,b){c.setValue(a[b])})}},setRawValue:function(a){if(!this.rendered){this.rawValue=a;this.lazyRawValueSet=true}else{this.items.each(function(c,b){c.setRawValue(a[b])})}}});Ext.reg("spinnergroup",Ext.ux.form.SpinnerGroup);
+/*
+ * Ext.ux.form.ToggleField.js
+ *
+ * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the OpenSSL
+ * library.
+ * You must obey the GNU General Public License in all respects for all of
+ * the code used other than OpenSSL. If you modify file(s) with this
+ * exception, you may extend this exception to your version of the file(s),
+ * but you are not obligated to do so. If you do not wish to do so, delete
+ * this exception statement from your version. If you delete this exception
+ * statement from all source files in the program, then also delete it here.
+ */
+Ext.namespace("Ext.ux.form");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(b,a){if(!this.el){this.panel=new Ext.Panel({cls:this.groupCls,layout:"table",layoutConfig:{columns:2},border:false,renderTo:b});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,b,a)},onResize:function(a,b){this.panel.setSize(a,b);this.panel.doLayout();var c=a-this.toggle.getSize().width-25;this.input.setSize(c,b)},onToggleCheck:function(a,b){this.input.setDisabled(!b)}});Ext.reg("togglefield",Ext.ux.form.ToggleField);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(a,b){window.alert("Error loading script:\n\n"+a.url+"\n\nstatus: "+b)}
+/*
+ * Ext JS Library 3.4.0
+ * Copyright(c) 2006-2011 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
+ */
+;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(a){Ext.ux.Spinner.superclass.constructor.call(this,a);Ext.apply(this,a);this.mimicing=false},init:function(a){this.field=a;a.afterMethod("onRender",this.doRender,this);a.afterMethod("onEnable",this.doEnable,this);a.afterMethod("onDisable",this.doDisable,this);a.afterMethod("afterRender",this.doAfterRender,this);a.afterMethod("onResize",this.doResize,this);a.afterMethod("onFocus",this.doFocus,this);a.beforeMethod("onDestroy",this.doDestroy,this)},doRender:function(b,a){var c=this.el=this.field.getEl();var d=this.field;if(!d.wrap){d.wrap=this.wrap=c.wrap({cls:"x-form-field-wrap"})}else{this.wrap=d.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(!d.width){this.wrap.setWidth(c.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 a;if(Ext.isIE&&this.el.getY()!=(a=this.trigger.getY())){this.el.position();this.el.setY(a)}},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(a,b){if(typeof a=="number"){this.el.setWidth(a-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)}},checkTab:function(a){if(a.getKey()==a.TAB){this.triggerBlur()}},mimicBlur:function(a){if(!this.wrap.contains(a.target)&&this.field.validateBlur(a)){this.triggerBlur()}},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(a){a.preventDefault();this.onSpinUp()},down:function(a){a.preventDefault();this.onSpinDown()},pageUp:function(a){a.preventDefault();this.onSpinUpAlternate()},pageDown:function(a){a.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 a=this.getMiddle();this.tmpHoverClass=(Ext.EventObject.getPageY()<a)?"x-form-spinner-overup":"x-form-spinner-overdown";this.trigger.addClass(this.tmpHoverClass)},onMouseOut:function(){this.trigger.removeClass(this.tmpHoverClass)},onMouseMove:function(){if(this.disabled){return}var a=this.getMiddle();if(((Ext.EventObject.getPageY()>a)&&this.tmpHoverClass=="x-form-spinner-overup")||((Ext.EventObject.getPageY()<a)&&this.tmpHoverClass=="x-form-spinner-overdown")){}},onMouseDown:function(){if(this.disabled){return}var a=this.getMiddle();this.tmpClickClass=(Ext.EventObject.getPageY()<a)?"x-form-spinner-clickup":"x-form-spinner-clickdown";this.trigger.addClass(this.tmpClickClass)},onMouseUp:function(){this.trigger.removeClass(this.tmpClickClass)},onTriggerClick:function(){if(this.disabled||this.el.dom.readOnly){return}var b=this.getMiddle();var a=(Ext.EventObject.getPageY()<b)?"Up":"Down";this["onSpin"+a]()},getMiddle:function(){var b=this.trigger.getTop();var c=this.trigger.getHeight();var a=b+(c/2);return a},isSpinnable:function(){if(this.disabled||this.el.dom.readOnly){Ext.EventObject.preventDefault();return false}return true},handleMouseWheel:function(a){if(this.wrap.hasClass("x-trigger-wrap-focus")==false){return}var b=a.getWheelDelta();if(b>0){this.onSpinUp();a.stopEvent()}else{if(b<0){this.onSpinDown();a.stopEvent()}}},startDrag:function(){this.proxy.show();this._previousY=Ext.fly(this.dd.getDragEl()).getTop()},endDrag:function(){this.proxy.hide()},onDrag:function(){if(this.disabled){return}var b=Ext.fly(this.dd.getDragEl()).getTop();var a="";if(this._previousY>b){a="Up"}if(this._previousY<b){a="Down"}if(a!=""){this["onSpin"+a]()}this._previousY=b},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)},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)},onSpinUpAlternate:function(){if(this.isSpinnable()==false){return}this.spin(false,true);this.field.fireEvent("spin",this);this.field.fireEvent("spinup",this)},onSpinDownAlternate:function(){if(this.isSpinnable()==false){return}this.spin(true,true);this.field.fireEvent("spin",this);this.field.fireEvent("spindown",this)},spin:function(d,b){var a=parseFloat(this.field.getValue());var c=(b==true)?this.alternateIncrementValue:this.incrementValue;(d==true)?a-=c:a+=c;a=(isNaN(a))?this.defaultValue:a;a=this.fixBoundries(a);this.field.setRawValue(a)},fixBoundries:function(b){var a=b;if(this.field.minValue!=undefined&&a<this.field.minValue){a=this.field.minValue}if(this.field.maxValue!=undefined&&a>this.field.maxValue){a=this.field.maxValue}return this.fixPrecision(a)},fixPrecision:function(b){var a=isNaN(b);if(!this.field.allowDecimals||this.field.decimalPrecision==-1||a||!b){return a?"":b}return parseFloat(parseFloat(b).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)}}});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
+ */
+Ext.ux.StatusBar=Ext.extend(Ext.Toolbar,{cls:"x-statusbar",busyIconCls:"x-status-busy",busyText:"Loading...",autoClear:5000,emptyText:"&nbsp;",activeThreadId:0,initComponent:function(){if(this.statusAlign=="right"){this.cls+=" x-status-right"}Ext.ux.StatusBar.superclass.initComponent.call(this)},afterRender:function(){Ext.ux.StatusBar.superclass.afterRender.call(this);var a=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(a){this.add("->");this.add(this.statusEl)}else{this.insert(0,this.statusEl);this.insert(1,"->")}this.doLayout()},setStatus:function(d){d=d||{};if(typeof d=="string"){d={text:d}}if(d.text!==undefined){this.setText(d.text)}if(d.iconCls!==undefined){this.setIcon(d.iconCls)}if(d.clear){var e=d.clear,b=this.autoClear,a={useDefaults:true,anim:true};if(typeof e=="object"){e=Ext.applyIf(e,a);if(e.wait){b=e.wait}}else{if(typeof e=="number"){b=e;e=a}else{if(typeof e=="boolean"){e=a}}}e.threadId=this.activeThreadId;this.clearStatus.defer(b,this,[e])}return this},clearStatus:function(c){c=c||{};if(c.threadId&&c.threadId!==this.activeThreadId){return this}var b=c.useDefaults?this.defaultText:this.emptyText,a=c.useDefaults?(this.defaultIconCls?this.defaultIconCls:""):"";if(c.anim){this.statusEl.el.fadeOut({remove:false,useDisplay:true,scope:this,callback:function(){this.setStatus({text:b,iconCls:a});this.statusEl.el.show()}})}else{this.statusEl.hide();this.setStatus({text:b,iconCls:a});this.statusEl.show()}return this},setText:function(a){this.activeThreadId++;this.text=a||"";if(this.rendered){this.statusEl.setText(this.text)}return this},getText:function(){return this.text},setIcon:function(a){this.activeThreadId++;a=a||"";if(this.rendered){if(this.currIconCls){this.statusEl.removeClass(this.currIconCls);this.currIconCls=null}if(a.length>0){this.statusEl.addClass(a);this.currIconCls=a}}else{this.currIconCls=a}return this},showBusy:function(a){if(typeof a=="string"){a={text:a}}a=Ext.applyIf(a||{},{text:this.busyText,iconCls:this.busyIconCls});return this.setStatus(a)}});Ext.reg("statusbar",Ext.ux.StatusBar); \ No newline at end of file