]> git.saurik.com Git - cydia.git/commitdiff
Rename Cydia.* to MobileCydia.* and add Cydia.frappliance.
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 28 Oct 2010 09:25:18 +0000 (02:25 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 2 Nov 2010 05:56:25 +0000 (22:56 -0700)
289 files changed:
.gitignore
Cydia.app/Cydia [deleted file]
Cydia.app/Default-Portrait.png [deleted file]
Cydia.app/Default.png [deleted file]
Cydia.app/Default@2x.png [deleted file]
Cydia.app/English.lproj/Localizable.strings [deleted file]
Cydia.app/English.lproj/Sections_.strings [deleted file]
Cydia.app/French.lproj/Localizable.strings [deleted file]
Cydia.app/French.lproj/Sections.strings [deleted file]
Cydia.app/German.lproj/Localizable.strings [deleted file]
Cydia.app/German.lproj/Sections.strings [deleted file]
Cydia.app/Icon-Small-50.png [deleted file]
Cydia.app/Icon-Small.png [deleted file]
Cydia.app/Icon-Small@2x.png [deleted file]
Cydia.app/Info.plist [deleted file]
Cydia.app/Modes/DOWNGRADE.png [deleted file]
Cydia.app/Modes/INSTALL.png [deleted file]
Cydia.app/Modes/NEW_INSTALL.png [deleted symlink]
Cydia.app/Modes/PURGE.png [deleted file]
Cydia.app/Modes/REINSTALL.png [deleted file]
Cydia.app/Modes/REMOVE.png [deleted file]
Cydia.app/Modes/UPGRADE.png [deleted file]
Cydia.app/Purposes/commercial.png [deleted file]
Cydia.app/Purposes/console.png [deleted file]
Cydia.app/Purposes/daemon.png [deleted file]
Cydia.app/Purposes/extension.png [deleted file]
Cydia.app/Purposes/library.png [deleted file]
Cydia.app/Purposes/uikit.png [deleted file]
Cydia.app/Purposes/x.png [deleted file]
Cydia.app/Sections.plist [deleted file]
Cydia.app/Sections/Administration.png [deleted file]
Cydia.app/Sections/App Addons.png [deleted file]
Cydia.app/Sections/Archiving.png [deleted file]
Cydia.app/Sections/Blanks.png [deleted file]
Cydia.app/Sections/Carrier Bundles.png [deleted file]
Cydia.app/Sections/Communication.png [deleted file]
Cydia.app/Sections/Data Storage.png [deleted file]
Cydia.app/Sections/Development.png [deleted file]
Cydia.app/Sections/Dictionaries.png [deleted file]
Cydia.app/Sections/Education.png [deleted file]
Cydia.app/Sections/Entertainment.png [deleted file]
Cydia.app/Sections/Games.png [deleted file]
Cydia.app/Sections/Health and Fitness.png [deleted file]
Cydia.app/Sections/Imaging.png [deleted file]
Cydia.app/Sections/Java.png [deleted file]
Cydia.app/Sections/Keyboards.png [deleted file]
Cydia.app/Sections/Localization.png [deleted file]
Cydia.app/Sections/Messaging.png [deleted file]
Cydia.app/Sections/Multimedia.png [deleted file]
Cydia.app/Sections/Navigation.png [deleted file]
Cydia.app/Sections/Networking.png [deleted file]
Cydia.app/Sections/Packaging.png [deleted file]
Cydia.app/Sections/Planet-iPhones Mods.png [deleted file]
Cydia.app/Sections/Productivity.png [deleted file]
Cydia.app/Sections/Repositories.png [deleted file]
Cydia.app/Sections/Ringtones.png [deleted file]
Cydia.app/Sections/SBSettings Addons.png [deleted file]
Cydia.app/Sections/Scripting.png [deleted file]
Cydia.app/Sections/Security.png [deleted file]
Cydia.app/Sections/Social.png [deleted file]
Cydia.app/Sections/System.png [deleted file]
Cydia.app/Sections/Terminal Support.png [deleted file]
Cydia.app/Sections/Text Editors.png [deleted file]
Cydia.app/Sections/Themes.png [deleted file]
Cydia.app/Sections/Toys.png [deleted file]
Cydia.app/Sections/Tweaks.png [deleted file]
Cydia.app/Sections/Utilities.png [deleted file]
Cydia.app/Sections/Wallpaper.png [deleted file]
Cydia.app/Sections/WebClips.png [deleted file]
Cydia.app/Sections/Widgets.png [deleted file]
Cydia.app/Sections/X Window.png [deleted file]
Cydia.app/Sections/eBooks.png [deleted file]
Cydia.app/Sources/cy.sosiphone.com.png [deleted file]
Cydia.app/Sources/iphone.hackndev.org.png [deleted file]
Cydia.app/Sources/iphonehe.com.png [deleted file]
Cydia.app/Sources/urbanfanatics.com.png [deleted file]
Cydia.app/Sources/www.zodttd.com.png [deleted file]
Cydia.app/Test [deleted file]
Cydia.app/advanced.png [deleted file]
Cydia.app/changes.png [deleted file]
Cydia.app/changes@2x.png [deleted file]
Cydia.app/chevron@2x.png [deleted file]
Cydia.app/commercial.png [deleted file]
Cydia.app/compose.png [deleted file]
Cydia.app/configure.png [deleted file]
Cydia.app/confirm.html [deleted file]
Cydia.app/confirm.js [deleted file]
Cydia.app/console.png [deleted file]
Cydia.app/email.png [deleted file]
Cydia.app/error.html [deleted file]
Cydia.app/expanded.png [deleted file]
Cydia.app/filesystem.png [deleted file]
Cydia.app/folder.png [deleted file]
Cydia.app/folder@2x.png [deleted file]
Cydia.app/green-dn.png [deleted file]
Cydia.app/green-up.png [deleted file]
Cydia.app/home-Selected.png [deleted file]
Cydia.app/home-Selected@2x.png [deleted file]
Cydia.app/home.png [deleted file]
Cydia.app/home@2x.png [deleted file]
Cydia.app/icon-72.png [deleted file]
Cydia.app/icon.png [deleted file]
Cydia.app/icon@2x.png [deleted file]
Cydia.app/iconClassic.png [deleted file]
Cydia.app/id.png [deleted file]
Cydia.app/install.png [deleted file]
Cydia.app/install@2x.png [deleted file]
Cydia.app/installed.png [deleted file]
Cydia.app/installed@2x.png [deleted file]
Cydia.app/installing.png [deleted file]
Cydia.app/loading.html [deleted file]
Cydia.app/localize.js [deleted file]
Cydia.app/manage.html [deleted file]
Cydia.app/manage.png [deleted file]
Cydia.app/manage@2x.png [deleted file]
Cydia.app/menes/chevron.png [deleted file]
Cydia.app/menes/chevron@2x.png [deleted file]
Cydia.app/menes/indicator-c7ced5-4d4d70.gif [deleted file]
Cydia.app/menes/menes.js [deleted file]
Cydia.app/menes/style.css [deleted file]
Cydia.app/package.html [deleted file]
Cydia.app/package.js [deleted file]
Cydia.app/packages.png [deleted file]
Cydia.app/reload.png [deleted file]
Cydia.app/removing.png [deleted file]
Cydia.app/search.png [deleted file]
Cydia.app/search@2x.png [deleted file]
Cydia.app/settings.png [deleted file]
Cydia.app/signature.html [deleted file]
Cydia.app/source.png [deleted file]
Cydia.app/source@2x.png [deleted file]
Cydia.app/sources.png [deleted file]
Cydia.app/star.png [deleted file]
Cydia.app/storage.html [deleted file]
Cydia.app/storage.js [deleted file]
Cydia.app/storage.png [deleted file]
Cydia.app/trusted.png [deleted file]
Cydia.app/unknown.html [deleted file]
Cydia.app/unknown.png [deleted file]
Cydia.app/version.png [deleted file]
Cydia.app/warning.png [deleted file]
Cydia.app/web.png [deleted file]
Cydia.frappliance/English.lproj/InfoPlist.strings [new file with mode: 0644]
Cydia.frappliance/Info.plist [new file with mode: 0644]
Cydia.mm [deleted file]
CydiaAppliance.mm [new file with mode: 0644]
MobileCydia.app/Cydia [new file with mode: 0755]
MobileCydia.app/Default-Portrait.png [new file with mode: 0644]
MobileCydia.app/Default.png [new file with mode: 0644]
MobileCydia.app/Default@2x.png [new file with mode: 0644]
MobileCydia.app/English.lproj/Localizable.strings [new file with mode: 0644]
MobileCydia.app/English.lproj/Sections_.strings [new file with mode: 0644]
MobileCydia.app/French.lproj/Localizable.strings [new file with mode: 0644]
MobileCydia.app/French.lproj/Sections.strings [new file with mode: 0644]
MobileCydia.app/German.lproj/Localizable.strings [new file with mode: 0644]
MobileCydia.app/German.lproj/Sections.strings [new file with mode: 0644]
MobileCydia.app/Icon-Small-50.png [new file with mode: 0644]
MobileCydia.app/Icon-Small.png [new file with mode: 0644]
MobileCydia.app/Icon-Small@2x.png [new file with mode: 0644]
MobileCydia.app/Info.plist [new file with mode: 0644]
MobileCydia.app/Modes/DOWNGRADE.png [new file with mode: 0644]
MobileCydia.app/Modes/INSTALL.png [new file with mode: 0644]
MobileCydia.app/Modes/NEW_INSTALL.png [new symlink]
MobileCydia.app/Modes/PURGE.png [new file with mode: 0644]
MobileCydia.app/Modes/REINSTALL.png [new file with mode: 0644]
MobileCydia.app/Modes/REMOVE.png [new file with mode: 0644]
MobileCydia.app/Modes/UPGRADE.png [new file with mode: 0644]
MobileCydia.app/Purposes/commercial.png [new file with mode: 0644]
MobileCydia.app/Purposes/console.png [new file with mode: 0644]
MobileCydia.app/Purposes/daemon.png [new file with mode: 0644]
MobileCydia.app/Purposes/extension.png [new file with mode: 0644]
MobileCydia.app/Purposes/library.png [new file with mode: 0644]
MobileCydia.app/Purposes/uikit.png [new file with mode: 0644]
MobileCydia.app/Purposes/x.png [new file with mode: 0644]
MobileCydia.app/Sections.plist [new file with mode: 0644]
MobileCydia.app/Sections/Administration.png [new file with mode: 0644]
MobileCydia.app/Sections/App Addons.png [new file with mode: 0644]
MobileCydia.app/Sections/Archiving.png [new file with mode: 0644]
MobileCydia.app/Sections/Blanks.png [new file with mode: 0644]
MobileCydia.app/Sections/Carrier Bundles.png [new file with mode: 0644]
MobileCydia.app/Sections/Communication.png [new file with mode: 0644]
MobileCydia.app/Sections/Data Storage.png [new file with mode: 0644]
MobileCydia.app/Sections/Development.png [new file with mode: 0644]
MobileCydia.app/Sections/Dictionaries.png [new file with mode: 0644]
MobileCydia.app/Sections/Education.png [new file with mode: 0644]
MobileCydia.app/Sections/Entertainment.png [new file with mode: 0644]
MobileCydia.app/Sections/Games.png [new file with mode: 0644]
MobileCydia.app/Sections/Health and Fitness.png [new file with mode: 0644]
MobileCydia.app/Sections/Imaging.png [new file with mode: 0644]
MobileCydia.app/Sections/Java.png [new file with mode: 0644]
MobileCydia.app/Sections/Keyboards.png [new file with mode: 0644]
MobileCydia.app/Sections/Localization.png [new file with mode: 0644]
MobileCydia.app/Sections/Messaging.png [new file with mode: 0644]
MobileCydia.app/Sections/Multimedia.png [new file with mode: 0644]
MobileCydia.app/Sections/Navigation.png [new file with mode: 0644]
MobileCydia.app/Sections/Networking.png [new file with mode: 0644]
MobileCydia.app/Sections/Packaging.png [new file with mode: 0644]
MobileCydia.app/Sections/Planet-iPhones Mods.png [new file with mode: 0644]
MobileCydia.app/Sections/Productivity.png [new file with mode: 0644]
MobileCydia.app/Sections/Repositories.png [new file with mode: 0644]
MobileCydia.app/Sections/Ringtones.png [new file with mode: 0644]
MobileCydia.app/Sections/SBSettings Addons.png [new file with mode: 0644]
MobileCydia.app/Sections/Scripting.png [new file with mode: 0644]
MobileCydia.app/Sections/Security.png [new file with mode: 0644]
MobileCydia.app/Sections/Social.png [new file with mode: 0644]
MobileCydia.app/Sections/System.png [new file with mode: 0644]
MobileCydia.app/Sections/Terminal Support.png [new file with mode: 0644]
MobileCydia.app/Sections/Text Editors.png [new file with mode: 0644]
MobileCydia.app/Sections/Themes.png [new file with mode: 0644]
MobileCydia.app/Sections/Toys.png [new file with mode: 0644]
MobileCydia.app/Sections/Tweaks.png [new file with mode: 0644]
MobileCydia.app/Sections/Utilities.png [new file with mode: 0644]
MobileCydia.app/Sections/Wallpaper.png [new file with mode: 0644]
MobileCydia.app/Sections/WebClips.png [new file with mode: 0644]
MobileCydia.app/Sections/Widgets.png [new file with mode: 0644]
MobileCydia.app/Sections/X Window.png [new file with mode: 0644]
MobileCydia.app/Sections/eBooks.png [new file with mode: 0644]
MobileCydia.app/Sources/cy.sosiphone.com.png [new file with mode: 0644]
MobileCydia.app/Sources/iphone.hackndev.org.png [new file with mode: 0644]
MobileCydia.app/Sources/iphonehe.com.png [new file with mode: 0644]
MobileCydia.app/Sources/urbanfanatics.com.png [new file with mode: 0644]
MobileCydia.app/Sources/www.zodttd.com.png [new file with mode: 0644]
MobileCydia.app/Test [new file with mode: 0755]
MobileCydia.app/advanced.png [new file with mode: 0644]
MobileCydia.app/changes.png [new file with mode: 0644]
MobileCydia.app/changes@2x.png [new file with mode: 0644]
MobileCydia.app/chevron@2x.png [new file with mode: 0644]
MobileCydia.app/commercial.png [new file with mode: 0644]
MobileCydia.app/compose.png [new file with mode: 0644]
MobileCydia.app/configure.png [new file with mode: 0644]
MobileCydia.app/confirm.html [new file with mode: 0644]
MobileCydia.app/confirm.js [new file with mode: 0644]
MobileCydia.app/console.png [new file with mode: 0644]
MobileCydia.app/email.png [new file with mode: 0644]
MobileCydia.app/error.html [new file with mode: 0644]
MobileCydia.app/expanded.png [new file with mode: 0644]
MobileCydia.app/filesystem.png [new file with mode: 0644]
MobileCydia.app/folder.png [new file with mode: 0644]
MobileCydia.app/folder@2x.png [new file with mode: 0644]
MobileCydia.app/green-dn.png [new file with mode: 0644]
MobileCydia.app/green-up.png [new file with mode: 0644]
MobileCydia.app/home-Selected.png [new file with mode: 0644]
MobileCydia.app/home-Selected@2x.png [new file with mode: 0644]
MobileCydia.app/home.png [new file with mode: 0644]
MobileCydia.app/home@2x.png [new file with mode: 0644]
MobileCydia.app/icon-72.png [new file with mode: 0644]
MobileCydia.app/icon.png [new file with mode: 0644]
MobileCydia.app/icon@2x.png [new file with mode: 0644]
MobileCydia.app/iconClassic.png [new file with mode: 0644]
MobileCydia.app/id.png [new file with mode: 0644]
MobileCydia.app/install.png [new file with mode: 0644]
MobileCydia.app/install@2x.png [new file with mode: 0644]
MobileCydia.app/installed.png [new file with mode: 0644]
MobileCydia.app/installed@2x.png [new file with mode: 0644]
MobileCydia.app/installing.png [new file with mode: 0644]
MobileCydia.app/loading.html [new file with mode: 0644]
MobileCydia.app/localize.js [new file with mode: 0644]
MobileCydia.app/manage.html [new file with mode: 0644]
MobileCydia.app/manage.png [new file with mode: 0644]
MobileCydia.app/manage@2x.png [new file with mode: 0644]
MobileCydia.app/menes/chevron.png [new file with mode: 0644]
MobileCydia.app/menes/chevron@2x.png [new file with mode: 0644]
MobileCydia.app/menes/indicator-c7ced5-4d4d70.gif [new file with mode: 0644]
MobileCydia.app/menes/menes.js [new file with mode: 0644]
MobileCydia.app/menes/style.css [new file with mode: 0644]
MobileCydia.app/package.html [new file with mode: 0644]
MobileCydia.app/package.js [new file with mode: 0644]
MobileCydia.app/packages.png [new file with mode: 0644]
MobileCydia.app/reload.png [new file with mode: 0644]
MobileCydia.app/removing.png [new file with mode: 0644]
MobileCydia.app/search.png [new file with mode: 0644]
MobileCydia.app/search@2x.png [new file with mode: 0644]
MobileCydia.app/settings.png [new file with mode: 0644]
MobileCydia.app/signature.html [new file with mode: 0644]
MobileCydia.app/source.png [new file with mode: 0755]
MobileCydia.app/source@2x.png [new file with mode: 0755]
MobileCydia.app/sources.png [new file with mode: 0755]
MobileCydia.app/star.png [new file with mode: 0644]
MobileCydia.app/storage.html [new file with mode: 0644]
MobileCydia.app/storage.js [new file with mode: 0644]
MobileCydia.app/storage.png [new file with mode: 0644]
MobileCydia.app/trusted.png [new file with mode: 0644]
MobileCydia.app/unknown.html [new file with mode: 0644]
MobileCydia.app/unknown.png [new file with mode: 0644]
MobileCydia.app/version.png [new file with mode: 0644]
MobileCydia.app/warning.png [new file with mode: 0644]
MobileCydia.app/web.png [new file with mode: 0644]
MobileCydia.mm [new file with mode: 0644]
makefile

index 31dc3c16f69b08e1a331bf8db902e1c6c8005b2b..c1d905993a400b17192ce5ad4258b077d7093225 100644 (file)
@@ -1,5 +1,6 @@
 sysroot
 sysroot
-Cydia
+MobileCydia
+CydiaAppliance
 _
 *.deb
 .DS_Store
 _
 *.deb
 .DS_Store
diff --git a/Cydia.app/Cydia b/Cydia.app/Cydia
deleted file mode 100755 (executable)
index 3c72315..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-C=/${0}
-C=${C%/*}
-declare -a flags
-[[ :${DYLD_INSERT_LIBRARIES}: == */MobileSubstrate.dylib: ]] && flags[${#flags[@]}]=--substrate
-exec "${C:-.}"/Cydia_ "${flags[@]}" -- "$@" 2>>/tmp/cydia.log
diff --git a/Cydia.app/Default-Portrait.png b/Cydia.app/Default-Portrait.png
deleted file mode 100644 (file)
index c24b27e..0000000
Binary files a/Cydia.app/Default-Portrait.png and /dev/null differ
diff --git a/Cydia.app/Default.png b/Cydia.app/Default.png
deleted file mode 100644 (file)
index b85286b..0000000
Binary files a/Cydia.app/Default.png and /dev/null differ
diff --git a/Cydia.app/Default@2x.png b/Cydia.app/Default@2x.png
deleted file mode 100644 (file)
index abc651b..0000000
Binary files a/Cydia.app/Default@2x.png and /dev/null differ
diff --git a/Cydia.app/English.lproj/Localizable.strings b/Cydia.app/English.lproj/Localizable.strings
deleted file mode 100644 (file)
index 80ff0be..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-"ABOUT" = "About";
-"ABOUT_CYDIA" = "About Cydia Installer";
-"ACCEPT_NEW_COPY" = "Accept The New Copy";
-"ADD" = "Add";
-"ADD_ANYWAY" = "Add Anyway";
-"ADD_SOURCE" = "Add Source";
-"ADMINISTRATIVE_INFORMATION" = "Administrative Information";
-"ADVANCED_SEARCH" = "Advanced Search";
-"ALL_PACKAGES" = "All Packages";
-"APPLE" = "Apple";
-"AUTHOR" = "Author";
-"AVAILABLE_UPGRADES" = "Available Upgrades";
-"BROWSER" = "Browser";
-"BY" = "by %@";
-"CANCEL" = "Cancel";
-"CANCEL_CLEAR" = "Cancel and Clear";
-"CANCEL_OPERATION" = "Cancel Operation";
-"CANNOT_COMPLY" = "Cannot Comply";
-"CANNOT_COMPLY_EX" = "The requested modifications cannot be applied due to required dependencies or conflicts that cannot be automatically found or fixed.";
-"CANNOT_LOCATE_PACKAGE" = "Cannot Locate Package";
-"CHANGE_PACKAGE_SETTINGS" = "Change Package Settings";
-"CHANGES" = "Changes";
-"CLEAN_ARCHIVES" = "Clean Archives";
-"CLEAR" = "Clear";
-"CLOSE" = "Close";
-"CLOSE_CYDIA" = "Close Cydia (Restart)";
-"COLON_DELIMITED" = "%@: %@";
-"COMMA_DELIMITED" = "%@, %@";
-"COMING_SOON" = "Coming Soon!";
-"COMPLETE" = "Complete";
-"COMPLETE_UPGRADE" = "Complete Upgrade";
-"CONFIGURATION_UPGRADE" = "Configuration Upgrade";
-"CONFIGURATION_UPGRADE_EX" = "The following file has been changed by both the package maintainer and by you (or for you by a script).";
-"COMMERCIAL_APPLICATIONS" = "Commercial Applications";
-"CONFIRM" = "Confirm";
-"CONSOLE_PACKAGE" = "This is a console package!";
-"CONSOLE_UTILITIES_DAEMONS" = "Console Utilities & Daemons";
-"CONTINUE_QUEUING" = "Continue Queuing";
-"COUNTS_NONZERO_EX" = "So, I just counted some important-looking values, and they didn't sum to zero. This is scary. I don't know why I don't like this anymore, but I think APT was adamant this should not occur.";
-"CREDITS" = "Credits";
-"CYDIA_STORE" = "Cydia Store";
-"DATABASE" = "Database";
-"DETAILS" = "Details";
-"DEVELOPER" = "Developer";
-"DEVELOPER_EX" = "Everything, even scary internal stuff.";
-"DEVELOPERS_ONLY" = "Developers Only";
-"DISK_FREEING" = "Disk Freeing";
-"DISK_USING" = "Disk Using";
-"DONATE_USING" = "Donate using %@";
-"DONE" = "Done";
-"DOUBLE_QUOTED" = "“%@”";
-"DOWNGRADE" = "Downgrade";
-"DOWNLOADING" = "Downloading";
-"DOWNLOADING_" = "Downloading %@";
-"EDIT" = "Edit";
-"ENTER_APT_URL" = "Enter Cydia/APT URL";
-"ENTERED_BY_USER" = "Entered by User";
-"ERROR" = "Error";
-"ESSENTIAL_UPGRADE" = "Essential Upgrade";
-"ESSENTIAL_UPGRADES" = "%d Essential Upgrades";
-"ESSENTIAL_UPGRADE_EX" = "One or more essential packages are currently out of date. If these upgrades are not performed you are likely to encounter errors.";
-"EXCLAMATION" = "%@!";
-"EXPANDED_SIZE" = "Expanded Size";
-"EXPERT" = "Expert";
-"FEATURED_PACKAGES" = "Featured Packages";
-"FAQ" = "FAQ";
-"FILES" = "Files";
-"FILES_INSTALLED_TO" = "files installed to %@";
-"FILESYSTEM_CONTENT" = "Filesystem Content";
-"FOLLOW_ON_TWITTER" = "Follow %@ on Twitter";
-"FORCE_REMOVAL" = "Force Removal";
-"FORCIBLY_CLEAR" = "Forcibly Clear";
-"FREE_APPLICATIONS" = "Free Applications";
-"FREE_EXTENSIONS" = "Free Extensions";
-"FREQUENTLY_ASKED_QUESTIONS" = "Frequently Asked Questions";
-"FROM" = "from %@";
-"FROWNY_PANTS" = "Frowny Pants";
-"FUTURE_FEATURE_ROADMAP" = "Future Feature Roadmap";
-"HACKER" = "Hacker";
-"HACKER_EX" = "Adds Command Line tools.";
-"HALFINSTALLED_PACKAGE" = "Half-Installed Package";
-"HALFINSTALLED_PACKAGES" = "%d Half-Installed Packages";
-"HALFINSTALLED_PACKAGE_EX" = "When the shell scripts associated with packages fail, they are left in a bad state known as either half-configured or half-installed. These errors don't go away and instead continue to cause issues. These scripts can be deleted and the packages forcibly removed.";
-"HOME" = "Home";
-"ID" = "ID";
-"IGNORE_UPGRADES" = "Ignore Upgrades";
-"IGNORED_UPGRADES" = "Ignored Upgrades";
-"ILLEGAL_PACKAGE_IDENTIFIER" = "Illegal Package Identifier";
-"INSTALL" = "Install";
-"INSTALLED" = "Installed";
-"INSTALLED_BY_PACKAGE" = "Installed by Package";
-"INSTALLED_DETAILS" = "Installed Package";
-"INSTALLED_FILES" = "Installed Files";
-"KEEP_OLD_COPY" = "Keep My Old Copy";
-"LOADING" = "Loading";
-"LOADING_DATA" = "Loading Data";
-"LOCAL" = "Local";
-"LOGIN" = "Login";
-"MAILING_LISTS" = "Mailing Lists";
-"MAINTAINER" = "Contact";
-"MANAGE" = "Manage";
-"MODIFICATIONS" = "Modifications";
-"MODIFY" = "Modify";
-"MORE_INFORMATION" = "More Information";
-"MORE_PACKAGE_SOURCES" = "More Package Sources";
-"NAME" = "Name";
-"NETWORK_ERROR" = "Network Error";
-"NEVER_OR_UNKNOWN" = "Never or Unknown";
-"NEW" = "New";
-"NEW_AT" = "New at %@";
-"NEW_INSTALL" = "New Install";
-"NO" = "No";
-"NO_SECTION" = "(No Section)";
-"NOT_RATED" = "Not Rated";
-"NOTE" = "Note";
-"NOT_REPOSITORY" = "Did not Find Repository";
-"NOT_REPOSITORY_EX" = "The indicated repository could not be found. This could be because you are trying to add a legacy Installer repository (these are not supported). Also, this interface is only capable of working with exact repository URLs. If you host a repository and are having issues please contact the author of Cydia with any questions you have.";
-"OK" = "OK";
-"OKAY" = "Okay";
-"PACKAGE_CANNOT_BE_FOUND" = "The package %@ cannot be found in your current sources. I might recommend installing more sources.";
-"PACKAGE_CANNOT_BE_FOUND_EX" = "This issue may also be caused by a number of other factors. The most common one is that your package catalog is out of date. To manually refresh, click the Refresh button on the Changes tab. This package may simply no longer exist. It is also possible you are using an old firmware version: users should attempt to remain reasonably up to date with Apple's firmware releases.";
-"PACKAGE_DAMAGED" = "Package Damaged";
-"PACKAGE_DETAILS" = "Package Details";
-"PACKAGE_QUEUE" = "Package Queue";
-"PACKAGES" = "Packages";
-"PACKAGES_EX" = "View or remove packages you previously installed.";
-"PARENTHETICAL" = "%@ (%@)";
-"PASSWORD" = "password";
-"PERFORM_SELECTIONS" = "Perform Selections";
-"PREPARE_ARCHIVES" = "Prepare Archives";
-"PRODUCTS" = "Products";
-"PURGE" = "Purge";
-"Q_D" = "Q'd";
-"QUEUED_FOR" = "Queued for %@";
-"QUESTION" = "%@?";
-"REBOOT_DEVICE" = "Reboot Device";
-"RECENT_CHANGES_UPDATES" = "Recent Changes/Updates";
-"RECOMMENDED_BOOKS" = "Recommended Books";
-"REFRESH" = "Refresh";
-"REFRESHING_DATA" = "Refreshing Data";
-"REINSTALL" = "Reinstall";
-"RELOAD" = "Reload";
-"RELOAD_SPRINGBOARD" = "Reload SpringBoard";
-"RELOADING_DATA" = "Reloading Data";
-"REMOVE" = "Remove";
-"REMOVING_ESSENTIALS" = "Removing Essentials";
-"REMOVING_ESSENTIALS_EX" = "This operation involves the removal of one or more packages that are required for the continued operation of either Cydia or iPhoneOS. If you continue, you may not be able to use Cydia to repair any damage.";
-"REPAIRING" = "Repairing";
-"REPOSITORY_SIGNATURE" = "View Repository Signature";
-"REQUEST_ADVERTISING_SPACE" = "Request Advertising Space";
-"REQUIREMENTS_FOR_LISTING" = "Requirements for Listing";
-"RESTART_SPRINGBOARD" = "Restart SpringBoard";
-"RESUBMIT_FORM" = "Are you sure you want to submit this form again?";
-"RESUMING_AT" = "Resuming At";
-"RETURN_TO_CYDIA" = "Return to Cydia";
-"ROLE_EX" = "Not all of the packages available via Cydia are designed to be used by all users. Please categorize yourself so that Cydia can apply helpful filters.\n\nThis choice can be changed from \"Settings\" under the \"Manage\" tab (on the iPhone or iPod touch), or the \"Sources\" tab (on the iPad).";
-"RUNNING" = "Running";
-"SAFE" = "Safe";
-"SAMPLE" = "Sample";
-"SCREENSHOT" = "Screenshot";
-"SCREENSHOTS" = "Screenshots";
-"SEARCH" = "Search";
-"SEARCH_EX" = "Package Names & Descriptions";
-"SECTION" = "Section";
-"SECTION_VISIBILITY" = "Section Visibility";
-"SECTIONS" = "Sections";
-"SEE_WHAT_CHANGED" = "See What Changed";
-"SETTINGS" = "Settings";
-"SHOW_ALL_CHANGES" = "Show All Changes";
-"SHOW_ALL_CHANGES_EX" = "Changes only shows upgrades to installed packages so as to minimize spam from packagers. Activate this to see upgrades to this package even when it is not installed.";
-"SIGNED_PACKAGE" = "This package has been signed.";
-"SIMPLE" = "Simple";
-"SINGLE_QUOTED" = "‘%@’";
-"SLASH_DELIMITED" = "%@ / %@";
-"SOURCE_DETAILS" = "Source Information";
-"SOURCE_WARNING" = "Source Warning";
-"SOURCES" = "Sources";
-"SOURCES_EX" = "List current sources and add custom ones you may know.";
-"SPONSOR" = "Sponsor";
-"SPONSORING_PRODUCTS" = "Sponsoring Products";
-"STATISTICS" = "Statistics";
-"STILL_BROKEN_EX" = "Trying to fix the broken selections did not seem to help.";
-"STORAGE" = "Storage";
-"STORAGE_EX" = "See how much room you have left for new packages.";
-"SUBMIT" = "Submit";
-"SUPPORT_KNOWN_ISSUES" = "Support & Known Issues";
-"TEMPORARY_IGNORE" = "Ignore (Temporary)";
-"THANK_YOU" = "Thank You";
-"QUEUE" = "Queue";
-"UNABLE_TO_COMPLY" = "Unable to Comply";
-"UNABLE_TO_COMPLY_EX" = "This operation requires the removal of one or more packages that are required for the continued operation of either Cydia or iPhoneOS. In order to continue and force this operation you will need to be activate the Advanced mode under to continue and force this operation you will need to be activate the Advanced mode under Settings.";
-"UNABLE_TO_LOAD" = "Unable to Load";
-"UNKNOWN" = "Unknown";
-"UNSAFE" = "Unsafe";
-"UPDATING_DATABASE" = "Updating Database";
-"UPDATING_SOURCES" = "Updating Sources";
-"UPGRADE" = "Upgrade";
-"UPGRADE_ESSENTIAL" = "Upgrade Essential";
-"UPGRADING_TO_READ_THIS" = "Upgrading to %@? Read This";
-"USER" = "User";
-"USER_EX" = "Apps, Tweaks, and Themes.";
-"USER_GUIDES" = "User Guides";
-"USERNAME" = "username";
-"VERIFICATION_ERROR" = "Verification Error";
-"VERIFYING_URL" = "Verifying URL";
-"VERSION" = "Version";
-"WARNING" = "Warning";
-"WELCOME_TO_CYDIA" = "Welcome to Cydia™";
-"WHO_ARE_YOU" = "Who Are You?";
-"YES" = "Yes";
diff --git a/Cydia.app/English.lproj/Sections_.strings b/Cydia.app/English.lproj/Sections_.strings
deleted file mode 100644 (file)
index 9cc7ba1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-"Administration" = "";
-"App Addons" = "";
-"Archiving" = "";
-"Battery" = "";
-"Carrier Bundles" = "";
-"Carriers" = "";
-"Complete" = "";
-"Data Storage" = "";
-"Development" = "";
-"Dialer" = "";
-"Dictionaries" = "";
-"Dock" = "";
-"eBooks" = "";
-"Education" = "";
-"Emulation" = "";
-"Entertainment" = "";
-"Games" = "";
-"Icy" = "";
-"Java" = "";
-"Keyboards" = "";
-"Localization" = "";
-"LockScreen" = "";
-"Messaging" = "";
-"Multimedia" = "";
-"Networking" = "";
-"Notifications" = "";
-"Packaging" = "";
-"Productivity" = "";
-"Repositories" = "";
-"Ringtones" = "";
-"Scripting" = "";
-"Security" = "";
-"Sliders" = "";
-"SMS" = "";
-"System" = "";
-"Terminal Support" = "";
-"Text Editors" = "";
-"Themes" = "";
-"Toys" = "";
-"Tweaks" = "";
-"Utilities" = "";
-"Wallpaper" = "";
-"Weather" = "";
-"WebClips" = "";
-"Widgets" = "";
diff --git a/Cydia.app/French.lproj/Localizable.strings b/Cydia.app/French.lproj/Localizable.strings
deleted file mode 100644 (file)
index bdd6988..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-"ABOUT" = "À propos";
-"ABOUT_CYDIA" = "À propos de Cydia";
-"ACCEPT_NEW_COPY" = "Accepter la nouvelle version";
-"ADD" = "Ajouter";
-"ADD_ANYWAY" = "Ajouter quand même";
-"ADD_SOURCE" = "Ajouter la source";
-"ADMINISTRATIVE_INFORMATION" = "Information administrative";
-"ADVANCED_SEARCH" = "Recherche avancée";
-"ALL_PACKAGES" = "Tous les paquets";
-"APPLE" = "Apple";
-"AUTHOR" = "Auteur";
-"AVAILABLE_UPGRADES" = "Mises à jour disponibles";
-"BROWSER" = "Navigateur";
-"BY" = "par %@";
-"CANCEL" = "Annuler";
-"CANCEL_CLEAR" = "Annuler et vider la file";
-"CANCEL_OPERATION" = "Annuler l'opération";
-"CANNOT_COMPLY" = "Impossible";
-"CANNOT_COMPLY_EX" = "Les modifications demandées ne peuvent pas être appliquées à cause de dépendances ou de conflits impossibles à identifier automatiquement.";
-"CANNOT_LOCATE_PACKAGE" = "Impossible de trouver le paquet";
-"CHANGE_PACKAGE_SETTINGS" = "Changer les réglages du paquet";
-"CHANGES" = "Nouveautés";
-"CLEAN_ARCHIVES" = "Nettoyer les archives";
-"CLEAR" = "Nettoyer";
-"CLOSE" = "Fermer";
-"CLOSE_CYDIA" = "Quitter Cydia (Redémarrer)";
-"COLON_DELIMITED" = "%@ : %@";
-"COMMA_DELIMITED" = "%@, %@";
-"COMING_SOON" = "À venir!";
-"COMPLETE" = "Effectué";
-"COMPLETE_UPGRADE" = "Mise à Jour effectuée";
-"CONFIGURATION_UPGRADE" = "Configuration de la mise à jour";
-"CONFIGURATION_UPGRADE_EX" = "Le(s) fichier(s) suivant(s) ont été modifiés par le responsable de ce paquet et par vous (ou pour vous par un script).";
-"COMMERCIAL_APPLICATIONS" = "Applications commerciales";
-"CONFIRM" = "Confirmer";
-"CONSOLE_PACKAGE" = "Ceci est un paquet console!";
-"CONSOLE_UTILITIES_DAEMONS" = "Utilitaires de terminal & daemons";
-"CONTINUE_QUEUING" = "Mettre dans la file d'attente";
-"COUNTS_NONZERO_EX" = "Après avoir calculé la somme de valeurs importantes, elle n'est pas égale à zéro. Ceci est épeurant. J'ai aucune idée pourquoi ceci est dangereux, mais je crois que APT ne voulait absolument pas que ceci arrive.";
-"CREDITS" = "Crédits";
-"CYDIA_STORE" = "Cydia Store";
-"DATABASE" = "Base de données";
-"DETAILS" = "Détails";
-"DEVELOPER" = "Développeur";
-"DEVELOPER_EX" = "Aucun filtre";
-"DEVELOPERS_ONLY" = "Développeurs seulement";
-"DISK_FREEING" = "Espace disque libéré";
-"DISK_USING" = "Espace disque utilisé";
-"DONATE_USING" = "Donnez en utilisant %@";
-"DONE" = "OK";
-"DOUBLE_QUOTED" = "« $@ »";
-"DOWNGRADE" = "Rétrograder";
-"DOWNLOADING" = "Télécharger";
-"DOWNLOADING_" = "Téléchargement de %@ en cours";
-"EDIT" = "Modifier";
-"ENTER_APT_URL" = "Entrez une adresse Cydia/APT";
-"ENTERED_BY_USER" = "Entré par l'utilisateur";
-"ERROR" = "Erreur";
-"ESSENTIAL_UPGRADE" = "Mise à jour essentielle";
-"ESSENTIAL_UPGRADES" = "%d mises à jour essentielles";
-"ESSENTIAL_UPGRADE_EX" = "Un ou plusieurs paquets essentiels sont périmés. Si vous ne les mettez pas à jour, vous pourriez rencontrer des erreurs.";
-"EXCLAMATION" = "%@ !";
-"EXPANDED_SIZE" = "Taille décompressée";
-"EXPERT" = "Expert";
-"FEATURED_PACKAGES" = "Paquets conseillés";
-"FAQ" = "FAQ";
-"FILES" = "Fichiers";
-"FILES_INSTALLED_TO" = "fichiers installés dans %@";
-"FILESYSTEM_CONTENT" = "Contenu";
-"FOLLOW_ON_TWITTER" = "Suivez %@ sur Twitter";
-"FORCE_REMOVAL" = "Forcer la suppression";
-"FORCIBLY_CLEAR" = "Forcer le nettoyage";
-"FREE_APPLICATIONS" = "Applications gratuites";
-"FREE_EXTENSIONS" = "Extensions gratuites";
-"FREQUENTLY_ASKED_QUESTIONS" = "Foire aux questions";
-"FROM" = "de %@";
-"FROWNY_PANTS" = "Pantalon fronçant";
-"FUTURE_FEATURE_ROADMAP" = "Feuille de route des mises à jour";
-"HACKER" = "Hacker";
-"HACKER_EX" = "+ CLI";
-"HALFINSTALLED_PACKAGE" = "Paquet à moitié installé";
-"HALFINSTALLED_PACKAGES" = "%d paquets à moitié installés";
-"HALFINSTALLED_PACKAGE_EX" = "Quand les scripts du paquet ne fonctionnent pas, ils laissent le paquet à moitié installé et à moitié configuré. Ces erreurs ne disparaissent pas et vont continuer à causer des problèmes. Ces scripts peuvent être supprimés et les paquets frocément désinstallés.";
-"HOME" = "Accueil";
-"ID" = "ID";
-"IGNORE_UPGRADES" = "Ignorer les mises à jour";
-"IGNORED_UPGRADES" = "Mises à jour ignorées";
-"ILLEGAL_PACKAGE_IDENTIFIER" = "Identifiant du paquet illégal";
-"INSTALL" = "Installer";
-"INSTALLED" = "Installé";
-"INSTALLED_BY_PACKAGE" = "Installer par paquet";
-"INSTALLED_DETAILS" = "Paquet installé";
-"INSTALLED_FILES" = "Fichiers installés";
-"KEEP_OLD_COPY" = "Garder ma vieille copie";
-"LOADING" = "Chargement";
-"LOADING_DATA" = "Chargement des données";
-"LOCAL" = "Local";
-"LOGIN" = "S'identifier";
-"MAILING_LISTS" = "Listes de diffusion";
-"MAINTAINER" = "Contacter";
-"MANAGE" = "Gérer";
-"MODIFY" = "Modifier";
-"MODIFICATIONS" = "Modifications";
-"MORE_INFORMATION" = "Plus d'information";
-"MORE_PACKAGE_SOURCES" = "Plus de sources de paquets";
-"NAME" = "Nom";
-"NETWORK_ERROR" = "Erreur réseau";
-"NEVER_OR_UNKNOWN" = "Jamais ou inconnnu";
-"NEW" = "Nouveau";
-"NEW_AT" = "Nouveau à %@";
-"NEW_INSTALL" = "Nouvelle installation";
-"NO" = "Non";
-"NO_SECTION" = "(Pas de catégorie)";
-"NOT_RATED" = "Pas de cote";
-"NOTE" = "Note";
-"NOT_REPOSITORY" = "Impossible de trouver cette source";
-"NOT_REPOSITORY_EX" = "La source de paquets ne peut pas être trouvée. Ce pourrait être car c'est une source d'Installer (qui ne fonctionne pas avec Cydia). Cydia ne peut fonctionner qu'avec des adresses rigoureusement exactes. Si vous hébergez une source de paquets, contactez l'auteur de Cydia à propos de ces erreurs.";
-"OK" = "OK";
-"OKAY" = "OK";
-"PACKAGE_CANNOT_BE_FOUND" = "Le paquet %@ est introuvable dans vos sources actuelles. Je vous recommande d'ajouter de nouvelles sources.";
-"PACKAGE_CANNOT_BE_FOUND_EX" = "Ce problème peut aussi être causé par plusieurs autres facteurs. Le plus commun est que votre catalogue de paquets est périmé. Pour rafraîchir manuellement, utilisez le bouton Rafraîchir dans l'onglet Nouveautés. Le paquet pour simplement ne plus exister. Il est aussi posible que vous utilisez un vieux firmware; les utilisateurs devraient essayer de rester raisonnablement à date avec les sorties de firmware de Apple.";
-"PACKAGE_DAMAGED" = "Paquet abimé";
-"PACKAGE_DETAILS" = "Détails du paquet";
-"PACKAGE_QUEUE" = "File d'attente de paquets";
-"PACKAGES" = "Paquets";
-"PACKAGES_EX" = "Voir ou supprimer des paquets précédemment installés.";
-"PARENTHETICAL" = "%@ (%@)";
-"PASSWORD" = "mot de passe";
-"PERFORM_SELECTIONS" = "Performer des sélections";
-"PREPARE_ARCHIVES" = "Préparer les archives";
-"PRODUCTS" = "Produits";
-"PURGE" = "Purger";
-"Q_D" = "File";
-"QUEUED_FOR" = "File d'attente pour %@";
-"QUESTION" = "%@ ?";
-"REBOOT_DEVICE" = "Redémarrer l'appareil";
-"RECENT_CHANGES_UPDATES" = "Mises à jour ou changements récents";
-"RECOMMENDED_BOOKS" = "Livres recommandés";
-"REFRESH" = "Rafraîchir";
-"REFRESHING_DATA" = "Rafraîchissement de données";
-"REINSTALL" = "Réinstaller";
-"RELOAD" = "Recharger";
-"RELOAD_SPRINGBOARD" = "Relancer SpringBoard";
-"RELOADING_DATA" = "Rechargement des données";
-"REMOVE" = "Supprimer";
-"REMOVING_ESSENTIALS" = "Suppression d'essentiels";
-"REMOVING_ESSENTIALS_EX" = "Cette opération va supprimer un ou plusieurs paquets indispensables au bon fonctionnement de Cydia ou de votre iPhone. Si vous continuez, vous pourriez bien ne pas pouvoir utiliser Cydia pour réparer les dommages causés.";
-"REPAIRING" = "Réparation";
-"REPOSITORY_SIGNATURE" = "Voir la Signature de la Source";
-"REQUEST_ADVERTISING_SPACE" = "Demander un Espace de Publicité";
-"REQUIREMENTS_FOR_LISTING" = "Prérequis pour le Listage";
-"RESTART_SPRINGBOARD" = "Relancer le SpringBoard";
-"RESUBMIT_FORM" = "Êtes-vous certain(e) de vouloir envoyer ce formulaire à nouveau?";
-"RESUMING_AT" = "Reprise à";
-"RETURN_TO_CYDIA" = "Retour à Cydia";
-"ROLE_EX" = "Certains des paquets disponibles sur Cydia ne sont pas destinés à tous les utilisateurs. Choisissez votre catégorie pour que Cydia ne vous propose que ceux dont vous auriez besoin.\n\nCe choix peut être changé dans les \"Réglages\" du menu \"Gestion\".";
-"RUNNING" = "En Fonction";
-"SAFE" = "Sûr";
-"SAMPLE" = "Échantillon";
-"SCREENSHOT" = "Capture d'écran";
-"SCREENSHOTS" = "Captures d'écran";
-"SEARCH" = "Recherche";
-"SEARCH_EX" = "Noms des paquets & descriptions";
-"SECTION" = "Catégorie";
-"SECTION_VISIBILITY" = "Visibilité des catégories";
-"SECTIONS" = "Catégories";
-"SEE_WHAT_CHANGED" = "Voyez ce qui a changé";
-"SETTINGS" = "Réglages";
-"SHOW_ALL_CHANGES" = "Montrer tous les changements";
-"SHOW_ALL_CHANGES_EX" = "Seuls les mises à jour de paquets installés ne sont affichés ici pour limiter le spam des empaqueteurs. En activant ceci vous serez averti des mises à jour sans que ce paquet soit installé.";
-"SIGNED_PACKAGE" = "Ce paquet est signé.";
-"SIMPLE" = "Simple";
-"SINGLE_QUOTED" = "‹ %@ ›";
-"SLASH_DELIMITED" = "%@ / %@";
-"SOURCE_DETAILS" = "Détails sur la source";
-"SOURCE_WARNING" = "Avertissement de source";
-"SOURCES" = "Sources";
-"SOURCES_EX" = "Voyez vos sources et en ajoutez des nouvelles.";
-"SPONSOR" = "Commanditaire";
-"SPONSORING_PRODUCTS" = "Produits commanditants";
-"STATISTICS" = "Statistiques";
-"STILL_BROKEN_EX" = "Même après avoir essayé de réparé les sélections, le problème n'a pas l'air à être réglé.";
-"STORAGE" = "Stockage";
-"STORAGE_EX" = "Voyez combien d'espace il vous reste pour de nouveaux paquets.";
-"SUBMIT" = "Envoyer";
-"SUPPORT_KNOWN_ISSUES" = "Aide & problèmes connus";
-"TEMPORARY_IGNORE" = "Ignorer (temporairement)";
-"THANK_YOU" = "Remerciements";
-"QUEUE" = "File d'attente";
-"UNABLE_TO_COMPLY" = "Impossible";
-"UNABLE_TO_COMPLY_EX" = "Cette opération va supprimer un ou plusieurs paquets indispensables au bon fonctionnement de Cydia ou de votre iPhone. Pour continuer et forcer cette opération, vous devez activer le mode Utilisateur avancé dans les Réglages.";
-"UNABLE_TO_LOAD" = "Chargement impossible";
-"UNKNOWN" = "Inconnu";
-"UNSAFE" = "Risqué";
-"UPDATING_DATABASE" = "Mise à jour de la base de données";
-"UPDATING_SOURCES" = "Mise à jour des sources";
-"UPGRADE" = "Mise à jour";
-"UPGRADE_ESSENTIAL" = "Mise à jour des essentiels";
-"UPGRADING_TO_READ_THIS" = "À lire: mise à jour à %@";
-"USER" = "Utilisateur";
-"USER_EX" = "GUI seulement";
-"USER_GUIDES" = "Guides utilisateur";
-"USERNAME" = "Nom d'utilisateur";
-"VERIFICATION_ERROR" = "Erreur de vérification";
-"VERIFYING_URL" = "Vérification de l'URL";
-"VERSION" = "Version";
-"WARNING" = "Avertissement";
-"WELCOME_TO_CYDIA" = "Bienvenue dans Cydia™";
-"WHO_ARE_YOU" = "Qui êtes-vous?";
-"YES" = "Oui";
diff --git a/Cydia.app/French.lproj/Sections.strings b/Cydia.app/French.lproj/Sections.strings
deleted file mode 100644 (file)
index 799a82c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-"Administration" = "Administration";
-"App Addons" = "Ajouts aux applications";
-"Archiving" = "Archivage";
-"Battery" = "Batterie";
-"Carrier Bundles" = "Opérateurs";
-"Carriers" = "Opérateurs";
-"Complete" = "Terminé";
-"Data Storage" = "Archivage de données";
-"Development" = "Développement";
-"Dialer" = "Numéroteur";
-"Dictionaries" = "Dictionnaires";
-"Dock" = "Dock";
-"eBooks" = "eLivres";
-"Education" = "Éducation";
-"Emulation" = "Émulation";
-"Entertainment" = "Divertissement";
-"Games" = "Jeux";
-"Icy" = "Icy";
-"Java" = "Java";
-"Keyboards" = "Claviers";
-"Localization" = "Localisation";
-"LockScreen" = "Écran de verrouillage";
-"Messaging" = "Messagerie";
-"Multimedia" = "Multimédia";
-"Networking" = "Réseau";
-"Notifications" = "Notifications";
-"Packaging" = "Enpaquetage";
-"Productivity" = "Productivité";
-"Repositories" = "Sources";
-"Ringtones" = "Sonneries";
-"Scripting" = "Scripts";
-"Security" = "Sécurité";
-"Sliders" = "Sliders";
-"SMS" = "SMS";
-"System" = "Système";
-"Terminal Support" = "Aide au terminal";
-"Text Editors" = "Éditeurs de texte";
-"Themes" = "Thèmes";
-"Toys" = "Jouets";
-"Tweaks" = "Modifications";
-"Utilities" = "Utilitaires";
-"Wallpaper" = "Fonds d'écran";
-"Weather" = "Météo";
-"WebClips" = "WebClips";
-"Widgets" = "Widgets";
diff --git a/Cydia.app/German.lproj/Localizable.strings b/Cydia.app/German.lproj/Localizable.strings
deleted file mode 100644 (file)
index 78a818c..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-"ABOUT" = "Über";
-"ABOUT_CYDIA" = "Über Cydia Installer";
-"ACCEPT_NEW_COPY" = "Die neue Kopie annehmen";
-"ADD" = "Hinzufügen";
-"ADD_ANYWAY" = "Trotzdem hinzufügen";
-"ADD_SOURCE" = "Quelle hinzufügen";
-"ADMINISTRATIVE_INFORMATION" = "Administrative Information";
-"ADVANCED_SEARCH" = "Erweiterte Suche";
-"ALL_PACKAGES" = "Alle Pakete";
-"APPLE" = "Apple";
-"AUTHOR" = "Autor";
-"AVAILABLE_UPGRADES" = "Vorhandene Aktualisierungen";
-"BROWSER" = "Browser";
-"BY" = "von %@";
-"CANCEL" = "Abbrechen";
-"CANCEL_CLEAR" = "Abbrechen und leeren";
-"CANCEL_OPERATION" = "Vorgang abbrechen";
-"CANNOT_COMPLY" = "Ausführung unmöglich";
-"CANNOT_COMPLY_EX" = "Die gewünschten Änderungen können wegen notwendiger Abhängigkeiten oder Konflikten, die nicht automatisch behoben werden können, nicht durchgeführt werden.";
-"CANNOT_LOCATE_PACKAGE" = "Paket nicht gefunden";
-"CHANGE_PACKAGE_SETTINGS" = "Paket-Einstellungen ändern";
-"CHANGES" = "Änderungen";
-"CLEAN_ARCHIVES" = "Archive aufräumen";
-"CLEAR" = "Leeren";
-"CLOSE" = "Schließen";
-"CLOSE_CYDIA" = "Cydia beenden (neustarten)";
-"COLON_DELIMITED" = "%@: %@";
-"COMMA_DELIMITED" = "%@, %@";
-"COMING_SOON" = "Bald verfügbar!";
-"COMPLETE" = "Fertig";
-"COMPLETE_UPGRADE" = "Vollständige Aktualisierung";
-"CONFIGURATION_UPGRADE" = "Konfiguration wählen";
-"CONFIGURATION_UPGRADE_EX" = "Die folgende Datei wurde sowohl durch den Paket-Inhaber als auch von Ihnen (oder für Sie von einem Skript) geändert.";
-"COMMERCIAL_APPLICATIONS" = "Kommerzielle Programme";
-"CONFIRM" = "Bestätigen";
-"CONSOLE_PACKAGE" = "Dies ist ein Konsolen-Paket!";
-"CONSOLE_UTILITIES_DAEMONS" = "Konsolentools & Hintergrundprozesse";
-"CONTINUE_QUEUING" = "Weiter auswählen";
-"COUNTS_NONZERO_EX" = "So, ich habe gerade ein paar wichtig scheinende Werte gezählt, und ihre Summe war nicht null. Das ist beängstigend. Ich weiß nicht mehr, warum ich das nicht mag, aber ich denke APT bestand darauf, dass das nicht passieren darf.";
-"CREDITS" = "Credits";
-"CYDIA_STORE" = "Cydia Store";
-"DATABASE" = "Datenbank";
-"DETAILS" = "Details";
-"DEVELOPER" = "Entwickler";
-"DEVELOPER_EX" = "Ohne Filter";
-"DEVELOPERS_ONLY" = "Nur für Entwickler";
-"DISK_FREEING" = "Freigegebener Speicher";
-"DISK_USING" = "Speicherverbrauch";
-"DONATE_USING" = "Spenden via %@";
-"DONE" = "Fertig";
-"DOUBLE_QUOTED" = "„%@“";
-"DOWNGRADE" = "Downgrade";
-"DOWNLOADING" = "Lädt";
-"DOWNLOADING_" = "Lädt %@ herunter";
-"EDIT" = "Bearbeiten";
-"ENTER_APT_URL" = "Cydia/APT URL eingeben";
-"ENTERED_BY_USER" = "Vom Benutzer eingegeben";
-"ERROR" = "Fehler";
-"ESSENTIAL_UPGRADE" = "Wichtige Aktualisierung";
-"ESSENTIAL_UPGRADES" = "%d wichtige Aktualisierungen";
-"ESSENTIAL_UPGRADE_EX" = "Ein oder mehr wichtige Pakete sind veraltet. Um Fehler zu vermeiden, wird empfohlen die Aktualisierungen zu installieren.";
-"EXCLAMATION" = "%@!";
-"EXPANDED_SIZE" = "Entpackte Größe";
-"EXPERT" = "Experte";
-"FEATURED_PACKAGES" = "Paketempfehlungen";
-"FAQ" = "FAQ";
-"FILES" = "Dateien";
-"FILES_INSTALLED_TO" = "Dateien installiert nach %@";
-"FILESYSTEM_CONTENT" = "Inhalt des Dateisystems";
-"FOLLOW_ON_TWITTER" = "Folge %@ auf Twitter";
-"FORCE_REMOVAL" = "Löschen erzwingen";
-"FORCIBLY_CLEAR" = "Leeren erzwingen";
-"FREE_APPLICATIONS" = "Kostenlose Programme";
-"FREE_EXTENSIONS" = "Kostenlose Erweiterungen";
-"FREQUENTLY_ASKED_QUESTIONS" = "Häufig gestellte Fragen (FAQ)";
-"FROM" = "von %@";
-"FROWNY_PANTS" = "Stirnrunzelnde Hose";
-"FUTURE_FEATURE_ROADMAP" = "Übersicht geplanter Funktionen";
-"HACKER" = "Hacker";
-"HACKER_EX" = "+ Kommandozeile";
-"HALFINSTALLED_PACKAGE" = "Teilinstalliertes Paket";
-"HALFINSTALLED_PACKAGES" = "%d teilinstallierte Pakete";
-"HALFINSTALLED_PACKAGE_EX" = "Wenn die an Pakete gebundenen Skripte Probleme machen, werden sie in einem schlechten Status (halb eingestellt oder halb installiert) zurückgelassen. Diese Fehler sind dauerhaft und erzeugen weitere Probleme. Diese fehlerhaften Skripte und Pakete können entfernt werden.";
-"HOME" = "Start";
-"ID" = "ID";
-"IGNORE_UPGRADES" = "Aktualisierungen ignorieren";
-"IGNORED_UPGRADES" = "Ignorierte Aktualisierungen";
-"ILLEGAL_PACKAGE_IDENTIFIER" = "Unerlaubte Paket-Kennung";
-"INSTALL" = "Installieren";
-"INSTALLED" = "Installiert";
-"INSTALLED_BY_PACKAGE" = "Installiert nach Paket";
-"INSTALLED_DETAILS" = "Installiertes Paket";
-"INSTALLED_FILES" = "Installierte Dateien";
-"KEEP_OLD_COPY" = "Meine alte Kopie behalten";
-"LOADING" = "Lade";
-"LOADING_DATA" = "Lade Daten";
-"LOCAL" = "Lokal";
-"LOGIN" = "Anmeldung";
-"MAILING_LISTS" = "Mailingliste";
-"MAINTAINER" = "Kontakt";
-"MANAGE" = "Verwalten";
-"MODIFICATIONS" = "Änderungen";
-"MODIFY" = "Verändern";
-"MORE_INFORMATION" = "Mehr Informationen";
-"MORE_PACKAGE_SOURCES" = "Mehr Paketquellen";
-"NAME" = "Name";
-"NETWORK_ERROR" = "Netzwerk-Fehler";
-"NEVER_OR_UNKNOWN" = "Nie oder unbekannt";
-"NEW" = "Neu";
-"NEW_AT" = "Neu am %@";
-"NEW_INSTALL" = "Neuinstallation";
-"NO" = "Nein";
-"NO_SECTION" = "(Keine Kategorie)";
-"NOT_RATED" = "Nicht bewertet";
-"NOTE" = "Hinweis";
-"NOT_REPOSITORY" = "Quelle nicht gefunden";
-"NOT_REPOSITORY_EX" = "Die angegebene Quelle konnte nicht gefunden werden. Dies kann passieren, wenn eine Installer-Quelle hinzugefügt wurde (diese werden nicht unterstützt). Außerdem kann dieses Programm nur mit exakten, vollständigen URLs umgehen. Falls sie eine Quelle hosten und Probleme haben kontaktieren sie mit ihren Fragen bitte den Autor von Cydia.";
-"OK" = "OK";
-"OKAY" = "Okay";
-"PACKAGE_CANNOT_BE_FOUND" = "Das Paket %@ kann in den aktuellen Quellen nicht gefunden werden. Ich schlage vor, mehr Quellen hinzuzufügen.";
-"PACKAGE_CANNOT_BE_FOUND_EX" = "Dieses Problem kann auch durch eine Reihe anderer Faktoren hervorgerufen worden sein. Der häufigste ist, dass dein Paketkatalog nicht mehr aktuell ist. Zum manuellen erneuern, klicke den Aktualisieren-Knopf im Änderungen-Tab. Das Paket könnte auch einfach nicht mehr existieren. Es könnte auch sein, dass du eine alte Firmwareversion nutzt: Nutzer sollten versuchen halbwegs auf dem Laufenden zu bleiben mit Apples neuen Firmwares.";
-"PACKAGE_DAMAGED" = "Paket beschädigt";
-"PACKAGE_DETAILS" = "Paketdetails";
-"PACKAGE_QUEUE" = "Paket-Warteschlange";
-"PACKAGES" = "Pakete";
-"PACKAGES_EX" = "Bereits installierte Pakete ansehen oder löschen.";
-"PARENTHETICAL" = "%@ (%@)";
-"PASSWORD" = "Passwort";
-"PERFORM_SELECTIONS" = "Führe Auswahl durch";
-"PREPARE_ARCHIVES" = "Bereite Archive vor";
-"PRODUCTS" = "Produkte";
-"PURGE" = "Völlig entfernen";
-"Q_D" = "S";
-"QUEUED_FOR" = "In Warteschlange für %@";
-"QUESTION" = "%@?";
-"REBOOT_DEVICE" = "Gerät neustarten";
-"RECENT_CHANGES_UPDATES" = "Neueste Änderungen/Aktualisierungen";
-"RECOMMENDED_BOOKS" = "Empfohlene Bücher";
-"REFRESH" = "Aktualisieren";
-"REFRESHING_DATA" = "Hole neue Daten";
-"REINSTALL" = "Neu installieren";
-"RELOAD" = "Neu laden";
-"RELOAD_SPRINGBOARD" = "SpringBoard neu laden";
-"RELOADING_DATA" = "Lade neue Daten";
-"REMOVE" = "Entfernen";
-"REMOVING_ESSENTIALS" = "Grundlegende Pakete löschen";
-"REMOVING_ESSENTIALS_EX" = "Diese Aktion erfordert das Löschen eines oder mehrerer Pakete die notwendig für die Funktionalität von Cydia oder iPhoneOS sind. Wenn Sie fortsetzen, können Sie ggf. Cydia nicht mehr benutzen um den Schaden zu beheben.";
-"REPAIRING" = "Reparieren";
-"REPOSITORY_SIGNATURE" = "Quellen-Signatur anzeigen";
-"REQUEST_ADVERTISING_SPACE" = "Werbefläche beantragen";
-"REQUIREMENTS_FOR_LISTING" = "Bedingungen für die Aufnahme";
-"RESTART_SPRINGBOARD" = "SpringBoard neu starten";
-"RESUBMIT_FORM" = "Sind Sie sicher, dass Sie das Formular erneut senden möchten?";
-"RESUMING_AT" = "Wiederaufnahme bei";
-"RETURN_TO_CYDIA" = "Zu Cydia zurückkehren";
-"ROLE_EX" = "Nicht alle in Cydia erhältlichen Pakete sind für alle Benutzer gedacht. Bitte stufen Sie sich ein, so dass Cydia hilfreiche Filter anwenden kann.\n\nDiese Einstellung kann in den \"Einstellungen\" unter \"Verwalten\" geändert werden.";
-"RUNNING" = "Aktiv";
-"SAFE" = "Sicher";
-"SAMPLE" = "Beispiel";
-"SCREENSHOT" = "Bildschirmfoto";
-"SCREENSHOTS" = "Bildschirmfotos";
-"SEARCH" = "Suche";
-"SEARCH_EX" = "Paketname & Beschreibung";
-"SECTION" = "Kategorie";
-"SECTION_VISIBILITY" = "Sichtbarkeit der Kategorien";
-"SECTIONS" = "Kategorien";
-"SEE_WHAT_CHANGED" = "Änderungen ansehen";
-"SETTINGS" = "Einstellungen";
-"SHOW_ALL_CHANGES" = "Alle Änderungen zeigen";
-"SHOW_ALL_CHANGES_EX" = "Änderungen zeigt nur Aktualisierungen der installierten Paketen an, um Spam von Paket-Herstellern zu reduzieren. Aktivieren Sie dies, um Aktualisierungen zu diesem Paket zu sehen, obwohl es nicht installiert ist.";
-"SIGNED_PACKAGE" = "Dieses Paket wurde signiert.";
-"SIMPLE" = "Einfach";
-"SINGLE_QUOTED" = "‚%@‘";
-"SLASH_DELIMITED" = "%@ / %@";
-"SOURCE_DETAILS" = "Information zur Quelle";
-"SOURCE_WARNING" = "Quellenwarnung";
-"SOURCES" = "Quellen";
-"SOURCES_EX" = "Quellenliste anzeigen und eigene hinzufügen.";
-"SPONSOR" = "Sponsor";
-"SPONSORING_PRODUCTS" = "Unterstützende Produkte";
-"STATISTICS" = "Statistik";
-"STILL_BROKEN_EX" = "Der Versuch, die kaputten Sektionen zu reparieren hat nichts gebracht.";
-"STORAGE" = "Speicherplatz";
-"STORAGE_EX" = "Nachsehen, wieviel Speicherplatz für neue Pakete vorhanden ist.";
-"SUBMIT" = "Absenden";
-"SUPPORT_KNOWN_ISSUES" = "Support & bekannte Probleme";
-"TEMPORARY_IGNORE" = "Ignorieren (temporär)";
-"THANK_YOU" = "Danke";
-"QUEUE" = "Warteschlange";
-"UNABLE_TO_COMPLY" = "Operation nicht möglich";
-"UNABLE_TO_COMPLY_EX" = "Diese Aktion erfordert das Löschen eines oder mehrerer Pakete die notwendig für die Funktionalität von Cydia oder iPhoneOS sind. Um fortzufahren und diese Aktion zu erzwingen muss der Fortgeschrittenen-Modus in den Einstellungen aktiviert sein.";
-"UNABLE_TO_LOAD" = "Laden nicht möglich";
-"UNKNOWN" = "Unbekannt";
-"UNSAFE" = "Unsicher";
-"UPDATING_DATABASE" = "Datenbank aktualisieren";
-"UPDATING_SOURCES" = "Quellen aktualisieren";
-"UPGRADE" = "Aktualisierung";
-"UPGRADE_ESSENTIAL" = "Wichtige Pakete aktualisieren";
-"UPGRADING_TO_READ_THIS" = "Upgrade auf %@? Hier lesen";
-"USER" = "Benutzer";
-"USER_EX" = "Nur Grafische";
-"USER_GUIDES" = "Benutzer-Handbücher";
-"USERNAME" = "Benutzername";
-"VERIFICATION_ERROR" = "Fehler beim Überprüfen";
-"VERIFYING_URL" = "URL überprüfen";
-"VERSION" = "Version";
-"WARNING" = "Warnung";
-"WELCOME_TO_CYDIA" = "Willkommen bei Cydia™";
-"WHO_ARE_YOU" = "Wer sind Sie?";
-"YES" = "Ja";
diff --git a/Cydia.app/German.lproj/Sections.strings b/Cydia.app/German.lproj/Sections.strings
deleted file mode 100644 (file)
index 6abe4ce..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-"Addons" = "Erweiterungen";
-"Administration" = "Verwaltung";
-"Adult" = "Ab 18";
-"App Addons" = "Programm-Erweiterugen";
-"Archiving" = "Archivierung";
-"Battery" = "Batterie";
-"Carrier Bundles" = "Telefongesellschaft-Pakete";
-"Carriers" = "Telefongesellschaften";
-"Complete" = "Vollständig";
-"Data Storage" = "Speicherplatzverwaltung";
-"Development" = "Entwicklung";
-"Dialer" = "Wählhilfen";
-"Dictionaries" = "Wörterbücher";
-"Dock" = "Dock";
-"eBooks" = "eBooks";
-"Education" = "Bildung";
-"Emulation" = "Emulation";
-"Entertainment" = "Unterhaltung";
-"Games" = "Spiele";
-"Icy" = "Icy";
-"Java" = "Java";
-"Keyboards" = "Tastaturen";
-"Localization" = "Lokalisierung";
-"LockScreen" = "Lockscreen";
-"Messaging" = "Nachrichtendienste";
-"Multimedia" = "Multimedia";
-"Networking" = "Netzwerk";
-"Notifications" = "Mitteilugen";
-"Packaging" = "Paketverwaltung";
-"Productivity" = "Produktivität / Kreativität";
-"Repositories" = "Quellen";
-"Ringtones" = "Klingeltöne";
-"Scripting" = "Skriptsprachen";
-"Security" = "Sicherheit";
-"Sliders" = "Slider";
-"SMS" = "SMS";
-"Social" = "Soziale Netze";
-"System" = "System";
-"Terminal Support" = "Konsolen-Support";
-"Text Editors" = "Texteditoren";
-"Themes" = "Themes";
-"Toys" = "Spielereien";
-"Tweaks" = "Tweaks / Tuning";
-"Utilities" = "Dienstprogramme";
-"Videos" = "Videos";
-"Wallpaper" = "Hintergrundbilder";
-"Weather" = "Wetter";
-"WebClips" = "Web-Schnipsel";
-"Widgets" = "Widgets";
diff --git a/Cydia.app/Icon-Small-50.png b/Cydia.app/Icon-Small-50.png
deleted file mode 100644 (file)
index d7d2849..0000000
Binary files a/Cydia.app/Icon-Small-50.png and /dev/null differ
diff --git a/Cydia.app/Icon-Small.png b/Cydia.app/Icon-Small.png
deleted file mode 100644 (file)
index af15d71..0000000
Binary files a/Cydia.app/Icon-Small.png and /dev/null differ
diff --git a/Cydia.app/Icon-Small@2x.png b/Cydia.app/Icon-Small@2x.png
deleted file mode 100644 (file)
index 1a73ddb..0000000
Binary files a/Cydia.app/Icon-Small@2x.png and /dev/null differ
diff --git a/Cydia.app/Info.plist b/Cydia.app/Info.plist
deleted file mode 100644 (file)
index 806506b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-
-<dict>
-    <key>CFBundleDevelopmentRegion</key>
-    <string>en</string>
-
-    <key>CFBundleExecutable</key>
-    <string>Cydia</string>
-
-    <key>CFBundleIdentifier</key>
-    <string>com.saurik.Cydia</string>
-
-    <key>CFBundleInfoDictionaryVersion</key>
-    <string>6.0</string>
-
-    <key>CFBundleName</key>
-    <string>Cydia</string>
-
-    <key>CFBundlePackageType</key>
-    <string>APPL</string>
-
-    <key>CFBundleShortVersionString</key>
-    <string>0.9</string>
-
-    <key>CFBundleSignature</key>
-    <string>????</string>
-
-    <key>CFBundleVersion</key>
-    <string>0.9</string>
-
-    <key>SBUsesNetwork</key>
-    <integer>11</integer>
-
-    <key>CFBundleURLTypes</key>
-    <array>
-        <dict>
-            <key>CFBundleURLName</key>
-            <string>Cydia Internal URL</string>
-            <key>CFBundleURLSchemes</key>
-            <array>
-                <string>cydia</string>
-            </array>
-        </dict>
-    </array>
-
-    <key>DTSDKName</key>
-    <string>iphoneos2.0.saurik</string>
-
-    <key>MinimumOSVersion</key>
-    <string>2.0</string>
-
-    <key>UIDeviceFamily</key>
-    <array>
-        <integer>1</integer>
-        <integer>2</integer>
-    </array>
-
-    <key>UISupportedInterfaceOrientations</key>
-    <array>
-        <string>UIInterfaceOrientationPortrait</string>
-        <!--string>UIInterfaceOrientationPortraitUpsideDown</string>
-        <string>UIInterfaceOrientationLandscapeLeft</string>
-        <string>UIInterfaceOrientationLandscapeRight</string-->
-    </array>
-
-    <key>UIBackgroundModes</key>
-    <array>
-        <string>audio</string>
-        <string>continuous</string>
-    </array>
-
-    <key>CFBundleIconFile</key>
-    <string>iconClassic.png</string>
-
-    <key>CFBundleIconFiles</key>
-    <array>
-        <string>icon.png</string>
-        <string>icon-72.png</string>
-        <string>icon@2x.png</string>
-        <string>Icon-Small.png</string>
-        <string>Icon-Small-50.png</string>
-        <string>Icon-Small@2x.png</string>
-    </array>
-</dict>
-
-</plist>
diff --git a/Cydia.app/Modes/DOWNGRADE.png b/Cydia.app/Modes/DOWNGRADE.png
deleted file mode 100644 (file)
index 41c0d70..0000000
Binary files a/Cydia.app/Modes/DOWNGRADE.png and /dev/null differ
diff --git a/Cydia.app/Modes/INSTALL.png b/Cydia.app/Modes/INSTALL.png
deleted file mode 100644 (file)
index a83f354..0000000
Binary files a/Cydia.app/Modes/INSTALL.png and /dev/null differ
diff --git a/Cydia.app/Modes/NEW_INSTALL.png b/Cydia.app/Modes/NEW_INSTALL.png
deleted file mode 120000 (symlink)
index 475bda6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-INSTALL.png
\ No newline at end of file
diff --git a/Cydia.app/Modes/PURGE.png b/Cydia.app/Modes/PURGE.png
deleted file mode 100644 (file)
index 795fa19..0000000
Binary files a/Cydia.app/Modes/PURGE.png and /dev/null differ
diff --git a/Cydia.app/Modes/REINSTALL.png b/Cydia.app/Modes/REINSTALL.png
deleted file mode 100644 (file)
index 0b7754c..0000000
Binary files a/Cydia.app/Modes/REINSTALL.png and /dev/null differ
diff --git a/Cydia.app/Modes/REMOVE.png b/Cydia.app/Modes/REMOVE.png
deleted file mode 100644 (file)
index 1b2e691..0000000
Binary files a/Cydia.app/Modes/REMOVE.png and /dev/null differ
diff --git a/Cydia.app/Modes/UPGRADE.png b/Cydia.app/Modes/UPGRADE.png
deleted file mode 100644 (file)
index 631b7ef..0000000
Binary files a/Cydia.app/Modes/UPGRADE.png and /dev/null differ
diff --git a/Cydia.app/Purposes/commercial.png b/Cydia.app/Purposes/commercial.png
deleted file mode 100644 (file)
index ba66d4b..0000000
Binary files a/Cydia.app/Purposes/commercial.png and /dev/null differ
diff --git a/Cydia.app/Purposes/console.png b/Cydia.app/Purposes/console.png
deleted file mode 100644 (file)
index 48f7e88..0000000
Binary files a/Cydia.app/Purposes/console.png and /dev/null differ
diff --git a/Cydia.app/Purposes/daemon.png b/Cydia.app/Purposes/daemon.png
deleted file mode 100644 (file)
index 4593ee8..0000000
Binary files a/Cydia.app/Purposes/daemon.png and /dev/null differ
diff --git a/Cydia.app/Purposes/extension.png b/Cydia.app/Purposes/extension.png
deleted file mode 100644 (file)
index e7025b4..0000000
Binary files a/Cydia.app/Purposes/extension.png and /dev/null differ
diff --git a/Cydia.app/Purposes/library.png b/Cydia.app/Purposes/library.png
deleted file mode 100644 (file)
index 3bcbc04..0000000
Binary files a/Cydia.app/Purposes/library.png and /dev/null differ
diff --git a/Cydia.app/Purposes/uikit.png b/Cydia.app/Purposes/uikit.png
deleted file mode 100644 (file)
index 2141d72..0000000
Binary files a/Cydia.app/Purposes/uikit.png and /dev/null differ
diff --git a/Cydia.app/Purposes/x.png b/Cydia.app/Purposes/x.png
deleted file mode 100644 (file)
index 0b24b74..0000000
Binary files a/Cydia.app/Purposes/x.png and /dev/null differ
diff --git a/Cydia.app/Sections.plist b/Cydia.app/Sections.plist
deleted file mode 100644 (file)
index a62e6d7..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-
-<dict>
-    <key>Hunspell_Dictionaries</key>
-    <dict>
-        <key>Rename</key>
-        <string>Dictionaries_(Hunspell)</string>
-    </dict>
-
-    <key>Utility</key>
-    <dict>
-        <key>Rename</key>
-        <string>Utilities</string>
-    </dict>
-
-    <key>Themes_(Springboard)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(SpringBoard)</string>
-    </dict>
-
-    <key>Themes_(SummerBoard)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(SpringBoard)</string>
-    </dict>
-    
-    <key>Themes_(Systen)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(System)</string>
-    </dict>
-
-    <key>Intelliborn</key>
-    <dict>
-        <key>Rename</key>
-        <string>Utilities</string>
-    </dict>
-
-    <key>SMS</key>
-    <dict>
-        <key>Rename</key>
-        <string>Messaging</string>
-    </dict>
-
-    <key>CarrierBundle</key>
-    <dict>
-        <key>Rename</key>
-        <string>Carrier_Bundles</string>
-    </dict>
-
-    <key>Messages</key>
-    <dict>
-        <key>Rename</key>
-        <string>Messaging</string>
-    </dict>
-
-    <key>Themes_(Locksceen)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(LockScreen)</string>
-    </dict>
-
-    <key>Themes_(Lockscree)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(LockScreen)</string>
-    </dict>
-
-    <key>Themes_(Losckscreen)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(LockScreen)</string>
-    </dict>
-
-    <key>Themes_(Video)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(Videos)</string>
-    </dict>
-
-    <key>Utilites</key>
-    <dict>
-        <key>Rename</key>
-        <string>Utilities</string>
-    </dict>
-
-    <key>Themes_(Lockscreen)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(LockScreen)</string>
-    </dict>
-
-    <key>Themes_(Complet)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(Complete)</string>
-    </dict>
-    
-    <key>Themes_(Widgets)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Themes_(Addons)</string>
-    </dict>
-
-    <key>Wallpapers</key>
-    <dict>
-        <key>Rename</key>
-        <string>Wallpaper</string>
-    </dict>
-
-    <key>Messageing</key>
-    <dict>
-        <key>Rename</key>
-        <string>Messaging</string>
-    </dict>
-
-    <key>Network</key>
-    <dict>
-        <key>Rename</key>
-        <string>Networking</string>
-    </dict>
-    
-    <key>Ringtone</key>
-    <dict>
-        <key>Rename</key>
-        <string>Ringtones</string>
-    </dict>
-
-    <key>Tweak</key>
-    <dict>
-        <key>Rename</key>
-        <string>Tweaks</string>
-    </dict>
-
-    <key>Tweaks_2.0</key>
-    <dict>
-        <key>Rename</key>
-        <string>Tweaks_(2.0)</string>
-    </dict>
-
-    <key>Tweaks_2.1</key>
-    <dict>
-        <key>Rename</key>
-        <string>Tweaks_(2.1)</string>
-    </dict>
-
-    <key>Tweaks_2.2</key>
-    <dict>
-        <key>Rename</key>
-        <string>Tweaks_(2.2)</string>
-    </dict>
-
-    <key>Tweaks_3.0</key>
-    <dict>
-        <key>Rename</key>
-        <string>Tweaks_(3.0)</string>
-    </dict>
-    
-    <key>SBSettings_Addons</key>
-    <dict>
-        <key>Rename</key>
-        <string>Addons_(SBSettings)</string>
-    </dict>
-    
-    <key>LockInfo_Addons</key>
-    <dict>
-        <key>Rename</key>
-        <string>Addons_(LockInfo)</string>
-    </dict>
-    
-    <key>App_Addons</key>
-    <dict>
-        <key>Rename</key>
-        <string>Addons</string>
-    </dict>
-    
-    <key>App_Addons_(Iconoclasm)</key>
-    <dict>
-        <key>Rename</key>
-        <string>Addons_(Iconoclasm)</string>
-    </dict>
-    
-    <key>BossPaper_Addons</key>
-    <dict>
-        <key>Rename</key>
-        <string>Addons_(BossPaper)</string>
-    </dict>
-</dict>
-
-</plist>
diff --git a/Cydia.app/Sections/Administration.png b/Cydia.app/Sections/Administration.png
deleted file mode 100644 (file)
index 65efd3e..0000000
Binary files a/Cydia.app/Sections/Administration.png and /dev/null differ
diff --git a/Cydia.app/Sections/App Addons.png b/Cydia.app/Sections/App Addons.png
deleted file mode 100644 (file)
index 424f565..0000000
Binary files a/Cydia.app/Sections/App Addons.png and /dev/null differ
diff --git a/Cydia.app/Sections/Archiving.png b/Cydia.app/Sections/Archiving.png
deleted file mode 100644 (file)
index 9efce56..0000000
Binary files a/Cydia.app/Sections/Archiving.png and /dev/null differ
diff --git a/Cydia.app/Sections/Blanks.png b/Cydia.app/Sections/Blanks.png
deleted file mode 100644 (file)
index 7c0c2a0..0000000
Binary files a/Cydia.app/Sections/Blanks.png and /dev/null differ
diff --git a/Cydia.app/Sections/Carrier Bundles.png b/Cydia.app/Sections/Carrier Bundles.png
deleted file mode 100644 (file)
index 00f36f7..0000000
Binary files a/Cydia.app/Sections/Carrier Bundles.png and /dev/null differ
diff --git a/Cydia.app/Sections/Communication.png b/Cydia.app/Sections/Communication.png
deleted file mode 100644 (file)
index 00f36f7..0000000
Binary files a/Cydia.app/Sections/Communication.png and /dev/null differ
diff --git a/Cydia.app/Sections/Data Storage.png b/Cydia.app/Sections/Data Storage.png
deleted file mode 100644 (file)
index 1bb23fe..0000000
Binary files a/Cydia.app/Sections/Data Storage.png and /dev/null differ
diff --git a/Cydia.app/Sections/Development.png b/Cydia.app/Sections/Development.png
deleted file mode 100644 (file)
index 806b442..0000000
Binary files a/Cydia.app/Sections/Development.png and /dev/null differ
diff --git a/Cydia.app/Sections/Dictionaries.png b/Cydia.app/Sections/Dictionaries.png
deleted file mode 100644 (file)
index e386e76..0000000
Binary files a/Cydia.app/Sections/Dictionaries.png and /dev/null differ
diff --git a/Cydia.app/Sections/Education.png b/Cydia.app/Sections/Education.png
deleted file mode 100644 (file)
index 4a2a03f..0000000
Binary files a/Cydia.app/Sections/Education.png and /dev/null differ
diff --git a/Cydia.app/Sections/Entertainment.png b/Cydia.app/Sections/Entertainment.png
deleted file mode 100644 (file)
index 69c8214..0000000
Binary files a/Cydia.app/Sections/Entertainment.png and /dev/null differ
diff --git a/Cydia.app/Sections/Games.png b/Cydia.app/Sections/Games.png
deleted file mode 100644 (file)
index 6e14c50..0000000
Binary files a/Cydia.app/Sections/Games.png and /dev/null differ
diff --git a/Cydia.app/Sections/Health and Fitness.png b/Cydia.app/Sections/Health and Fitness.png
deleted file mode 100644 (file)
index e2db013..0000000
Binary files a/Cydia.app/Sections/Health and Fitness.png and /dev/null differ
diff --git a/Cydia.app/Sections/Imaging.png b/Cydia.app/Sections/Imaging.png
deleted file mode 100644 (file)
index 1e8f7fa..0000000
Binary files a/Cydia.app/Sections/Imaging.png and /dev/null differ
diff --git a/Cydia.app/Sections/Java.png b/Cydia.app/Sections/Java.png
deleted file mode 100644 (file)
index e6bbc91..0000000
Binary files a/Cydia.app/Sections/Java.png and /dev/null differ
diff --git a/Cydia.app/Sections/Keyboards.png b/Cydia.app/Sections/Keyboards.png
deleted file mode 100644 (file)
index 6b3df89..0000000
Binary files a/Cydia.app/Sections/Keyboards.png and /dev/null differ
diff --git a/Cydia.app/Sections/Localization.png b/Cydia.app/Sections/Localization.png
deleted file mode 100644 (file)
index 80d41d3..0000000
Binary files a/Cydia.app/Sections/Localization.png and /dev/null differ
diff --git a/Cydia.app/Sections/Messaging.png b/Cydia.app/Sections/Messaging.png
deleted file mode 100644 (file)
index 69d18e0..0000000
Binary files a/Cydia.app/Sections/Messaging.png and /dev/null differ
diff --git a/Cydia.app/Sections/Multimedia.png b/Cydia.app/Sections/Multimedia.png
deleted file mode 100644 (file)
index 42d0b5e..0000000
Binary files a/Cydia.app/Sections/Multimedia.png and /dev/null differ
diff --git a/Cydia.app/Sections/Navigation.png b/Cydia.app/Sections/Navigation.png
deleted file mode 100644 (file)
index 4829e62..0000000
Binary files a/Cydia.app/Sections/Navigation.png and /dev/null differ
diff --git a/Cydia.app/Sections/Networking.png b/Cydia.app/Sections/Networking.png
deleted file mode 100644 (file)
index a4f04e3..0000000
Binary files a/Cydia.app/Sections/Networking.png and /dev/null differ
diff --git a/Cydia.app/Sections/Packaging.png b/Cydia.app/Sections/Packaging.png
deleted file mode 100644 (file)
index d7d914e..0000000
Binary files a/Cydia.app/Sections/Packaging.png and /dev/null differ
diff --git a/Cydia.app/Sections/Planet-iPhones Mods.png b/Cydia.app/Sections/Planet-iPhones Mods.png
deleted file mode 100644 (file)
index e641970..0000000
Binary files a/Cydia.app/Sections/Planet-iPhones Mods.png and /dev/null differ
diff --git a/Cydia.app/Sections/Productivity.png b/Cydia.app/Sections/Productivity.png
deleted file mode 100644 (file)
index c99c69d..0000000
Binary files a/Cydia.app/Sections/Productivity.png and /dev/null differ
diff --git a/Cydia.app/Sections/Repositories.png b/Cydia.app/Sections/Repositories.png
deleted file mode 100644 (file)
index d6fe267..0000000
Binary files a/Cydia.app/Sections/Repositories.png and /dev/null differ
diff --git a/Cydia.app/Sections/Ringtones.png b/Cydia.app/Sections/Ringtones.png
deleted file mode 100644 (file)
index 57fd660..0000000
Binary files a/Cydia.app/Sections/Ringtones.png and /dev/null differ
diff --git a/Cydia.app/Sections/SBSettings Addons.png b/Cydia.app/Sections/SBSettings Addons.png
deleted file mode 100644 (file)
index 571555a..0000000
Binary files a/Cydia.app/Sections/SBSettings Addons.png and /dev/null differ
diff --git a/Cydia.app/Sections/Scripting.png b/Cydia.app/Sections/Scripting.png
deleted file mode 100644 (file)
index 22285d2..0000000
Binary files a/Cydia.app/Sections/Scripting.png and /dev/null differ
diff --git a/Cydia.app/Sections/Security.png b/Cydia.app/Sections/Security.png
deleted file mode 100644 (file)
index ae142eb..0000000
Binary files a/Cydia.app/Sections/Security.png and /dev/null differ
diff --git a/Cydia.app/Sections/Social.png b/Cydia.app/Sections/Social.png
deleted file mode 100644 (file)
index 6c0cfa4..0000000
Binary files a/Cydia.app/Sections/Social.png and /dev/null differ
diff --git a/Cydia.app/Sections/System.png b/Cydia.app/Sections/System.png
deleted file mode 100644 (file)
index 19d2c22..0000000
Binary files a/Cydia.app/Sections/System.png and /dev/null differ
diff --git a/Cydia.app/Sections/Terminal Support.png b/Cydia.app/Sections/Terminal Support.png
deleted file mode 100644 (file)
index d664618..0000000
Binary files a/Cydia.app/Sections/Terminal Support.png and /dev/null differ
diff --git a/Cydia.app/Sections/Text Editors.png b/Cydia.app/Sections/Text Editors.png
deleted file mode 100644 (file)
index 5e65d46..0000000
Binary files a/Cydia.app/Sections/Text Editors.png and /dev/null differ
diff --git a/Cydia.app/Sections/Themes.png b/Cydia.app/Sections/Themes.png
deleted file mode 100644 (file)
index e35b948..0000000
Binary files a/Cydia.app/Sections/Themes.png and /dev/null differ
diff --git a/Cydia.app/Sections/Toys.png b/Cydia.app/Sections/Toys.png
deleted file mode 100644 (file)
index 368eb4c..0000000
Binary files a/Cydia.app/Sections/Toys.png and /dev/null differ
diff --git a/Cydia.app/Sections/Tweaks.png b/Cydia.app/Sections/Tweaks.png
deleted file mode 100644 (file)
index 4f588c6..0000000
Binary files a/Cydia.app/Sections/Tweaks.png and /dev/null differ
diff --git a/Cydia.app/Sections/Utilities.png b/Cydia.app/Sections/Utilities.png
deleted file mode 100644 (file)
index fab5d32..0000000
Binary files a/Cydia.app/Sections/Utilities.png and /dev/null differ
diff --git a/Cydia.app/Sections/Wallpaper.png b/Cydia.app/Sections/Wallpaper.png
deleted file mode 100644 (file)
index 1060fa0..0000000
Binary files a/Cydia.app/Sections/Wallpaper.png and /dev/null differ
diff --git a/Cydia.app/Sections/WebClips.png b/Cydia.app/Sections/WebClips.png
deleted file mode 100644 (file)
index 7ed4053..0000000
Binary files a/Cydia.app/Sections/WebClips.png and /dev/null differ
diff --git a/Cydia.app/Sections/Widgets.png b/Cydia.app/Sections/Widgets.png
deleted file mode 100644 (file)
index ca8c1ef..0000000
Binary files a/Cydia.app/Sections/Widgets.png and /dev/null differ
diff --git a/Cydia.app/Sections/X Window.png b/Cydia.app/Sections/X Window.png
deleted file mode 100644 (file)
index eac01e9..0000000
Binary files a/Cydia.app/Sections/X Window.png and /dev/null differ
diff --git a/Cydia.app/Sections/eBooks.png b/Cydia.app/Sections/eBooks.png
deleted file mode 100644 (file)
index 512c68b..0000000
Binary files a/Cydia.app/Sections/eBooks.png and /dev/null differ
diff --git a/Cydia.app/Sources/cy.sosiphone.com.png b/Cydia.app/Sources/cy.sosiphone.com.png
deleted file mode 100644 (file)
index b848d95..0000000
Binary files a/Cydia.app/Sources/cy.sosiphone.com.png and /dev/null differ
diff --git a/Cydia.app/Sources/iphone.hackndev.org.png b/Cydia.app/Sources/iphone.hackndev.org.png
deleted file mode 100644 (file)
index 1f701df..0000000
Binary files a/Cydia.app/Sources/iphone.hackndev.org.png and /dev/null differ
diff --git a/Cydia.app/Sources/iphonehe.com.png b/Cydia.app/Sources/iphonehe.com.png
deleted file mode 100644 (file)
index b20263e..0000000
Binary files a/Cydia.app/Sources/iphonehe.com.png and /dev/null differ
diff --git a/Cydia.app/Sources/urbanfanatics.com.png b/Cydia.app/Sources/urbanfanatics.com.png
deleted file mode 100644 (file)
index 9cf47c4..0000000
Binary files a/Cydia.app/Sources/urbanfanatics.com.png and /dev/null differ
diff --git a/Cydia.app/Sources/www.zodttd.com.png b/Cydia.app/Sources/www.zodttd.com.png
deleted file mode 100644 (file)
index 83a3b33..0000000
Binary files a/Cydia.app/Sources/www.zodttd.com.png and /dev/null differ
diff --git a/Cydia.app/Test b/Cydia.app/Test
deleted file mode 100755 (executable)
index 123c7eb..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-killall Cydia_
-set -e
-rsync -SPaz --copy-links saurik@carrier.saurik.com:menes/cydia/cydia_iphoneos-arm.deb .
-dpkg -i cydia_iphoneos-arm.deb
-touch /tmp/cydia.log
-chown mobile.mobile /tmp/cydia.log
-uiopen "${1-cydia://}"
-exec tail /var/log/syslog /tmp/cydia.log -fn0
diff --git a/Cydia.app/advanced.png b/Cydia.app/advanced.png
deleted file mode 100644 (file)
index 419ba52..0000000
Binary files a/Cydia.app/advanced.png and /dev/null differ
diff --git a/Cydia.app/changes.png b/Cydia.app/changes.png
deleted file mode 100644 (file)
index 654208f..0000000
Binary files a/Cydia.app/changes.png and /dev/null differ
diff --git a/Cydia.app/changes@2x.png b/Cydia.app/changes@2x.png
deleted file mode 100644 (file)
index aa6a29a..0000000
Binary files a/Cydia.app/changes@2x.png and /dev/null differ
diff --git a/Cydia.app/chevron@2x.png b/Cydia.app/chevron@2x.png
deleted file mode 100644 (file)
index 9905c17..0000000
Binary files a/Cydia.app/chevron@2x.png and /dev/null differ
diff --git a/Cydia.app/commercial.png b/Cydia.app/commercial.png
deleted file mode 100644 (file)
index 8599f48..0000000
Binary files a/Cydia.app/commercial.png and /dev/null differ
diff --git a/Cydia.app/compose.png b/Cydia.app/compose.png
deleted file mode 100644 (file)
index 1141d5d..0000000
Binary files a/Cydia.app/compose.png and /dev/null differ
diff --git a/Cydia.app/configure.png b/Cydia.app/configure.png
deleted file mode 100644 (file)
index c27618d..0000000
Binary files a/Cydia.app/configure.png and /dev/null differ
diff --git a/Cydia.app/confirm.html b/Cydia.app/confirm.html
deleted file mode 100644 (file)
index 5a4ed55..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="CONFIRM"></title>
-    <meta name="viewport" content="width=320, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="confirm.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-</head><body class="pinstripe">
-<panel id="issues">
-
-<fieldset class="issues">
-    <div><p><span style="color: red; font-weight: bold" localize="NOTE"></span>: <span localize="CANNOT_COMPLY_EX"></span></p></div>
-</fieldset>
-
-<label class="_issues" localize="STATISTICS"></label>
-<fieldset class="_issues">
-    <div class="downloading"><div>
-        <label localize="DOWNLOADING"></label>
-        <label id="downloading"></label>
-    </div></div>
-
-    <div class="resuming"><div>
-        <label localize="RESUMING_AT"></label>
-        <label id="resuming"></label>
-    </div></div>
-</fieldset>
-
-<label localize="MODIFICATIONS"></label>
-<fieldset id="modifications">
-</fieldset>
-
-<fieldset class="queue" style="margin-top: 25px;">
-<a href="javascript:queue();" style="text-align: center; color: #2a3f70; font-size: 15px; background-image: none;">
-    <label localize="CONTINUE_QUEUING"></label>
-</div></a>
-</fieldset>
-
-</panel>
-</body></html>
diff --git a/Cydia.app/confirm.js b/Cydia.app/confirm.js
deleted file mode 100644 (file)
index efffdc4..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-$(function () {
-    if (issues == null) {
-        $(".issues").remove();
-
-        var downloading = sizes[0];
-        if (downloading == "0.0 B")
-            $(".downloading").remove();
-        else
-        $("#downloading").html($.xml(downloading));
-
-        var resuming = sizes[1];
-        if (resuming == "0.0 B")
-            $(".resuming").remove();
-        else
-        $("#resuming").html($.xml(resuming));
-    } else for (var i = 0; i != issues.length; ++i) {
-        document.title = cydia.localize("CANNOT_COMPLY");
-
-        $(".queue").remove();
-
-        $("._issues").remove();
-
-        var issue = issues[i];
-
-        $("#issues").append(
-            "<label style=\"color: #704d4d\">" + $.xml(issue[0]) + "</label>" +
-            "<fieldset style=\"background-color: #dddddd\" class=\"clearfix\" id=\"i" + i + "\"></fieldset>"
-        );
-
-        for (var j = 1; j != issue.length; ++j) {
-            var entry = issue[j];
-            var type = entry[0];
-            if (type == "PreDepends")
-                type = "Depends";
-            var version = entry[1];
-            if (entry.length >= 4)
-                version += " " + entry[3];
-            $("#i" + i).append("<div class=\"clearfix\"><div>" +
-                "<label>" + $.xml(type) + "</label>" +
-                "<label>" + $.xml(version) + "</label>" +
-            "</div></div>");
-        }
-    }
-
-    var keys = [
-        "INSTALL",
-        "REINSTALL",
-        "UPGRADE",
-        "DOWNGRADE",
-        "REMOVE"
-    ];
-
-    for (var i = 0; i != 5; ++i) {
-        var list = changes[i];
-        var length = list.length;
-
-        if (length != 0) {
-            $("#modifications").append("<div class=\"clearfix\"><div>" +
-                "<label>" + cydia.localize($.xml(keys[i])) + "</label>" +
-                "<label id=\"c" + i + "\"></label>" +
-            "</div></div>");
-
-            var value = "";
-            for (var j = 0; j != length; ++j) {
-                if (j != 0)
-                    value += "<br/>";
-                value += $.xml(list[j]);
-            }
-
-            $("#c" + i).html(value);
-        }
-    }
-});
diff --git a/Cydia.app/console.png b/Cydia.app/console.png
deleted file mode 100644 (file)
index dba3788..0000000
Binary files a/Cydia.app/console.png and /dev/null differ
diff --git a/Cydia.app/email.png b/Cydia.app/email.png
deleted file mode 100644 (file)
index 1aa20b3..0000000
Binary files a/Cydia.app/email.png and /dev/null differ
diff --git a/Cydia.app/error.html b/Cydia.app/error.html
deleted file mode 100644 (file)
index a68ff76..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="NETWORK_ERROR"></title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-
-    <style>
-        body {
-            background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
-            background-size: 7px 1px;
-            display: table;
-            font-family: Helvetica;
-            height: 337px;
-            margin: 0;
-            text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0
-        }
-
-        div.page {
-            display: table-cell;
-            text-align: center;
-            margin: 0 auto;
-            vertical-align: middle;
-            width: 320px;
-        }
-
-        div.title {
-            font-size: 32px;
-        }
-
-        div.error {
-            font-size: 24px;
-        }
-    </style>
-</head><body><div class="page">
-
-<div class="title" localize="UNABLE_TO_LOAD"></div>
-
-<div class="error">(<script>
-    document.write(decodeURI(location.search.substring(1)));
-</script>)</div>
-
-</div></body></html>
diff --git a/Cydia.app/expanded.png b/Cydia.app/expanded.png
deleted file mode 100644 (file)
index 9efce56..0000000
Binary files a/Cydia.app/expanded.png and /dev/null differ
diff --git a/Cydia.app/filesystem.png b/Cydia.app/filesystem.png
deleted file mode 100644 (file)
index 1bb23fe..0000000
Binary files a/Cydia.app/filesystem.png and /dev/null differ
diff --git a/Cydia.app/folder.png b/Cydia.app/folder.png
deleted file mode 100644 (file)
index b628e95..0000000
Binary files a/Cydia.app/folder.png and /dev/null differ
diff --git a/Cydia.app/folder@2x.png b/Cydia.app/folder@2x.png
deleted file mode 100644 (file)
index af3009c..0000000
Binary files a/Cydia.app/folder@2x.png and /dev/null differ
diff --git a/Cydia.app/green-dn.png b/Cydia.app/green-dn.png
deleted file mode 100644 (file)
index c311acd..0000000
Binary files a/Cydia.app/green-dn.png and /dev/null differ
diff --git a/Cydia.app/green-up.png b/Cydia.app/green-up.png
deleted file mode 100644 (file)
index c335b24..0000000
Binary files a/Cydia.app/green-up.png and /dev/null differ
diff --git a/Cydia.app/home-Selected.png b/Cydia.app/home-Selected.png
deleted file mode 100644 (file)
index c02c120..0000000
Binary files a/Cydia.app/home-Selected.png and /dev/null differ
diff --git a/Cydia.app/home-Selected@2x.png b/Cydia.app/home-Selected@2x.png
deleted file mode 100644 (file)
index 748be33..0000000
Binary files a/Cydia.app/home-Selected@2x.png and /dev/null differ
diff --git a/Cydia.app/home.png b/Cydia.app/home.png
deleted file mode 100644 (file)
index 0611697..0000000
Binary files a/Cydia.app/home.png and /dev/null differ
diff --git a/Cydia.app/home@2x.png b/Cydia.app/home@2x.png
deleted file mode 100644 (file)
index 72b7297..0000000
Binary files a/Cydia.app/home@2x.png and /dev/null differ
diff --git a/Cydia.app/icon-72.png b/Cydia.app/icon-72.png
deleted file mode 100644 (file)
index 1dbce13..0000000
Binary files a/Cydia.app/icon-72.png and /dev/null differ
diff --git a/Cydia.app/icon.png b/Cydia.app/icon.png
deleted file mode 100644 (file)
index 61d51dd..0000000
Binary files a/Cydia.app/icon.png and /dev/null differ
diff --git a/Cydia.app/icon@2x.png b/Cydia.app/icon@2x.png
deleted file mode 100644 (file)
index 1ec010c..0000000
Binary files a/Cydia.app/icon@2x.png and /dev/null differ
diff --git a/Cydia.app/iconClassic.png b/Cydia.app/iconClassic.png
deleted file mode 100644 (file)
index 384c582..0000000
Binary files a/Cydia.app/iconClassic.png and /dev/null differ
diff --git a/Cydia.app/id.png b/Cydia.app/id.png
deleted file mode 100644 (file)
index f168812..0000000
Binary files a/Cydia.app/id.png and /dev/null differ
diff --git a/Cydia.app/install.png b/Cydia.app/install.png
deleted file mode 100644 (file)
index 9e30898..0000000
Binary files a/Cydia.app/install.png and /dev/null differ
diff --git a/Cydia.app/install@2x.png b/Cydia.app/install@2x.png
deleted file mode 100644 (file)
index dfb8212..0000000
Binary files a/Cydia.app/install@2x.png and /dev/null differ
diff --git a/Cydia.app/installed.png b/Cydia.app/installed.png
deleted file mode 100644 (file)
index 2f86f0a..0000000
Binary files a/Cydia.app/installed.png and /dev/null differ
diff --git a/Cydia.app/installed@2x.png b/Cydia.app/installed@2x.png
deleted file mode 100644 (file)
index ab86df2..0000000
Binary files a/Cydia.app/installed@2x.png and /dev/null differ
diff --git a/Cydia.app/installing.png b/Cydia.app/installing.png
deleted file mode 100644 (file)
index 6332fef..0000000
Binary files a/Cydia.app/installing.png and /dev/null differ
diff --git a/Cydia.app/loading.html b/Cydia.app/loading.html
deleted file mode 100644 (file)
index 33b2637..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title>Loading</title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <base target="_blank"/>
-</head><body>
-    <div style="padding: 5px 7px">
-        <span style="color: #4d4d70; font-weight: normal; font-size: 16px">
-            <div style="display: inline-block; background-image: url(menes/indicator-c7ced5-4d4d70.gif); width: 16px; height: 16px; margin: 2px 0 -2px 0"></div>
-            <span style="margin: 0 4px">Loading...</span>
-        </span>
-    </div>
-</body></html>
diff --git a/Cydia.app/localize.js b/Cydia.app/localize.js
deleted file mode 100644 (file)
index 9be82d0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-document.addEventListener("DOMContentLoaded", function () {
-    var results = document.evaluate("//*[@localize]", document, null, XPathResult.ANY_TYPE, null);
-    var result, nodes = [];
-    while (result = results.iterateNext())
-        nodes.push(result);
-    for (var index in nodes) {
-        var node = nodes[index];
-        var key = node.getAttribute('localize');
-        var value = cydia.localize(key, node.innerHTML);
-        if (node.nodeName == 'TITLE')
-            document.title = value;
-        else
-            node.innerHTML = value;
-    }
-});
diff --git a/Cydia.app/manage.html b/Cydia.app/manage.html
deleted file mode 100644 (file)
index bba3762..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="MANAGE"></title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-
-    <style>
-        body {
-            background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
-            background-size: 7px 1px;
-            display: table;
-            font-family: Helvetica;
-            height: 337px;
-            margin: 0;
-            padding: 0;
-            -webkit-text-size-adjust: none;
-            -webkit-user-select: none;
-        }
-
-        div.page {
-            display: table-cell;
-            text-align: center;
-            margin: 0 auto;
-            vertical-align: middle;
-            width: 320px;
-        }
-
-        a.giant-button {
-            background-color: rgba(0, 0, 0, .15);
-            -webkit-border-radius: 10px;
-            color: #193250;
-            display: block;
-            margin: 10px;
-            text-decoration: none;
-        }
-
-        a.giant-button > img {
-            display: inline-block;
-            float: left;
-            height: 80px;
-            margin: 10px -10px 0 10px;
-            width: 80px;
-            vertical-align: middle;
-        }
-
-        a.giant-button > div.contents {
-            display: inline-block;
-            width: 190px;
-            margin: 5px 10px 17px 10px;
-        }
-
-        a.giant-button > div.contents > label {
-            display: block;
-            font-size: 28px;
-            margin: 8px 0 8px 0;
-            text-align: center;
-            text-shadow: rgba(200, 200, 200, 0.75) 1px 1px 0;
-        }
-
-        a.giant-button > div.contents > div {
-            display: block;
-            font-size: 14px;
-            margin-left: 4px;
-            text-align: center;
-        }
-    </style>
-</head><body><div class="page">
-<div class="dialog">
-    <div class="panel">
-
-<a href="cydia://packages" class="giant-button">
-    <img src="packages.png"/>
-    <div class="contents">
-        <label localize="PACKAGES"></label>
-        <div localize="PACKAGES_EX"></div>
-    </div>
-</a>
-
-<a href="cydia://sources" class="giant-button">
-    <img src="sources.png"/>
-    <div class="contents">
-        <label localize="SOURCES"></label>
-        <div localize="SOURCES_EX"></div>
-    </div>
-</a>
-
-<a href="cydia://storage" class="giant-button">
-    <img src="storage.png"/>
-    <div class="contents">
-        <label localize="STORAGE"></label>
-        <div localize="STORAGE_EX"></div>
-    </div>
-</a>
-
-    </div>
-</div>
-</div></body></html>
diff --git a/Cydia.app/manage.png b/Cydia.app/manage.png
deleted file mode 100644 (file)
index 9513a7c..0000000
Binary files a/Cydia.app/manage.png and /dev/null differ
diff --git a/Cydia.app/manage@2x.png b/Cydia.app/manage@2x.png
deleted file mode 100644 (file)
index cfb8c13..0000000
Binary files a/Cydia.app/manage@2x.png and /dev/null differ
diff --git a/Cydia.app/menes/chevron.png b/Cydia.app/menes/chevron.png
deleted file mode 100644 (file)
index 6ff8205..0000000
Binary files a/Cydia.app/menes/chevron.png and /dev/null differ
diff --git a/Cydia.app/menes/chevron@2x.png b/Cydia.app/menes/chevron@2x.png
deleted file mode 100644 (file)
index 9905c17..0000000
Binary files a/Cydia.app/menes/chevron@2x.png and /dev/null differ
diff --git a/Cydia.app/menes/indicator-c7ced5-4d4d70.gif b/Cydia.app/menes/indicator-c7ced5-4d4d70.gif
deleted file mode 100644 (file)
index e41bb96..0000000
Binary files a/Cydia.app/menes/indicator-c7ced5-4d4d70.gif and /dev/null differ
diff --git a/Cydia.app/menes/menes.js b/Cydia.app/menes/menes.js
deleted file mode 100644 (file)
index dc210bb..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-/* XXX: this message is ultra-lame */
-var _assert = function (expr, value) {
-    if (!expr) {
-        var message = "_assert(" + value + ")";
-        console.log(message);
-        throw message;
-    }
-}
-
-// Compatibility {{{
-if (typeof Array.prototype.push != "function")
-    Array.prototype.push = function (value) {
-        this[this.length] = value;
-    };
-// }}}
-
-var $ = function (arg, doc) {
-    if (this.magic_ != $.prototype.magic_)
-        return new $(arg);
-
-    if (arg == null)
-        arg = [];
-
-    var type = $.type(arg);
-
-    if (type == "function")
-        $.ready(arg);
-    else if (type == "string") {
-        if (typeof doc == 'undefined')
-            doc = document;
-        if (arg.charAt(0) == '#') {
-            /* XXX: this is somewhat incorrect-a-porter */
-            var element = doc.getElementById(arg.substring(1));
-            return $(element == null ? [] : [element]);
-        } else if (arg.charAt(0) == '.')
-            return $(doc.getElementsByClassName(arg.substring(1)));
-        else
-            return $([doc]).descendants(arg);
-    } else if (typeof arg.length != 'undefined') {
-        _assert(typeof doc == 'undefined', "non-query with document to $");
-        this.set(arg);
-        return this;
-    } else _assert(false, "unknown argument to $: " + typeof arg);
-};
-
-$.xml = function (value) {
-    return value
-        .replace(/&/, "&amp;")
-        .replace(/</, "&lt;")
-        .replace(/>/, "&gt;")
-        .replace(/"/, "&quot;")
-        .replace(/'/, "&apos;")
-    ;
-}
-
-$.type = function (value) {
-    var type = typeof value;
-
-    if ((type == "function" || type == "object") && value.toString != null) {
-        var string = value.toString();
-        if (string.substring(0, 8) == "[object ")
-            return string.substring(8, string.length - 1);
-    }
-
-    return type;
-};
-
-(function () {
-    var ready_ = null;
-
-    $.ready = function (_function) {
-        if (ready_ == null) {
-            ready_ = [];
-
-            document.addEventListener("DOMContentLoaded", function () {
-                for (var i = 0; i != ready_.length; ++i)
-                    ready_[i]();
-            }, false);
-        }
-
-        ready_.push(_function);
-    };
-})();
-
-/* XXX: verify arg3 overflow */
-$.each = function (values, _function, arg0, arg1, arg2) {
-    for (var i = 0, e = values.length; i != e; ++i)
-        _function(values[i], arg0, arg1, arg2);
-};
-
-/* XXX: verify arg3 overflow */
-$.map = function (values, _function, arg0, arg1, arg2) {
-    var mapped = [];
-    for (var i = 0, e = values.length; i != e; ++i)
-        mapped.push(_function(values[i], arg0, arg1, arg2));
-    return mapped;
-};
-
-$.array = function (values) {
-    if (values.constructor == Array)
-        return values;
-    _assert(typeof values.length != 'undefined', "$.array on underlying non-array");
-    var array = [];
-    for (var i = 0; i != values.length; ++i)
-        array.push(values[i]);
-    return array;
-};
-
-$.document = function (node) {
-    for (;;) {
-        var parent = node.parentNode;
-        if (parent == null)
-            return node;
-        node = parent;
-    }
-};
-
-$.reclass = function (_class) {
-    return new RegExp('(\\s|^)' + _class + '(\\s|$)');
-};
-
-$.prototype = {
-    magic_: 2041085062,
-
-    add: function (nodes) {
-        Array.prototype.push.apply(this, $.array(nodes));
-    },
-
-    at: function (name, value) {
-        if (typeof value == 'undefined')
-            return $.map(this, function (node) {
-                return node.getAttribute(name);
-            });
-        else if (value == null)
-            $.each(this, function (node) {
-                node.removeAttribute();
-            });
-        else
-            $.each(this, function (node) {
-                node.setAttribute(name, value);
-            });
-    },
-
-    set: function (nodes) {
-        this.length = 0;
-        this.add(nodes);
-    },
-
-    /* XXX: verify arg3 overflow */
-    each: function (_function, arg0, arg1, arg2) {
-        $.each(this, function (node) {
-            _function($([node]), arg0, arg1, arg2);
-        });
-    },
-
-    css: function (name, value) {
-        $.each(this, function (node) {
-            node.style[name] = value;
-        });
-    },
-
-    addClass: function (_class) {
-        $.each(this, function (node) {
-            if (!$([node]).hasClass(_class)[0])
-                node.className += " " + _class;
-        });
-    },
-
-    blur: function () {
-        $.each(this, function (node) {
-            node.blur();
-        });
-    },
-
-    focus: function () {
-        $.each(this, function (node) {
-            node.focus();
-        });
-    },
-
-    removeClass: function (_class) {
-        $.each(this, function (node) {
-            node.className = node.className.replace($.reclass(_class), ' ');
-        });
-    },
-
-    hasClass: function (_class) {
-        return $.map(this, function (node) {
-            return node.className.match($.reclass(_class));
-        });
-    },
-
-    append: function (children) {
-        if ($.type(children) == "string")
-            $.each(this, function (node) {
-                var doc = $.document(node);
-
-                // XXX: implement wrapper system
-                var div = doc.createElement("div");
-                div.innerHTML = children;
-
-                while (div.childNodes.length != 0) {
-                    var child = div.childNodes[0];
-                    node.appendChild(child);
-                }
-            });
-        else
-            $.each(this, function (node) {
-                $.each(children, function (child) {
-                    node.appendChild(child);
-                });
-            });
-    },
-
-    xpath: function (expression) {
-        var value = $([]);
-
-        $.each(this, function (node) {
-            var doc = $.document(node);
-            var results = doc.evaluate(expression, node, null, XPathResult.ANY_TYPE, null);
-            var result;
-            while (result = results.iterateNext())
-                value.add([result]);
-        });
-
-        return value;
-    },
-
-    clone: function (deep) {
-        return $($.map(this, function (node) {
-            return node.cloneNode(deep);
-        }));
-    },
-
-    descendants: function (expression) {
-        var descendants = $([]);
-
-        $.each(this, function (node) {
-            var nodes = node.getElementsByTagName(expression);
-            descendants.add(nodes);
-        });
-
-        return descendants;
-    },
-
-    remove: function () {
-        $.each(this, function (node) {
-            node.parentNode.removeChild(node);
-        });
-    }
-};
-
-$.scroll = function (x, y) {
-    window.scrollTo(x, y);
-};
-
-// XXX: document.all?
-$.all = function (doc) {
-    if (typeof doc == 'undefined')
-        doc = document;
-    return $(doc.getElementsByTagName("*"));
-};
-
-$.inject = function (a, b) {
-    if ($.type(a) == "string") {
-        $.prototype[a] = function (value) {
-            if (typeof value == 'undefined')
-                return $.map(this, function (node) {
-                    return b.get(node);
-                });
-            else
-                $.each(this, function (node, value) {
-                    b.set(node, value);
-                }, value);
-        };
-    } else for (var name in a)
-        $.inject(name, a[name]);
-};
-
-$.inject({
-    _default: {
-        get: function (node) {
-            return node.style.defaultValue;
-        },
-        set: function (node, value) {
-            node.style.defaultValue = value;
-        }
-    },
-
-    height: {
-        get: function (node) {
-            return node.height;
-        },
-        set: function (node, value) {
-            node.height = value;
-        }
-    },
-
-    html: {
-        get: function (node) {
-            return node.innerHTML;
-        },
-        set: function (node, value) {
-            node.innerHTML = value;
-        }
-    },
-
-    href: {
-        get: function (node) {
-            return node.href;
-        },
-        set: function (node, value) {
-            node.href = value;
-        }
-    },
-
-    name: {
-        get: function (node) {
-            return node.name;
-        },
-        set: function (node, value) {
-            node.name = value;
-        }
-    },
-
-    parent: {
-        get: function (node) {
-            return node.parentNode;
-        }
-    },
-
-    src: {
-        get: function (node) {
-            return node.src;
-        },
-        set: function (node, value) {
-            node.src = value;
-        }
-    },
-
-    type: {
-        get: function (node) {
-            return node.localName;
-        }
-    },
-
-    value: {
-        get: function (node) {
-            return node.value;
-        },
-        set: function (node, value) {
-            // XXX: do I really need this?
-            if (true || node.localName != "select")
-                node.value = value;
-            else {
-                var options = node.options;
-                for (var i = 0, e = options.length; i != e; ++i)
-                    if (options[i].value == value) {
-                        if (node.selectedIndex != i)
-                            node.selectedIndex = i;
-                        break;
-                    }
-            }
-        }
-    },
-
-    width: {
-        get: function (node) {
-            return node.offsetWidth;
-        }
-    }
-});
-
-// Query String Parsing {{{
-$.query = function () {
-    var args = {};
-
-    var search = location.search;
-    if (search != null) {
-        _assert(search[0] == "?", "query string without ?");
-
-        var values = search.substring(1).split("&");
-        for (var index in values) {
-            var value = values[index]
-            var equal = value.indexOf("=");
-            var name;
-
-            if (equal == -1) {
-                name = value;
-                value = null;
-            } else {
-                name = value.substring(0, equal);
-                value = value.substring(equal + 1);
-                value = decodeURIComponent(value);
-            }
-
-            name = decodeURIComponent(name);
-            if (typeof args[name] == "undefined")
-                args[name] = [];
-            if (value != null)
-                args[name].push(value);
-        }
-    }
-
-    return args;
-};
-// }}}
-// Event Registration {{{
-// XXX: unable to remove registration
-$.prototype.event = function (event, _function) {
-    $.each(this, function (node) {
-        // XXX: smooth over this pointer ugliness
-        if (node.addEventListener)
-            node.addEventListener(event, _function, false);
-        else if (node.attachEvent)
-            node.attachEvent("on" + event, _function);
-        else
-            // XXX: multiple registration SNAFU
-            node["on" + event] = _function;
-    });
-};
-
-$.each([
-    "click", "load", "submit"
-], function (event) {
-    $.prototype[event] = function (_function) {
-        if (typeof _function == 'undefined')
-            _assert(false, "undefined function to $.[event]");
-        else
-            this.event(event, _function);
-    };
-});
-// }}}
-// Timed Animation {{{
-$.interpolate = function (duration, event) {
-    var start = new Date();
-
-    var next = function () {
-        setTimeout(update, 0);
-    };
-
-    var update = function () {
-        var time = new Date() - start;
-
-        if (time >= duration)
-            event(1);
-        else {
-            event(time / duration);
-            next();
-        }
-    };
-
-    next();
-};
-// }}}
-// AJAX Requests {{{
-// XXX: abstract and implement other cases
-$.xhr = function (url, method, headers, data, events) {
-    var xhr = new XMLHttpRequest();
-    xhr.open(method, url, true);
-
-    for (var name in headers)
-        xhr.setRequestHeader(name.replace(/_/, "-"), headers[name]);
-
-    if (events == null)
-        events = {};
-
-    xhr.onreadystatechange = function () {
-        if (xhr.readyState == 4) {
-            var status = xhr.status;
-            var text = xhr.responseText;
-            if (events.response != null)
-                events.response(status, text);
-            if (status == 200) {
-                if (events.success != null)
-                    events.success(text);
-            } else {
-                if (events.failure != null)
-                    events.failure(status);
-            }
-        }
-    };
-
-    xhr.send(data);
-};
-
-$.call = function (url, post, onsuccess) {
-    var events = {};
-
-    if (onsuccess != null)
-        events.complete = function (text) {
-            onsuccess(eval(text));
-        };
-
-    if (post == null)
-        $.xhr(url, "POST", null, null, events);
-    else
-        $.xhr(url, "POST", {
-            Content_Type: "application/json"
-        }, $.json(post), events);
-};
-// }}}
-// WWW Form URL Encoder {{{
-$.form = function (parameters) {
-    var data = "";
-
-    var ampersand = false;
-    for (var name in parameters) {
-        if (!ampersand)
-            ampersand = true;
-        else
-            data += "&";
-
-        var value = parameters[name];
-
-        data += escape(name);
-        data += "=";
-        data += escape(value);
-    }
-
-    return data;
-};
-// }}}
-// JSON Serializer {{{
-$.json = function (value) {
-    if (value == null)
-        return "null";
-
-    var type = $.type(value);
-
-    if (type == "number")
-        return value;
-    else if (type == "string")
-        return "\"" + value
-            .replace(/\\/, "\\\\")
-            .replace(/\t/, "\\t")
-            .replace(/\r/, "\\r")
-            .replace(/\n/, "\\n")
-            .replace(/"/, "\\\"")
-        + "\"";
-    else if (value.constructor == Array) {
-        var json = "[";
-        var comma = false;
-
-        for (var i = 0; i != value.length; ++i) {
-            if (!comma)
-                comma = true;
-            else
-                json += ",";
-
-            json += $.json(value[i]);
-        }
-
-        return json + "]";
-    } else if (
-        value.constructor == Object &&
-        value.toString() == "[object Object]"
-    ) {
-        var json = "{";
-        var comma = false;
-
-        for (var name in value) {
-            if (!comma)
-                comma = true;
-            else
-                json += ",";
-
-            json += name + ":" + $.json(value[name]);
-        }
-        return json + "}";
-    } else {
-        return value;
-    }
-};
-// }}}
diff --git a/Cydia.app/menes/style.css b/Cydia.app/menes/style.css
deleted file mode 100644 (file)
index 677a2fc..0000000
+++ /dev/null
@@ -1,885 +0,0 @@
-/* iPhone.css - iPhone Interface Cascading Style Sheet
- * Copyright (C) 2007-2008  Jay Freeman (saurik)
-*/
-
-/*
- *        Redistribution and use in source and binary
- * forms, with or without modification, are permitted
- * provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer in the documentation
- *    and/or other materials provided with the
- *    distribution.
- * 3. The name of the author may not be used to endorse
- *    or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* .clearfix {{{ */
-.clearfix:after {
-    content: ".";
-    display: block;
-    clear: both;
-    visibility: hidden;
-    line-height: 0;
-    height: 0;
-}
-
-.clearfix {
-    display: block;
-}
-/* }}} */
-
-* {
-    border: 0;
-    -moz-border-radius: 0;
-    -webkit-border-radius: 0;
-    box-sizing: border-box;
-    -moz-box-sizing: border-box;
-    -ms-box-sizing: border-box;
-    -webkit-box-sizing: border-box;
-    /*font-family: inherit;*/
-    font-size: 100%;
-    font-style: inherit;
-    font-weight: inherit;
-    margin: 0;
-    outline: 0;
-    padding: 0;
-    text-decoration: none;
-    vertical-align: baseline;
-}
-
-a {
-    color: inherit;
-}
-
-sup {
-    font-size: smaller;
-    margin-top: -6px;
-    position: relative;
-    top: -6px;
-}
-
-select {
-    border: 1px solid #999999;
-}
-
-panel {
-    display: block;
-    width: 320px;
-}
-
-body {
-    font-family: Helvetica, Arial;
-    -webkit-text-size-adjust: none;
-    -webkit-user-select: none;
-    margin: 0 auto;
-    width: 320px;
-}
-
-body.white {
-    background-color: #ffffff;
-}
-
-body.pinstripe {
-    background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
-    background-size: 7px 1px;
-}
-
-dialog {
-    display: block;
-    position: absolute;
-    width: 100%;
-}
-
-dialog > panel {
-    display: block;
-}
-
-a {
-    color: blue;
-    text-underline-style: dotted;
-}
-
-strong {
-    font-weight: bold
-}
-
-pre, tt {
-    font-family: monospace;
-}
-
-pre {
-    letter-spacing: -2px;
-}
-
-em {
-    font-style: italic;
-}
-
-.default {
-    color: #aaaabb;
-}
-
-.deleted {
-    display: none;
-}
-
-/* #toolbar {{{ */
-dialog > toolbar {
-    background: url(toolbar.png) #6d84a2 repeat-x;
-    border-bottom: 1px solid #2d3642;
-    height: 45px;
-    padding: 10px;
-}
-
-dialog > toolbar > h1 {
-    color: #ffffff;
-    font-size: 20px;
-    font-weight: bold;
-    height: 100%;
-    margin: 1px auto 0 auto;
-    text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
-    text-align: center;
-    white-space: nowrap;
-}
-/* }}} */
-/* (back|forward)-button {{{ */
-dialog > toolbar > a.back-button,
-dialog > toolbar > a.forward-button {
-    color: #ffffff;
-    font-size: 12px;
-    font-weight: bold;
-    height: 30px;
-    line-height: 30px;
-    margin-top: -28px;
-    padding: 0 3px;
-    text-decoration: none;
-    text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
-    white-space: nowrap;
-}
-
-dialog > toolbar > a.back-button {
-    -webkit-border-image: url(backButton.png) 0 8 0 14;
-    border-width: 0 8px 0 14px;
-    float: left;
-}
-
-dialog > toolbar > a.forward-button {
-    -webkit-border-image: url(toolButton.png) 0 5 0 5;
-    border-width: 0 5px;
-    float: right;
-}
-/* }}} */
-
-panel > block {
-    /*background-color: #ccd1d5;*/
-    /*background-color: white;*/
-    /*background-color: #c7ced5;*/
-    background-color: transparent;
-    //background-color: #ffffff;
-    border-bottom: 1px solid #999999;
-    border-top: 1px solid #999999;
-    border-left: 1px dotted #999999;
-    border-right: 1px dotted #999999;
-    -moz-border-radius: 9px;
-    -webkit-border-radius: 9px;
-    //border: 1px solid #999999;
-    display: block;
-    font-size: 16px;
-    margin: 9px;
-    padding: 0 10px;
-}
-
-panel > fieldset > div > hr,
-panel > block > hr {
-    border-top: 1px dashed #999999;
-}
-
-panel > fieldset {
-    background-color: #ffffff;
-    border: 1px solid #999999;
-    -moz-border-radius: 9px;
-    -webkit-border-radius: 9px;
-    font-size: 16px;
-    margin: 9px;
-}
-
-panel > input[type="submit"] {
-    /*-webkit-border-image: url(whiteButton.png) 0 12 0 12;
-    -moz-border-radius: 0;
-    -webkit-border-radius: 0;
-    border-width: 0px 12px;*/
-    border: none;
-    color: #000000;
-    display: block;
-    font-size: 20px;
-    font-weight: bold;
-    margin: 9px;
-    height: 44px;
-    padding: 10px;
-    text-align: center;
-    width: 302px;
-}
-
-list > label {
-    background: #a7b3bc url(cydia://uikit-image/UISectionListHeaderBackground.png);
-    background-repeat: repeat-x no-repeat-y;
-    margin-bottom: 0px;
-    padding: 4px 15px 1px 15px;
-    display: block;
-    color: white;
-    font-size: inherit;
-    font-weight: bold;
-    text-shadow: rgba(0, 0, 0, 0.5) 0px 1px 0;
-}
-
-panel > label {
-    display: block;
-    margin: 13px 0 -4px 24px;
-    line-height: 24px;
-    font-size: inherit;
-    font-weight: bold;
-    color: #4d4d70;
-    text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0;
-}
-
-panel > fieldset > a,
-panel > fieldset > div,
-panel > fieldset > textarea {
-    border-top: 1px solid #999999;
-}
-
-/* XXX: should be a.left:nth-last-child(2) */
-panel > fieldset > a.left,
-panel > fieldset > a.middle,
-panel > fieldset > a:first-child,
-panel > fieldset > div:first-child,
-panel > fieldset > textarea:first-child {
-    border-top: 0;
-}
-
-list > fieldset > a,
-list > fieldset > div,
-list > fieldset > textarea {
-    border-bottom: 1px solid #e0e0e0;
-}
-
-fieldset > a:not([type="ad"]),
-fieldset > div,
-fieldset > textarea {
-    /* XXX: small differences due to font bugs */
-    padding: 12px 14px 10px 14px;
-}
-
-/*fieldset > a:not([type="ad"]):last-child,
-fieldset > div:last-child {
-    padding-bottom: 10px;
-}*/
-
-fieldset > a[type="ad"] {
-    /* XXX: small differences due to font bugs */
-    padding: 4px 4px 2px 5px;
-}
-
-panel > fieldset > a[type="ad"]:first-child > div:first-child,
-panel > fieldset > a[type="comment"]:first-child > div:first-child,
-panel > fieldset > a[type="profile"]:first-child > div:first-child,
-panel > fieldset > a[type="thumb"]:first-child > div:first-child {
-    -moz-border-radius-topleft: 9px;
-    -webkit-border-top-left-radius: 9px;
-}
-
-panel > fieldset > a[type="ad"]:last-child > div:first-child,
-panel > fieldset > a[type="comment"]:last-child > div:first-child,
-panel > fieldset > a[type="profile"]:last-child > div:first-child,
-panel > fieldset > a[type="thumb"]:last-child > div:first-child {
-    -moz-border-radius-bottomleft: 9px;
-    -webkit-border-bottom-left-radius: 9px;
-}
-
-fieldset > a[type="ad"] > div:first-child {
-    border: 1px solid #999999;
-}
-
-list > fieldset > a[type="comment"] > div:first-child,
-list > fieldset > a[type="profile"] > div:first-child,
-list > fieldset > a[type="thumb"] > div:first-child {
-    border: 1px solid #e0e0e0;
-}
-
-panel > fieldset > a[type="comment"] > div:first-child {
-    border: 1px solid #999999;
-    border-bottom-style: dashed;
-}
-
-panel > fieldset > a[type="profile"] > div:first-child,
-panel > fieldset:not(.header) > a[type="thumb"] > div:first-child {
-    border: 1px solid #999999;
-}
-
-div[tile] {
-    float: right;
-    height: 30px;
-    width: 30px;
-}
-
-div[tile="app"]   { background-image: url(http://cache.saurik.com/cydia/tile/app.png);   }
-div[tile="call"]  { background-image: url(http://cache.saurik.com/cydia/tile/call.png);  }
-div[tile="map"]   { background-image: url(http://cache.saurik.com/cydia/tile/map.png);   }
-div[tile="media"] { background-image: url(http://cache.saurik.com/cydia/tile/media.png); }
-div[tile="music"] { background-image: url(http://cache.saurik.com/cydia/tile/video.png); }
-div[tile="site"]  { background-image: url(http://cache.saurik.com/cydia/tile/site.png);  }
-
-fieldset > a[type="ad"] > div:first-child {
-    background-repeat: no-repeat;
-    background-position: center center;
-    border-right: none;
-    display: inline-block;
-    height: 40px;
-    line-height: 38px;
-    /* XXX: small differences due to font bugs */
-    /* XXX: 1px difference due to border stupidity */
-    margin: -5px 5px -3px -6px;
-    width: 40px;
-}
-
-panel > fieldset > a[type="comment"] {
-    border-bottom-style: dashed;
-}
-
-fieldset > a[type="comment"] > div:first-child {
-    -webkit-background-size: 44px;
-    height: 44px;
-    width: 44px;
-}
-
-fieldset > a[type="header"] > div:first-child {
-    height: 64px;
-    width: 64px;
-}
-
-fieldset > a[type="profile"] > div:first-child {
-    -webkit-background-size: 50px;
-    height: 50px;
-    width: 50px;
-}
-
-fieldset > a[type="thumb"] > div:first-child  {
-    height: 64px;
-    width: 64px;
-}
-
-fieldset > a[type="comment"] > div:first-child,
-fieldset > a[type="header"] > div:first-child,
-fieldset > a[type="profile"] > div:first-child,
-fieldset > a[type="thumb"] > div:first-child {
-    background-repeat: no-repeat;
-    background-position: center center;
-    display: inline-block;
-    /* XXX: small differences due to font bugs */
-    /* XXX: 1px difference due to border stupidity */
-    margin: -13px 7px -11px -15px;
-}
-
-fieldset > a > img.icon,
-fieldset > div > img.icon {
-    height: auto;
-    /* XXX: small differences due to font bugs */
-    margin: -7px 6px -9px -8px;
-    max-height: 30px;
-    min-width: 30px;
-    width: 30px;
-}
-
-fieldset > a.sixth > img.icon {
-    position: relative;
-    left: 7px;
-}
-
-panel > block > p,
-fieldset > div > p,
-panel > block > ul,
-fieldset > div > ul {
-    margin: 10px 0;
-}
-
-panel > block > ul,
-fieldset > div > ul {
-    margin-left: 13px;
-}
-
-panel > block > p,
-fieldset > div > p {
-    text-align: center;
-}
-
-fieldset > div > p:first-child,
-fieldset > div > ul:first-child {
-    margin-top: 0;
-}
-
-fieldset > div > p:last-child,
-fieldset > div > ul:last-child {
-    margin-bottom: 0;
-}
-
-fieldset > a {
-    color: inherit;
-    display: block;
-}
-
-fieldset > textarea,
-fieldset > div > input:not([type="checkbox"]),
-fieldset > div > select,
-fieldset > div > div > select {
-    background: none;
-    -webkit-box-shadow: none;
-    -webkit-appearance: none;
-}
-
-/* Chevrons {{{ */
-
-fieldset > a[href]:not([type="ad"]),
-fieldset > div > select,
-fieldset > div > div > select {
-    background-repeat: no-repeat;
-    background-image: url(chevron.png);
-}
-
-@media screen and (-webkit-min-device-pixel-ratio: 2) {
-fieldset > a[href]:not([type="ad"]),
-fieldset > div > select,
-fieldset > div > div > select {
-    background-image: url(chevron@2x.png);
-    background-size: 10px 13px;
-} }
-
-/* Horizontal */
-
-list > fieldset > a[href] {
-    background-position: 295px center;
-}
-
-panel > fieldset > a[href] {
-    background-position: 275px center;
-}
-
-panel > fieldset > a[href].half {
-    background-position: 125px center;
-}
-
-panel > fieldset > a[href].third {
-    background-position: 75px center;
-}
-
-panel > fieldset > a[href].sixth {
-    background: none;
-}
-
-list > fieldset > a:not([href]) > select,
-list > fieldset > div > select,
-list > fieldset > div > div > select {
-    background-position: 183px center;
-}
-
-panel > fieldset > a:not([href]) > select,
-panel > fieldset > div > select,
-panel > fieldset > div > div > select {
-    background-position: 163px center;
-}
-
-/* }}} */
-
-fieldset > textarea,
-fieldset > div > input,
-fieldset > div > select,
-fieldset > div > div > select,
-fieldset > a > div > label + label,
-fieldset > div > div > label + label {
-    color: #193250;
-}
-
-fieldset > textarea,
-fieldset > div > input,
-fieldset > div > select,
-fieldset > div > div > select {
-    font-size: 16px;
-}
-
-fieldset > div > input {
-    padding-left: 7px;
-    padding-right: 14px;
-}
-
-fieldset > div > input[type="checkbox"] {
-    border: 1px solid #999999;
-    -moz-border-radius: 7px;
-    -webkit-border-radius: 7px;
-    float: right;
-    margin: -7px -8px;
-    height: 30px;
-    width: 30px;
-}
-
-fieldset > div > select,
-fieldset > div > div > select,
-fieldset > div > input:not([type="checkbox"]) {
-    border: none;
-    float: right;
-    height: 40px;
-    margin: -11px -13px -11px -14px;
-}
-
-panel > fieldset > div > select,
-panel > fieldset > div > div > select,
-panel > fieldset > div > input:not([type="checkbox"]) {
-    width: 187px;
-}
-
-list > fieldset > div > select,
-list > fieldset > div > div > select,
-list > fieldset > div > input:not([type="checkbox"]) {
-    width: 207px;
-}
-
-fieldset > textarea {
-    padding: 10px;
-    width: 320px;
-}
-
-fieldset > div > div,
-fieldset > a > div {
-    display: inline-block;
-}
-
-fieldset > div > div {
-    width: 273px;
-}
-
-fieldset > a[type="ad"] > div:nth-child(2) {
-    width: 218px;
-}
-
-fieldset > a:not([type]) > div {
-    width: 250px;
-}
-
-fieldset > a:not([href]) > img.icon + div,
-fieldset > div > img.icon + div {
-    width: 244px;
-}
-
-fieldset > a[href] > img.icon + div {
-    width: 221px;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2) > label:nth-child(1).unknown {
-    color: #aaaabb;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2) > label:only-child {
-    left: 4px;
-    position: relative;
-    top: 3px;
-}
-
-fieldset > a[type="thumb"] > div:nth-child(2) > label:only-child {
-    position: relative;
-    top: 10px;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2) > label + label {
-    display: block;
-    font-size: 13px;
-    margin-top: 2px;
-}
-
-fieldset > a[type="thumb"] > div:nth-child(2) > label + label {
-    display: block;
-    margin-top: 2px;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2) {
-    width: 207px;
-}
-
-fieldset > a[type="thumb"] > div:nth-child(2) {
-    width: 193px;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2) {
-    margin: -5px 0;
-}
-
-fieldset > a[type="profile"] > div:nth-child(2),
-fieldset > a[type="thumb"] > div:nth-child(2) {
-    vertical-align: top;
-}
-
-fieldset > a > label:first-child,
-fieldset > a > div > label:first-child,
-fieldset > div > label:first-child,
-fieldset > div > div > label:first-child {
-    font-weight: bold;
-}
-
-/* XXX: this doesn't handle icon offsets */
-list > fieldset > a:not([type]) > div > label + label,
-list > fieldset > div > div > label + label {
-    margin-left: 94px;
-}
-
-panel > fieldset > a:not([type]) > div > label + label,
-panel > fieldset > div > div > label + label {
-    float: right;
-    text-align: right;
-}
-
-panel > img {
-    display: block;
-    margin: 9px auto 4px auto;
-    height: auto;
-    width: 300px;
-}
-
-fieldset > a[type="ad"] {
-}
-
-fieldset > a[type="ad"] > div:nth-child(2) {
-    position: relative;
-    vertical-align: top;
-}
-
-fieldset > a[type="ad"] > div > label:first-child {
-    color: #2d2d50;
-    font-size: 13px;
-    font-weight: bold;
-    line-height: 15px;
-}
-
-fieldset > a[type="ad"] > div > label + label {
-    position: absolute;
-    top: 17px;
-    left: 156px;
-    font-size: 9.5px;
-    font-weight: normal;
-}
-
-panel > fieldset > a.middle,
-panel > fieldset > a.right {
-    border-left: 1px solid #999999;
-}
-
-panel > fieldset > a.half {
-    display: inline-block;
-    width: 150px;
-}
-
-panel > fieldset > a.third {
-    display: inline-block;
-    width: 100px;
-}
-
-panel > fieldset > a.sixth {
-    display: inline-block;
-    width: 50px;
-}
-
-fieldset.half > a {
-    background: none;
-    background-position: 120px center;
-}
-
-fieldset.half > a > img.icon + div {
-    width: 65px;
-}
-
-fieldset.right {
-    float: right;
-    margin-left: 10px;
-}
-
-block + fieldset.right,
-fieldset + fieldset.right {
-    margin-top: 0;
-}
-
-fieldset.half {
-    width: 146px;
-}
-
-panel > fieldset.dashed > a,
-panel > fieldset.dashed > div,
-panel > fieldset.dashed > textarea,
-list > fieldset.dashed > a,
-list > fieldset.dashed > div,
-list > fieldset.dashed > textarea {
-    border-style: dashed;
-}
-
-fieldset > a[type="thumb"]:first-child > back {
-    -moz-border-radius-topright: 9px;
-    -webkit-border-top-right-radius: 9px;
-}
-
-fieldset > a[type="thumb"]:last-child > back {
-    -moz-border-radius-bottomright: 9px;
-    -webkit-border-bottom-right-radius: 9px;
-}
-
-fieldset > a[type="thumb"] > back {
-    background-repeat: no-repeat;
-    border: 1px solid #999999;
-    display: block;
-    height: 64px;
-    left: 62px;
-    position: absolute;
-    opacity: 0.2;
-    top: -1px;
-    width: 237px;
-}
-
-.mm {
-    border: 1px solid #999999;
-    -moz-border-radius: 9px;
-    -webkit-border-radius: 9px;
-}
-
-a.mm {
-    display: block;
-    margin: 9px;
-}
-
-div.mm img {
-    height: auto;
-    width: 300px;
-}
-
-fieldset > a.small {
-    font-size: 12px;
-    padding-top: 9px;
-}
-
-fieldset > a.small label {
-    display: inline-block;
-    position: relative;
-    top: 1px;
-}
-
-fieldset > a.small > img.icon {
-    max-height: 22px;
-    min-width: 22px;
-    width: 22px;
-}
-
-fieldset > a.small.half > img.icon + div {
-    width: 79px;
-}
-
-fieldset > a.small.third > img.icon + div {
-    width: 50px;
-}
-
-fieldset > a.small.sixth > img.icon + div {
-    width: 0px;
-}
-
-panel.centered > label {
-    margin-left: 0px;
-    margin-right: 0px;
-    text-align: center;
-}
-
-panel > iframe {
-    margin: -9px 0;
-}
-
-panel > iframe:first-child,
-panel > iframe + iframe {
-    margin-top: 0;
-}
-
-/* Rating Stars {{{ */
-.ratings {
-    margin: -2px 0;
-    text-align: center;
-}
-
-.rated {
-    display: inline-block;
-}
-
-.rated.left {
-    margin-right: 9px;
-}
-
-.rated label {
-    font-weight: bold;
-    margin-right: 3px;
-    position: relative;
-    top: -3px;
-}
-
-.rating {
-    display: inline-block;
-    width: 80px;
-}
-
-.rating .back,
-.rating .fore,
-.rating .star {
-    background: url(http://cache.saurik.com/crystal/16x16/actions/knewstuff.png);
-    height: 16px;
-}
-
-.rating .back,
-.rating .fore {
-    width: 80px;
-}
-
-.rating .star {
-    display: inline-block;
-    width: 16px;
-}
-
-.rating .back {
-    opacity: 0.2;
-}
-
-.rating .fore {
-    /*border-right: 1px solid #999999;*/
-    position: absolute;
-}
-/* }}} */
-
-panel > fieldset.header {
-    background-color: transparent;
-    border: none;
-    margin: -5px 9px -11px 9px;
-}
-
-panel > fieldset.header > a > div > label {
-    color: #4d4d70;
-    text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0;
-}
diff --git a/Cydia.app/package.html b/Cydia.app/package.html
deleted file mode 100644 (file)
index c91b52c..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="DETAILS"></title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="package.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-
-    <!--script type="text/javascript">
-        var count = -1;
-        var loaded = function() {
-            if (count++ != 0)
-                return;
-            $("#depiction-load").remove();
-            $("#depiction-src").css("display", "block");
-        }
-
-        var remove = function() {
-            $(".description").css("display", "block");
-            $(".depiction").remove();
-        }
-    </script-->
-
-    <style>
-        .flip-180 {
-            -webkit-backface-visibility: hidden;
-            -webkit-transform: rotateY(180deg);
-        }
-
-        #icon.flip-180 {
-            -webkit-transition-duration: 2s;
-            -webkit-transition-property: transform;
-        }
-
-        .flip-360 {
-            -webkit-backface-visibility: hidden;
-            -webkit-transform: rotateY(360deg);
-            -webkit-transition-duration: 2s;
-            -webkit-transition-property: transform;
-        }
-
-        .fade-out {
-            opacity: 0;
-            -webkit-transition-property: opacity;
-            -webkit-transition-duration: 2s;
-        }
-
-        .fade-in {
-            opacity: 1;
-            -webkit-transition-property: opacity;
-            -webkit-transition-duration: 2s;
-        }
-
-        #remove {
-            margin-top: 7px;
-            text-align: center;
-        }
-
-        #indicator {
-            left: 20px;
-            position: relative;
-            top: -5px;
-        }
-
-        #remove > a {
-            color: #335588;
-            text-decoration: none;
-        }
-
-        #upper-bar {
-            margin-bottom: 0;
-            margin-top: 10px;
-        }
-
-        #lower-bar {
-            margin-bottom: 10px;
-            margin-top: 0;
-        }
-
-        #warnings {
-            background-color: #ffdddd;
-        }
-
-        #warnings > div > label {
-            color: red;
-        }
-
-        #boundary {
-            float: left;
-            height: 64;
-            width: 64px;
-        }
-
-        #thumb,
-        #icon {
-            background-position: center center;
-            background-repeat: no-repeat;
-            height: 64px;
-            position: absolute;
-            width: 64px;
-        }
-
-        #thumb {
-            -webkit-border-radius: 9px;
-        }
-
-        /* XXX: this style is out of date */
-        #reflection {
-            height: 59px;
-            max-width: 60px;
-            opacity: 0.4;
-            position: absolute;
-            -webkit-transform: matrix(1, 0, 0, -1, 0, 0);
-            width: auto;
-        }
-
-        #id, #author, #maintainer, #sponsor {
-            white-space: nowrap;
-        }
-
-        #header {
-            background: transparent;
-            border: none;
-            position: relative;
-        }
-
-        #header > div {
-            padding: 0;
-        }
-
-        #content {
-            padding: 5px;
-            position: absolute;
-            left: 77px;
-            width: 232px;
-        }
-
-        #lower {
-            margin: 0px 5px;
-        }
-
-        #name {
-            margin-bottom: 13px;
-            font-weight: bold;
-            font-size: 17px;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-        }
-
-        #latest {
-            color: #335588;
-            float: left;
-        }
-
-        a[href].rating {
-            background: 107px 7px no-repeat url(menes/chevron.png);
-        }
-
-        .rating {
-            /*border: 1px solid #999999;*/
-            -webkit-border-radius: 6px;
-            padding: 7px 7px;
-            margin: -7px 0px;
-            float: right;
-            width: 126px;
-        }
-
-        .rating .back,
-        .rating .fore,
-        .rating .star {
-            background: url(star.png);
-        }
-
-        .rating .text {
-            display: inline-block;
-            color: #4d4d70;
-            margin: 0 6px;
-            vertical-align: top;
-        }
-
-        #rating-done {
-            padding-left: 12px;
-        }
-
-        #rating-none,
-        #rating-done {
-            display: none;
-        }
-
-        #depiction-src,
-        #notice-src {
-            height: 1px;
-            width: 320px;
-        }
-    </style>
-</head><body class="pinstripe">
-<panel>
-
-<fieldset id="header">
-    <div>
-        <div id="boundary">
-            <div class="flip-0" id="icon"></div>
-            <div class="flip-180" id="thumb"></div>
-            <!--img id="reflection"/-->
-        </div>
-
-        <div id="content">
-            <div id="name"></div>
-            <div id="latest"></div>
-
-            <a class="rating" id="rating-href">
-                <div id="rating-none">
-                    <div class="star"></div><div class="text" localize="NOT_RATED"></div>
-                </div><div id="rating-done">
-                    <div class="fore" id="rating-value"></div>
-                    <div class="back"></div>
-                </div>
-            </a>
-        </div>
-    </div>
-</fieldset>
-
-<fieldset class="mode">
-    <a>
-        <img class="icon" id="mode-src"/><div>
-        <label localize="PACKAGE_QUEUE"></label>
-        <label id="mode"></label>
-    </div></a>
-</fieldset>
-
-<fieldset id="actions">
-    <a id="settings">
-        <img class="icon" src="settings.png"/><div>
-        <label localize="CHANGE_PACKAGE_SETTINGS"></label>
-    </div></a>
-
-    <a id="author-href" class="author" target="_popup">
-        <img id="author-icon" class="icon" src="email.png"/><div>
-        <label localize="AUTHOR"></label>
-        <label id="author"></label>
-    </div></a>
-
-    <!--div class="commercial">
-        <img class="icon" src="commercial.png"/><div>
-        <label>This is a commercial package!</label>
-    </div></div-->
-
-    <a class="console" href="http://cydia.saurik.com/purpose/console/">
-        <img class="icon" src="console.png"/><div>
-        <label localize="CONSOLE_PACKAGE"></label>
-    </div></a>
-
-    <a id="application">
-        <img class="icon"/><div>
-        <label class="application"></label>
-    </div></a>
-</fieldset>
-
-<fieldset class="warnings" id="warnings">
-    <div id="warning">
-        <img class="icon" src="warning.png"/><div>
-        <label class="warning"></label>
-    </div></div>
-</fieldset>
-
-<iframe
-    class="notice"
-    id="notice-src"
-    frameborder="0"
-    width="320"
-    height="0"
-    target="_top"
-></iframe>
-
-<!--iframe
-    class="activation"
-    id="activation-src"
-    frameborder="0"
-    width="320"
-    height="0"
-    target="_top"
-></iframe-->
-
-<!--div id="remove" class="depiction">
-    <a href="javascript:remove()">Remove Custom Depiction</a>
-</div>
-
-<hr id="upper-bar" class="depiction"/-->
-
-<iframe
-    class="depiction"
-    id="depiction-src"
-    frameborder="0"
-    width="320"
-    height="0"
-    target="_top"
-    onload_="loaded()"
-></iframe>
-
-<!--hr id="lower-bar" class="depiction"/-->
-
-<block class="description"><p id="description"></p></block>
-
-<fieldset class="description homepage">
-    <a class="homepage" id="homepage-href">
-        <img class="icon" src="web.png"/><div>
-        <label localize="MORE_INFORMATION"></label>
-    </div></a>
-</fieldset>
-
-<label class="installed" localize="INSTALLED_DETAILS"></label>
-<fieldset class="installed">
-    <div>
-        <img class="icon" src="version.png"/><div>
-        <label localize="VERSION"></label>
-        <label id="installed"></label>
-    </div></div>
-
-    <a id="files-href">
-        <img class="icon" src="filesystem.png"/><div>
-        <label localize="FILESYSTEM_CONTENT"></label>
-    </div></a>
-</fieldset>
-
-<label localize="PACKAGE_DETAILS"></label>
-<fieldset>
-    <div>
-        <img class="icon" src="id.png"/><div>
-        <label localize="ID"></label>
-        <label id="id"></label>
-    </div></div>
-
-    <div class="section">
-        <img id="section-src" class="icon"/><div>
-        <label localize="SECTION"></label>
-        <label id="section"></label>
-    </div></div>
-
-    <div class="size">
-        <img class="icon" src="expanded.png"/><div>
-        <label localize="EXPANDED_SIZE"></label>
-        <label id="size"></label>
-    </div></div>
-
-    <a id="maintainer-href" class="maintainer" target="_popup">
-        <img id="maintainer-icon" class="icon" src="email.png"/><div>
-        <label localize="MAINTAINER"></label>
-        <label id="maintainer"></label>
-    </div></a>
-
-    <a id="sponsor-href" class="sponsor">
-        <img class="icon" src="web.png"/><div>
-        <label localize="SPONSOR"></label>
-        <label id="sponsor"></label>
-    </div></a>
-
-    <!--a class="trusted" id="trusted">
-        <img class="icon" src="trusted.png"><div>
-        <label localize="REPOSITORY_SIGNATURE"></label>
-    </div></a-->
-
-    <div class="trusted">
-        <img class="icon" src="trusted.png"><div>
-        <label>&nbsp;</label>
-        <label localize="SIGNED_PACKAGE"></label>
-    </div></div>
-</fieldset>
-
-<label class="source" localize="SOURCE_DETAILS"></label>
-<fieldset class="source">
-    <div>
-        <img class="icon" id="source-src"/><div>
-        <label id="source-name"></label>
-    </div></div>
-
-    <div class="source-description" id="source-description"></div>
-</fieldset>
-
-</panel>
-</body></html>
diff --git a/Cydia.app/package.js b/Cydia.app/package.js
deleted file mode 100644 (file)
index b9f85ff..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/*var package = {
-    "name": "MobileTerminal",
-    "latest": "286u-5",
-    "author": {
-        "name": "Allen Porter",
-        "address": "allen.porter@gmail.com"
-    },
-    //"depiction": "http://planet-iphones.com/repository/info/chromium1.3.php",
-    "depiction": "http://cydia.saurik.com/terminal.html",
-    "longDescription": "this is a sample description",
-    "homepage": "http://cydia.saurik.com/terminal.html",
-    "installed": "286u-4",
-    "id": "mobileterminal",
-    "section": "Terminal Support",
-    "size": 552*1024,
-    "maintainer": {
-        "name": "Jay Freeman",
-        "address": "saurik@saurik.com"
-    },
-    "source": {
-        "name": "Telesphoreo Tangelo",
-        "description": "Distribution of Unix Software for the iPhone"
-    }
-};*/
-
-function space(selector, html, max) {
-    var node = $(selector);
-    node.html(html);
-    var width = node.width();
-    if (width > max) {
-        var spacing = (max - node.width()) / (html.length - 1) + "px";
-        node.css("letter-spacing", spacing);
-    }
-}
-
-var swap_, swap = function (on, off, time) {
-    setTimeout(swap_(on, off, time), time);
-};
-
-swap_ = function (on, off, time) {
-    return function () {
-        on.className = 'fade-out';
-        off.className = 'fade-in';
-        swap(off, on, time);
-    };
-};
-
-var special_ = function () {
-    if (package == null)
-        return;
-
-    var id = package.id;
-    var idc = encodeURIComponent(id);
-    var name = package.name;
-    var icon = 'cydia://package-icon/' + idc;
-
-    var api = 'http://cydia.saurik.com/api/';
-    var capi = 'http://cache.cydia.saurik.com/api/';
-
-    var support = package.support;
-
-    var regarding = function (type) {
-        return encodeURIComponent("Cydia/APT(" + type + "): " + name);
-    };
-
-    $("#icon").css("background-image", 'url("' + icon + '")');
-    //$("#reflection").src("cydia://package-icon/" + idc);
-
-    $("#name").html(name);
-    space("#latest", package.latest, 96);
-
-    $.xhr(capi + 'package/' + idc, 'GET', {}, null, {
-        success: function (value) {
-            value = eval(value);
-
-            if (typeof value.notice == "undefined")
-                $(".notice").addClass("deleted");
-            else
-                $("#notice-src").src(value.notice);
-
-            if (typeof value.rating == "undefined")
-                $(".rating").addClass("deleted");
-            else {
-                $("#rating-load").addClass("deleted");
-                $("#rating-href").href(value.reviews);
-
-                var none = $("#rating-none");
-                var done = $("#rating-done");
-
-                if (value.rating == null) {
-                    none.css("display", "block");
-                } else {
-                    done.css("display", "block");
-
-                    $("#rating-value").css('width', 16 * value.rating);
-                }
-            }
-
-            if (typeof value.icon != "undefined" && value.icon != null) {
-                var icon = $("#icon");
-                var thumb = $("#thumb");
-
-                icon[0].className = 'flip-180';
-                thumb[0].className = 'flip-360';
-
-                thumb.css("background-image", 'url("' + value.icon + '")');
-
-                setTimeout(function () {
-                    icon.addClass("deleted");
-                    thumb[0].className = 'flip-0';
-                }, 2000);
-            }
-        },
-
-        failure: function (status) {
-            $(".rating").addClass("deleted");
-        }
-    });
-
-    $("#settings").href("cydia://package-settings/" + idc);
-
-    var mode = package.mode;
-    if (mode == null)
-        $(".mode").addClass("deleted");
-    else {
-        $("#mode").html(cydia.localize(mode));
-        $("#mode-src").src("Modes/" + mode + ".png");
-    }
-
-    var warnings = package.warnings;
-    var length = warnings == null ? 0 : warnings.length;
-    if (length == 0)
-        $(".warnings").addClass("deleted");
-    else {
-        var parent = $("#warnings");
-        var child = $("#warning");
-
-        for (var i = 0; i != length; ++i) {
-            var clone = child.clone(true);
-            clone.addClass("inserted");
-            parent.append(clone);
-            clone.xpath("./div/label").html($.xml(warnings[i]));
-        }
-
-        child.addClass("deleted");
-    }
-
-    var applications = package.applications;
-    var length = applications == null ? 0 : applications.length;
-
-    var child = $("#application");
-
-    /*if (length != 0) {
-        var parent = $("#actions");
-
-        for (var i = 0; i != length; ++i) {
-            var application = applications[i];
-            var clone = child.clone(true);
-            parent.append(clone);
-            clone.href("cydia://launch/" + application[0]);
-            clone.xpath("label").html("Run " + $.xml(application[1]));
-            clone.xpath("img").src(application[2]);
-        }
-    }*/
-
-    child.addClass("deleted");
-
-    var commercial = package.hasTag('cydia::commercial');
-    if (!commercial)
-        $(".commercial").addClass("deleted");
-
-    var _console = package.hasTag('purpose::console');
-    if (!_console)
-        $(".console").addClass("deleted");
-
-    var author = package.author;
-    if (author == null)
-        $(".author").addClass("deleted");
-    else {
-        space("#author", author.name, 160);
-        if (author.address == null)
-            $("#author-icon").addClass("deleted");
-        else if (support == null)
-            $("#author-href").href("mailto:" + author.address + "?subject=" + regarding("A"));
-        else
-            $("#author-href").href(support);
-    }
-
-    /*var store = commercial;
-    if (!store)
-        $(".activation").addClass("deleted");
-    else {
-        var activation = api + 'activation/' + idc;
-        $("#activation-src").src(activation);
-    }*/
-
-    var depiction = package.depiction;
-    if (depiction != null) {
-        $(".description").addClass("deleted");
-        $("#depiction-src").src(depiction);
-    } else {
-        $(".depiction").addClass("deleted");
-
-        var description = package.longDescription;
-        if (description == null)
-            description = package.shortDescription;
-
-        if (description == null)
-            $(".description").addClass("deleted");
-        else {
-            description = $.xml(description).replace(/\n/g, "<br/>");
-            $("#description").html(description);
-        }
-    }
-
-    var homepage = package.homepage;
-    if (homepage == null)
-        $(".homepage").addClass("deleted");
-    else
-        $("#homepage-href").href(homepage);
-
-    var installed = package.installed;
-    if (installed == null)
-        $(".installed").addClass("deleted");
-    else {
-        $("#installed").html(installed);
-        $("#files-href").href("cydia://files/" + idc);
-    }
-
-    space("#id", id, 220);
-
-    var section = package.longSection;
-    if (section == null)
-        $(".section").addClass("deleted");
-    else {
-        $("#section-src").src("cydia://section-icon/" + encodeURIComponent(section));
-        $("#section").html(section);
-    }
-
-    var size = package.size;
-    if (size == 0)
-        $(".size").addClass("deleted");
-    else
-        $("#size").html(size / 1024 + " kB");
-
-    var maintainer = package.maintainer;
-    if (maintainer == null)
-        $(".maintainer").addClass("deleted");
-    else {
-        space("#maintainer", maintainer.name, 153);
-        if (maintainer.address == null)
-            $("#maintainer-icon").addClass("deleted");
-        else if (support == null)
-            $("#maintainer-href").href("mailto:" + maintainer.address + "?subject=" + regarding("M"));
-        else
-            $("#maintainer-href").href(support);
-    }
-
-    var sponsor = package.sponsor;
-    if (sponsor == null)
-        $(".sponsor").addClass("deleted");
-    else {
-        space("#sponsor", sponsor.name, 152);
-        $("#sponsor-href").href(sponsor.address);
-    }
-
-    var source = package.source;
-    if (source == null) {
-        $(".source").addClass("deleted");
-        $(".trusted").addClass("deleted");
-    } else {
-        var host = source.host;
-
-        $("#source-src").src("cydia://source-icon/" + encodeURIComponent(host));
-        $("#source-name").html(source.name);
-
-        if (source.trusted)
-            $("#trusted").href("cydia://package-signature/" + idc);
-        else
-            $(".trusted").addClass("deleted");
-
-        var description = source.description;
-        if (description == null)
-            $(".source-description").addClass("deleted");
-        else
-            $("#source-description").html($.xml(description));
-    }
-};
-
-$(special_);
-
-var special = function () {
-    $(".deleted").removeClass("deleted");
-    $(".inserted").remove();
-
-    $("#icon")[0].className = 'flip-0';
-    $("#thumb")[0].className = 'flip-180';
-
-    /* XXX: this could be better */
-    $("#rating-href").href(null);
-    $("#rating-none").css("display", "none");
-    $("#rating-done").css("display", "none");
-
-    var notice = $("#notice-src");
-
-    notice[0].outerHTML = '<iframe' +
-        ' class="notice"' +
-        ' id="notice-src"' +
-        ' frameborder="0"' +
-        ' width="320"' +
-        ' height="0"' +
-        ' target="_top"' +
-    '></iframe>';
-
-    var depiction = $("#depiction-src");
-
-    depiction[0].outerHTML = '<iframe' +
-        ' class="depiction"' +
-        ' id="depiction-src"' +
-        ' frameborder="0"' +
-        ' width="320"' +
-        ' height="0"' +
-        ' target="_top"' +
-        ' onload_="loaded()"' +
-    '></iframe>';
-
-    special_();
-};
-
-cydia.setSpecial(special);
diff --git a/Cydia.app/packages.png b/Cydia.app/packages.png
deleted file mode 100644 (file)
index 404fe0c..0000000
Binary files a/Cydia.app/packages.png and /dev/null differ
diff --git a/Cydia.app/reload.png b/Cydia.app/reload.png
deleted file mode 100644 (file)
index 8d06eb4..0000000
Binary files a/Cydia.app/reload.png and /dev/null differ
diff --git a/Cydia.app/removing.png b/Cydia.app/removing.png
deleted file mode 100644 (file)
index 935d4c7..0000000
Binary files a/Cydia.app/removing.png and /dev/null differ
diff --git a/Cydia.app/search.png b/Cydia.app/search.png
deleted file mode 100644 (file)
index 4083f1b..0000000
Binary files a/Cydia.app/search.png and /dev/null differ
diff --git a/Cydia.app/search@2x.png b/Cydia.app/search@2x.png
deleted file mode 100644 (file)
index 74d6381..0000000
Binary files a/Cydia.app/search@2x.png and /dev/null differ
diff --git a/Cydia.app/settings.png b/Cydia.app/settings.png
deleted file mode 100644 (file)
index 86f4e78..0000000
Binary files a/Cydia.app/settings.png and /dev/null differ
diff --git a/Cydia.app/signature.html b/Cydia.app/signature.html
deleted file mode 100644 (file)
index aa113b8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title>Signature</title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="signature.js"></script>
-    <base target="_blank"/>
-</head><body><div class="page">
-<div class="dialog">
-    <div class="panel">
-
-    </div>
-</div>
-</div></body></html>
diff --git a/Cydia.app/source.png b/Cydia.app/source.png
deleted file mode 100755 (executable)
index 2dcfdbc..0000000
Binary files a/Cydia.app/source.png and /dev/null differ
diff --git a/Cydia.app/source@2x.png b/Cydia.app/source@2x.png
deleted file mode 100755 (executable)
index 65d70c3..0000000
Binary files a/Cydia.app/source@2x.png and /dev/null differ
diff --git a/Cydia.app/sources.png b/Cydia.app/sources.png
deleted file mode 100755 (executable)
index e8422e4..0000000
Binary files a/Cydia.app/sources.png and /dev/null differ
diff --git a/Cydia.app/star.png b/Cydia.app/star.png
deleted file mode 100644 (file)
index f762a24..0000000
Binary files a/Cydia.app/star.png and /dev/null differ
diff --git a/Cydia.app/storage.html b/Cydia.app/storage.html
deleted file mode 100644 (file)
index 55ac5ab..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="STORAGE"></title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="storage.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-
-    <style>
-        body {
-            display: table;
-            font-family: Helvetica;
-            height: 337px;
-            margin: 0;
-            padding: 0;
-            -webkit-text-size-adjust: none;
-            -webkit-user-select: none;
-        }
-
-        div.page {
-            display: table-cell;
-            text-align: center;
-            margin: 0 auto;
-            vertical-align: middle;
-            width: 320px;
-        }
-
-        a.giant-button {
-            background-color: rgba(0, 0, 0, 0.15);
-            -webkit-border-radius: 10px;
-            color: #193250;
-            display: block;
-            margin: 8px 10px;
-            position: relative;
-            text-decoration: none;
-            width: 300px;
-        }
-
-        a.giant-button > piechart {
-            float: left;
-            margin: 10px;
-            vertical-align: middle;
-        }
-
-        a.giant-button > label {
-            display: block;
-            float: left;
-            font-size: 25px;
-            margin: 10px 0 4px 4px;
-            text-align: center;
-            text-shadow: rgba(200, 200, 200, 0.75) 1px 1px 0;
-            width: 155px;
-        }
-
-        a.giant-button > div.text {
-            display: block;
-            float: left;
-            font-size: 14px;
-            margin-left: 4px;
-            text-align: center;
-            width: 155px;
-        }
-
-        div.key {
-            display: inline-block;
-            width: 50%;
-        }
-
-        a.giant-button > div.legend {
-            float: left;
-            font-size: 14px;
-            left: 15px;
-            position: absolute;
-            top: 120px;
-            width: 290px;
-        }
-
-        div.key {
-            margin-bottom: 4px;
-        }
-
-        piechart {
-            /*-webkit-transform: rotate(-5deg);*/
-            /*-webkit-transform: rotateY(15deg) rotateX(-45deg);*/
-        }
-
-        piechart > div {
-            -webkit-border-radius: 50px;
-            height: 100px;
-            overflow: hidden;
-            position: relative;
-            width: 100px;
-        }
-
-        piechart > div > div:first-child {
-            height: 100px;
-            overflow: hidden;
-            position: absolute;
-            z-index: 102;
-            width: 51px;
-        }
-
-        piechart > div > div:last-child {
-            height: 100px;
-            overflow: hidden;
-            position: absolute;
-            width: 100px;
-            z-index: 0;
-        }
-
-        piechart > div div.lslice,
-        piechart > div div.rslice,
-        piechart > div div.tslice,
-        piechart > div div.bslice {
-            background-color: #4d4d70;
-        }
-
-        piechart > div div.lslice,
-        piechart > div div.rslice,
-        piechart > div div.tslice,
-        piechart > div div.bslice,
-        piechart > div div.xslice {
-            /* XXX: technically, these aren't needed */
-            -webkit-border-bottom-left-radius: 50px;
-            -webkit-border-top-left-radius: 50px;
-            height: 100px;
-            position: absolute;
-            -webkit-transform-origin: 100% 50%;
-            width: 50px;
-        }
-
-        piechart > div div.lslice {
-            z-index: 100;
-        }
-
-        piechart > div div.rslice,
-        piechart > div div.tslice,
-        piechart > div div.bslice {
-            z-index: 0;
-        }
-
-        piechart > div div.rslice {
-            -webkit-transform: rotate(180deg);
-        }
-
-        piechart > div div.tslice {
-            -webkit-transform: rotate(90deg);
-        }
-
-        piechart > div div.bslice {
-            -webkit-transform: rotate(270deg);
-        }
-
-        piechart > div > div.nslice {
-            position: absolute;
-            text-align: center;
-            top: 42px;
-            width: 100px;
-            z-index: 103;
-        }
-
-        piechart > div > div.nslice > div {
-            background-color: rgba(255, 255, 255, 0.7);
-            -webkit-border-radius: 7px;
-            display: inline;
-            color: black;
-            font-size: 15px;
-            font-weight: bold;
-            margin: 0 auto;
-            padding: 2px 4px;
-            text-align: center;
-        }
-
-        div.color {
-            background-color: black;
-            border: 1px solid #4d4d70;
-            display: inline-block;
-            vertical-align: middle;
-        }
-
-        div.color > div {
-            border: 1px solid white;
-            display: inline-block;
-            height: 12px;
-            width: 12px;
-        }
-
-        div.name {
-            display: inline-block;
-            font-size: 14px;
-            margin-left: 5px;
-            vertical-align: middle;
-        }
-    </style>
-</head><body class="pinstripe">
-<panel>
-
-<a class="giant-button" style="height: 149px">
-    <piechart><div>
-        <div id="system-left"></div>
-        <div id="system-right">
-            <div class="lslice"></div>
-            <div class="rslice"></div>
-            <div class="tslice"></div>
-            <div class="bslice"></div>
-        </div>
-        <div class="nslice"><div id="system-size"></div></div>
-    </div></piechart>
-
-    <label>System</label>
-    <div class="text">A small partition used to store iPhone OS. Cydia adds a few important programs and libraries.</div>
-
-    <div class="legend" id="system-legend"></div>
-</a>
-
-<a class="giant-button" style="height: 189px">
-    <piechart><div>
-        <div id="private-left"></div>
-        <div id="private-right">
-            <div class="lslice"></div>
-            <div class="rslice"></div>
-            <div class="tslice"></div>
-            <div class="bslice"></div>
-        </div>
-        <div class="nslice"><div id="private-size"></div></div>
-    </div></piechart>
-
-    <label>Private</label>
-    <div class="text">Most content is stored on this partition: from applications (Cydia and Apple) to multimedia.</div>
-
-    <div class="legend" id="private-legend"></div>
-</a>
-
-</panel>
-</body></html>
diff --git a/Cydia.app/storage.js b/Cydia.app/storage.js
deleted file mode 100644 (file)
index ae8cb85..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-var colors = ["#9090e0", "#4d4d70", "#7d7da0", "#7da0e0", "#d0d0f0", "#7070e0"];
-
-var list = function (legend, color, name, value) {
-    legend.append('<div class="key">' +
-        '<div class="color" style="background-color: ' + color + '"><div></div></div>' +
-        '<div class="name">' + name + ' (' + Math.round(value * 1000) / 10 + '%)</div>' +
-    '</div>');
-};
-
-console.log(cydia.statfs("/"));
-
-var cut = function (parent, color, fraction, z) {
-    var deg = Math.round(360 * fraction);
-    if (deg < 2)
-        deg = 2;
-    parent.append('<div class="xslice" style="' +
-        'background-color: ' + color + ';' +
-        '-webkit-transform: rotate(' + deg + 'deg);' +
-        'z-index: ' + z + ';' +
-    '"></div>');
-};
-
-var chart = function (right, left, slices) {
-    var total = 0;
-    for (var i = 0; i != slices.length; ++i) {
-        var slice = slices[i];
-        var z = slices.length - i;
-        if (slice[1] > 0.5)
-            cut(right, slice[0], total + 0.5, z);
-        total += slice[1];
-        cut(total > 0.5 ? left : right, slice[0], total, z);
-    }
-};
-
-var setup = function (name, root, folders) {
-    var size = $("#" + name + "-size");
-    var statfs = cydia.statfs(root);
-    var kb = statfs[0] * statfs[1] / 1024;
-    var total = kb / 1024;
-
-    var unit;
-    if (total < 1000)
-        unit = 'M';
-    else {
-        total = total / 1024;
-        unit = 'G'
-    }
-
-    size.html(Math.round(total * 10) / 10 + " " + unit);
-
-    var legend = $("#" + name + "-legend");
-    var used = 0;
-
-    var slices = [];
-
-    if (folders != null)
-        for (var i = 0; i != folders.length; ++i) {
-            var folder = folders[i];
-            var usage = cydia.du(folder[1]);
-            if (usage == null)
-                usage = 0;
-            var color = colors[i + 2];
-            var percent = usage / kb;
-            list(legend, color, folder[0], percent);
-            slices.push([color, percent]);
-            used += usage;
-        }
-
-    var free = statfs[0] * statfs[2] / 1024;
-    var other = (kb - free - used) / kb;
-
-    slices.push([colors[0], other]);
-    chart($("#" + name + "-right"), $("#" + name + "-left"), slices);
-
-    list(legend, colors[0], folders == null ? "Used" : "Other", other);
-    list(legend, colors[1], "Free", statfs[2] / statfs[1]);
-};
-
-$(function () {
-    setup("system", "/", null);
-
-    setup("private", "/private/var", [
-        ["Themes", "/Library/Themes/"],
-        ["iTunes", "/var/mobile/Media/iTunes_Control/"],
-        ["App Store", "/var/mobile/Applications/"],
-        ["Camera", "/var/mobile/Media/DCIM/"]
-    ]);
-});
diff --git a/Cydia.app/storage.png b/Cydia.app/storage.png
deleted file mode 100644 (file)
index 3cefef0..0000000
Binary files a/Cydia.app/storage.png and /dev/null differ
diff --git a/Cydia.app/trusted.png b/Cydia.app/trusted.png
deleted file mode 100644 (file)
index de249eb..0000000
Binary files a/Cydia.app/trusted.png and /dev/null differ
diff --git a/Cydia.app/unknown.html b/Cydia.app/unknown.html
deleted file mode 100644 (file)
index 900a86f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-16"?>
-<html><head>
-    <title localize="UNKNOWN"></title>
-    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
-    <script type="text/javascript" src="menes/menes.js"></script>
-    <script type="text/javascript" src="localize.js"></script>
-    <base target="_blank"/>
-    <script type="text/javascript">
-    $(function () {
-        $("#body").html($.xml(cydia.format(cydia.localize("PACKAGE_CANNOT_BE_FOUND"), [location.search.substring(1)])));
-    });
-    </script>
-</head><body class="pinstripe">
-<panel>
-
-<fieldset>
-    <div><p style="font-weight: bold"><span style="color: red" localize="NOTE"></span>: <span localize="CANNOT_LOCATE_PACKAGE"></span></p></div>
-</fieldset>
-
-<block>
-    <p id="body"></p>
-    <p localize="PACKAGE_CANNOT_BE_FOUND_EX"></p>
-</block>
-
-</panel>
-</body></html>
diff --git a/Cydia.app/unknown.png b/Cydia.app/unknown.png
deleted file mode 100644 (file)
index 92d7338..0000000
Binary files a/Cydia.app/unknown.png and /dev/null differ
diff --git a/Cydia.app/version.png b/Cydia.app/version.png
deleted file mode 100644 (file)
index fd1eec1..0000000
Binary files a/Cydia.app/version.png and /dev/null differ
diff --git a/Cydia.app/warning.png b/Cydia.app/warning.png
deleted file mode 100644 (file)
index 8d3e5df..0000000
Binary files a/Cydia.app/warning.png and /dev/null differ
diff --git a/Cydia.app/web.png b/Cydia.app/web.png
deleted file mode 100644 (file)
index a4f04e3..0000000
Binary files a/Cydia.app/web.png and /dev/null differ
diff --git a/Cydia.frappliance/English.lproj/InfoPlist.strings b/Cydia.frappliance/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..3575674
--- /dev/null
@@ -0,0 +1 @@
+CFBundleName = "Cydia";
diff --git a/Cydia.frappliance/Info.plist b/Cydia.frappliance/Info.plist
new file mode 100644 (file)
index 0000000..f2eb03c
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+
+<dict>
+    <key>CFBundleExecutable</key>
+    <string>CydiaAppliance</string>
+
+    <key>CFBundleIdentifier</key>
+    <string>com.saurik.Cydia</string>
+
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+
+    <key>CFBundlePackageType</key>
+    <string>BNDL</string>
+
+    <key>CFBundleSignature</key>
+    <string>fnrw</string>
+
+    <key>CFBundleSupportedPlatforms</key>
+    <array>
+        <string>iPhoneOS</string>
+    </array>
+
+    <key>CFBundleVersion</key>
+    <string>0.9</string>
+
+    <key>DTSDKName</key>
+    <string>iphoneos2.0.saurik</string>
+
+    <key>FRApplianceDataSourceType</key>
+    <string>All</string>
+
+    <key>FRAppliancePreferedOrderValue</key>
+    <integer>1</integer>
+
+    <key>FRHideIfNoCategories</key>
+    <false/>
+
+    <key>FRRemoteAppliance</key>
+    <true/>
+
+    <key>LSRequiresIPhoneOS</key>
+    <string>1</string>
+
+    <key>MinimumOSVersion</key>
+    <string>3.0</string>
+
+    <key>NSPrincipalClass</key>
+    <string>CydiaAppliance</string>
+
+    <key>UIDeviceFamily</key>
+    <array>
+        <integer>3</integer>
+        <integer>2</integer>
+    </array>
+</dict>
+
+</plist>
diff --git a/Cydia.mm b/Cydia.mm
deleted file mode 100644 (file)
index a9c4ada..0000000
--- a/Cydia.mm
+++ /dev/null
@@ -1,9018 +0,0 @@
-/* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008-2010  Jay Freeman (saurik)
-*/
-
-/* Modified BSD License {{{ */
-/*
- *        Redistribution and use in source and binary
- * forms, with or without modification, are permitted
- * provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the
- *    above copyright notice, this list of conditions
- *    and the following disclaimer in the documentation
- *    and/or other materials provided with the
- *    distribution.
- * 3. The name of the author may not be used to endorse
- *    or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/* }}} */
-
-// XXX: wtf/FastMalloc.h... wtf?
-#define USE_SYSTEM_MALLOC 1
-
-/* #include Directives {{{ */
-#include "UICaboodle/UCPlatform.h"
-#include "UICaboodle/UCLocalize.h"
-
-#include <objc/objc.h>
-#include <objc/runtime.h>
-
-#include <CoreGraphics/CoreGraphics.h>
-#include <Foundation/Foundation.h>
-
-#if 0
-#define DEPLOYMENT_TARGET_MACOSX 1
-#define CF_BUILDING_CF 1
-#include <CoreFoundation/CFInternal.h>
-#endif
-
-#include <CoreFoundation/CFPriv.h>
-#include <CoreFoundation/CFUniChar.h>
-
-#include <SystemConfiguration/SystemConfiguration.h>
-
-#include <UIKit/UIKit.h>
-#include "iPhonePrivate.h"
-
-#include <IOKit/IOKitLib.h>
-
-#include <WebCore/WebCoreThread.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-#include <ext/stdio_filebuf.h>
-
-#undef ABS
-
-#include <apt-pkg/acquire.h>
-#include <apt-pkg/acquire-item.h>
-#include <apt-pkg/algorithms.h>
-#include <apt-pkg/cachefile.h>
-#include <apt-pkg/clean.h>
-#include <apt-pkg/configuration.h>
-#include <apt-pkg/debindexfile.h>
-#include <apt-pkg/debmetaindex.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/init.h>
-#include <apt-pkg/mmap.h>
-#include <apt-pkg/pkgrecords.h>
-#include <apt-pkg/sha1.h>
-#include <apt-pkg/sourcelist.h>
-#include <apt-pkg/sptr.h>
-#include <apt-pkg/strutl.h>
-#include <apt-pkg/tagfile.h>
-
-#include <apr-1/apr_pools.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/param.h>
-#include <sys/mount.h>
-
-#include <fcntl.h>
-#include <notify.h>
-#include <dlfcn.h>
-
-extern "C" {
-#include <mach-o/nlist.h>
-}
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include <errno.h>
-#include <pcre.h>
-
-#include <ext/hash_map>
-
-#include "UICaboodle/BrowserView.h"
-
-#include "substrate.h"
-/* }}} */
-
-/* Profiler {{{ */
-struct timeval _ltv;
-bool _itv;
-
-#define _timestamp ({ \
-    struct timeval tv; \
-    gettimeofday(&tv, NULL); \
-    tv.tv_sec * 1000000 + tv.tv_usec; \
-})
-
-typedef std::vector<class ProfileTime *> TimeList;
-TimeList times_;
-
-class ProfileTime {
-  private:
-    const char *name_;
-    uint64_t total_;
-    uint64_t count_;
-
-  public:
-    ProfileTime(const char *name) :
-        name_(name),
-        total_(0)
-    {
-        times_.push_back(this);
-    }
-
-    void AddTime(uint64_t time) {
-        total_ += time;
-        ++count_;
-    }
-
-    void Print() {
-        if (total_ != 0)
-            std::cerr << std::setw(5) << count_ << ", " << std::setw(7) << total_ << " : " << name_ << std::endl;
-        total_ = 0;
-        count_ = 0;
-    }
-};
-
-class ProfileTimer {
-  private:
-    ProfileTime &time_;
-    uint64_t start_;
-
-  public:
-    ProfileTimer(ProfileTime &time) :
-        time_(time),
-        start_(_timestamp)
-    {
-    }
-
-    ~ProfileTimer() {
-        time_.AddTime(_timestamp - start_);
-    }
-};
-
-void PrintTimes() {
-    for (TimeList::const_iterator i(times_.begin()); i != times_.end(); ++i)
-        (*i)->Print();
-    std::cerr << "========" << std::endl;
-}
-
-#define _profile(name) { \
-    static ProfileTime name(#name); \
-    ProfileTimer _ ## name(name);
-
-#define _end }
-/* }}} */
-
-#define _pooled _H<NSAutoreleasePool> _pool([[NSAutoreleasePool alloc] init], true);
-
-static const NSUInteger UIViewAutoresizingFlexibleBoth(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
-
-void NSLogPoint(const char *fix, const CGPoint &point) {
-    NSLog(@"%s(%g,%g)", fix, point.x, point.y);
-}
-
-void NSLogRect(const char *fix, const CGRect &rect) {
-    NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
-}
-
-static _finline NSString *CydiaURL(NSString *path) {
-    char page[25];
-    page[0] = 'h'; page[1] = 't'; page[2] = 't'; page[3] = 'p'; page[4] = ':';
-    page[5] = '/'; page[6] = '/'; page[7] = 'c'; page[8] = 'y'; page[9] = 'd';
-    page[10] = 'i'; page[11] = 'a'; page[12] = '.'; page[13] = 's'; page[14] = 'a';
-    page[15] = 'u'; page[16] = 'r'; page[17] = 'i'; page[18] = 'k'; page[19] = '.';
-    page[20] = 'c'; page[21] = 'o'; page[22] = 'm'; page[23] = '/'; page[24] = '\0';
-    return [[NSString stringWithUTF8String:page] stringByAppendingString:path];
-}
-
-static _finline void UpdateExternalStatus(uint64_t newStatus) {
-    int notify_token;
-    if (notify_register_check("com.saurik.Cydia.status", &notify_token) == NOTIFY_STATUS_OK) {
-        notify_set_state(notify_token, newStatus);
-        notify_cancel(notify_token);
-    }
-    notify_post("com.saurik.Cydia.status");
-}
-
-/* [NSObject yieldToSelector:(withObject:)] {{{*/
-@interface NSObject (Cydia)
-- (id) yieldToSelector:(SEL)selector withObject:(id)object;
-- (id) yieldToSelector:(SEL)selector;
-@end
-
-@implementation NSObject (Cydia)
-
-- (void) doNothing {
-}
-
-- (void) _yieldToContext:(NSMutableArray *)context { _pooled
-    SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
-    id object([[context objectAtIndex:1] nonretainedObjectValue]);
-    volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
-
-    /* XXX: deal with exceptions */
-    id value([self performSelector:selector withObject:object]);
-
-    NSMethodSignature *signature([self methodSignatureForSelector:selector]);
-    [context removeAllObjects];
-    if ([signature methodReturnLength] != 0 && value != nil)
-        [context addObject:value];
-
-    stopped = true;
-
-    [self
-        performSelectorOnMainThread:@selector(doNothing)
-        withObject:nil
-        waitUntilDone:NO
-    ];
-}
-
-- (id) yieldToSelector:(SEL)selector withObject:(id)object {
-    /*return [self performSelector:selector withObject:object];*/
-
-    volatile bool stopped(false);
-
-    NSMutableArray *context([NSMutableArray arrayWithObjects:
-        [NSValue valueWithPointer:selector],
-        [NSValue valueWithNonretainedObject:object],
-        [NSValue valueWithPointer:const_cast<bool *>(&stopped)],
-    nil]);
-
-    NSThread *thread([[[NSThread alloc]
-        initWithTarget:self
-        selector:@selector(_yieldToContext:)
-        object:context
-    ] autorelease]);
-
-    [thread start];
-
-    NSRunLoop *loop([NSRunLoop currentRunLoop]);
-    NSDate *future([NSDate distantFuture]);
-
-    while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
-
-    return [context count] == 0 ? nil : [context objectAtIndex:0];
-}
-
-- (id) yieldToSelector:(SEL)selector {
-    return [self yieldToSelector:selector withObject:nil];
-}
-
-@end
-/* }}} */
-
-@interface CYActionSheet : UIAlertView {
-    unsigned button_;
-}
-
-- (int) yieldToPopupAlertAnimated:(BOOL)animated;
-@end
-
-@implementation CYActionSheet
-
-- (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index {
-    if ((self = [super init])) {
-        [self setTitle:title];
-        [self setDelegate:self];
-        for (NSString *button in buttons) [self addButtonWithTitle:button];
-        [self setCancelButtonIndex:index];
-    } return self;
-}
-
-- (void) _updateFrameForDisplay {
-    [super _updateFrameForDisplay];
-    if ([self cancelButtonIndex] == -1) {
-        NSArray *buttons = [self buttons];
-        if ([buttons count]) {
-            UIImage *background = [[buttons objectAtIndex:0] backgroundForState:0];
-            for (UIThreePartButton *button in buttons)
-                [button setBackground:background forState:0];
-        }
-    }
-}
-
-- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
-    button_ = buttonIndex + 1;
-}
-
-- (void) dismiss {
-    [self dismissWithClickedButtonIndex:-1 animated:YES];
-}
-
-- (int) yieldToPopupAlertAnimated:(BOOL)animated {
-    [self setRunsModal:YES];
-    button_ = 0;
-    [self show];
-    return button_;
-}
-
-@end
-
-/* NSForcedOrderingSearch doesn't work on the iPhone */
-static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
-static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
-static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
-
-/* Information Dictionaries {{{ */
-@interface NSMutableArray (Cydia)
-- (void) addInfoDictionary:(NSDictionary *)info;
-@end
-
-@implementation NSMutableArray (Cydia)
-
-- (void) addInfoDictionary:(NSDictionary *)info {
-    [self addObject:info];
-}
-
-@end
-
-@interface NSMutableDictionary (Cydia)
-- (void) addInfoDictionary:(NSDictionary *)info;
-@end
-
-@implementation NSMutableDictionary (Cydia)
-
-- (void) addInfoDictionary:(NSDictionary *)info {
-    [self setObject:info forKey:[info objectForKey:@"CFBundleIdentifier"]];
-}
-
-@end
-/* }}} */
-
-#define lprintf(args...) fprintf(stderr, args)
-
-#define ForRelease 1
-#define TraceLogging (1 && !ForRelease)
-#define HistogramInsertionSort (0 && !ForRelease)
-#define ProfileTimes (0 && !ForRelease)
-#define ForSaurik (0 && !ForRelease)
-#define LogBrowser (0 && !ForRelease)
-#define TrackResize (0 && !ForRelease)
-#define ManualRefresh (0 && !ForRelease)
-#define ShowInternals (0 && !ForRelease)
-#define IgnoreInstall (0 && !ForRelease)
-#define RecycleWebViews 0
-#define RecyclePackageViews (0 && ForRelease)
-#define AlwaysReload (1 && !ForRelease)
-
-#if !TraceLogging
-#undef _trace
-#define _trace(args...)
-#endif
-
-#if !ProfileTimes
-#undef _profile
-#define _profile(name) {
-#undef _end
-#define _end }
-#define PrintTimes() do {} while (false)
-#endif
-
-/* Radix Sort {{{ */
-typedef uint32_t (*SKRadixFunction)(id, void *);
-
-@interface NSMutableArray (Radix)
-- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object;
-- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument;
-@end
-
-struct RadixItem_ {
-    size_t index;
-    uint32_t key;
-};
-
-static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *swap) {
-    struct RadixItem_ *lhs(swap), *rhs(swap + count);
-
-    static const size_t width = 32;
-    static const size_t bits = 11;
-    static const size_t slots = 1 << bits;
-    static const size_t passes = (width + (bits - 1)) / bits;
-
-    size_t *hist(new size_t[slots]);
-
-    for (size_t pass(0); pass != passes; ++pass) {
-        memset(hist, 0, sizeof(size_t) * slots);
-
-        for (size_t i(0); i != count; ++i) {
-            uint32_t key(lhs[i].key);
-            key >>= pass * bits;
-            key &= _not(uint32_t) >> width - bits;
-            ++hist[key];
-        }
-
-        size_t offset(0);
-        for (size_t i(0); i != slots; ++i) {
-            size_t local(offset);
-            offset += hist[i];
-            hist[i] = local;
-        }
-
-        for (size_t i(0); i != count; ++i) {
-            uint32_t key(lhs[i].key);
-            key >>= pass * bits;
-            key &= _not(uint32_t) >> width - bits;
-            rhs[hist[key]++] = lhs[i];
-        }
-
-        RadixItem_ *tmp(lhs);
-        lhs = rhs;
-        rhs = tmp;
-    }
-
-    delete [] hist;
-
-    NSMutableArray *values([NSMutableArray arrayWithCapacity:count]);
-    for (size_t i(0); i != count; ++i)
-        [values addObject:[self objectAtIndex:lhs[i].index]];
-    [self setArray:values];
-
-    delete [] swap;
-}
-
-@implementation NSMutableArray (Radix)
-
-- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object {
-    size_t count([self count]);
-    if (count == 0)
-        return;
-
-#if 0
-    NSInvocation *invocation([NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"L12@0:4@8"]]);
-    [invocation setSelector:selector];
-    [invocation setArgument:&object atIndex:2];
-#else
-    /* XXX: this is an unsafe optimization of doomy hell */
-    Method method(class_getInstanceMethod([[self objectAtIndex:0] class], selector));
-    _assert(method != NULL);
-    uint32_t (*imp)(id, SEL, id) = reinterpret_cast<uint32_t (*)(id, SEL, id)>(method_getImplementation(method));
-    _assert(imp != NULL);
-#endif
-
-    struct RadixItem_ *swap(new RadixItem_[count * 2]);
-
-    for (size_t i(0); i != count; ++i) {
-        RadixItem_ &item(swap[i]);
-        item.index = i;
-
-        id object([self objectAtIndex:i]);
-
-#if 0
-        [invocation setTarget:object];
-        [invocation invoke];
-        [invocation getReturnValue:&item.key];
-#else
-        item.key = imp(object, selector, object);
-#endif
-    }
-
-    RadixSort_(self, count, swap);
-}
-
-- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument {
-    size_t count([self count]);
-    struct RadixItem_ *swap(new RadixItem_[count * 2]);
-
-    for (size_t i(0); i != count; ++i) {
-        RadixItem_ &item(swap[i]);
-        item.index = i;
-
-        id object([self objectAtIndex:i]);
-        item.key = function(object, argument);
-    }
-
-    RadixSort_(self, count, swap);
-}
-
-@end
-/* }}} */
-/* Insertion Sort {{{ */
-
-CFIndex SKBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
-    const char *ptr = (const char *)list;
-    while (0 < count) {
-        CFIndex half = count / 2;
-        const char *probe = ptr + elementSize * half;
-        CFComparisonResult cr = comparator(element, probe, context);
-    if (0 == cr) return (probe - (const char *)list) / elementSize;
-        ptr = (cr < 0) ? ptr : probe + elementSize;
-        count = (cr < 0) ? half : (half + (count & 1) - 1);
-    }
-    return (ptr - (const char *)list) / elementSize;
-}
-
-CFIndex CFBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
-    const char *ptr = (const char *)list;
-    while (0 < count) {
-        CFIndex half = count / 2;
-        const char *probe = ptr + elementSize * half;
-        CFComparisonResult cr = comparator(element, probe, context);
-    if (0 == cr) return (probe - (const char *)list) / elementSize;
-        ptr = (cr < 0) ? ptr : probe + elementSize;
-        count = (cr < 0) ? half : (half + (count & 1) - 1);
-    }
-    return (ptr - (const char *)list) / elementSize;
-}
-
-void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) {
-    if (range.length == 0)
-        return;
-    const void **values(new const void *[range.length]);
-    CFArrayGetValues(array, range, values);
-
-#if HistogramInsertionSort
-    uint32_t total(0), *offsets(new uint32_t[range.length]);
-#endif
-
-    for (CFIndex index(1); index != range.length; ++index) {
-        const void *value(values[index]);
-        //CFIndex correct(SKBSearch_(&value, sizeof(const void *), values, index, comparator, context));
-        CFIndex correct(index);
-        while (comparator(value, values[correct - 1], context) == kCFCompareLessThan)
-            if (--correct == 0)
-                break;
-        if (correct != index) {
-            size_t offset(index - correct);
-#if HistogramInsertionSort
-            total += offset;
-            ++offsets[offset];
-            if (offset > 10)
-                NSLog(@"Heavy Insertion Displacement: %u = %@", offset, value);
-#endif
-            memmove(values + correct + 1, values + correct, sizeof(const void *) * offset);
-            values[correct] = value;
-        }
-    }
-
-    CFArrayReplaceValues(array, range, values, range.length);
-    delete [] values;
-
-#if HistogramInsertionSort
-    for (CFIndex index(0); index != range.length; ++index)
-        if (offsets[index] != 0)
-            NSLog(@"Insertion Displacement [%u]: %u", index, offsets[index]);
-    NSLog(@"Average Insertion Displacement: %f", double(total) / range.length);
-    delete [] offsets;
-#endif
-}
-
-/* }}} */
-
-/* Apple Bug Fixes {{{ */
-@implementation UIWebDocumentView (Cydia)
-
-- (void) _setScrollerOffset:(CGPoint)offset {
-    UIScroller *scroller([self _scroller]);
-
-    CGSize size([scroller contentSize]);
-    CGSize bounds([scroller bounds].size);
-
-    CGPoint max;
-    max.x = size.width - bounds.width;
-    max.y = size.height - bounds.height;
-
-    // wtf Apple?!
-    if (max.x < 0)
-        max.x = 0;
-    if (max.y < 0)
-        max.y = 0;
-
-    offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x;
-    offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y;
-
-    [scroller setOffset:offset];
-}
-
-@end
-/* }}} */
-
-@implementation WebScriptObject (NSFastEnumeration)
-
-- (NSUInteger) countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count {
-    size_t length([self count] - state->state);
-    if (length <= 0)
-        return 0;
-    else if (length > count)
-        length = count;
-    for (size_t i(0); i != length; ++i)
-        objects[i] = [self objectAtIndex:state->state++];
-    state->itemsPtr = objects;
-    state->mutationsPtr = (unsigned long *) self;
-    return length;
-}
-
-@end
-
-NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
-    size_t length([self length] - state->state);
-    if (length <= 0)
-        return 0;
-    else if (length > count)
-        length = count;
-    for (size_t i(0); i != length; ++i)
-        objects[i] = [self item:state->state++];
-    state->itemsPtr = objects;
-    state->mutationsPtr = (unsigned long *) self;
-    return length;
-}
-
-/* Cydia NSString Additions {{{ */
-@interface NSString (Cydia)
-+ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length;
-+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length withZone:(NSZone *)zone inPool:(apr_pool_t *)pool;
-+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length;
-- (NSComparisonResult) compareByPath:(NSString *)other;
-- (NSString *) stringByCachingURLWithCurrentCDN;
-- (NSString *) stringByAddingPercentEscapesIncludingReserved;
-@end
-
-@implementation NSString (Cydia)
-
-+ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length {
-    return [[[NSString alloc] initWithBytesNoCopy:const_cast<char *>(bytes) length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
-}
-
-+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length withZone:(NSZone *)zone inPool:(apr_pool_t *)pool {
-    char *data(reinterpret_cast<char *>(apr_palloc(pool, length)));
-    memcpy(data, bytes, length);
-    return [[[NSString allocWithZone:zone] initWithBytesNoCopy:data length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
-}
-
-+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length {
-    return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease];
-}
-
-- (NSComparisonResult) compareByPath:(NSString *)other {
-    NSString *prefix = [self commonPrefixWithString:other options:0];
-    size_t length = [prefix length];
-
-    NSRange lrange = NSMakeRange(length, [self length] - length);
-    NSRange rrange = NSMakeRange(length, [other length] - length);
-
-    lrange = [self rangeOfString:@"/" options:0 range:lrange];
-    rrange = [other rangeOfString:@"/" options:0 range:rrange];
-
-    NSComparisonResult value;
-
-    if (lrange.location == NSNotFound && rrange.location == NSNotFound)
-        value = NSOrderedSame;
-    else if (lrange.location == NSNotFound)
-        value = NSOrderedAscending;
-    else if (rrange.location == NSNotFound)
-        value = NSOrderedDescending;
-    else
-        value = NSOrderedSame;
-
-    NSString *lpath = lrange.location == NSNotFound ? [self substringFromIndex:length] :
-        [self substringWithRange:NSMakeRange(length, lrange.location - length)];
-    NSString *rpath = rrange.location == NSNotFound ? [other substringFromIndex:length] :
-        [other substringWithRange:NSMakeRange(length, rrange.location - length)];
-
-    NSComparisonResult result = [lpath compare:rpath];
-    return result == NSOrderedSame ? value : result;
-}
-
-- (NSString *) stringByCachingURLWithCurrentCDN {
-    return [self
-        stringByReplacingOccurrencesOfString:@"://cydia.saurik.com/"
-        withString:@"://cache.cydia.saurik.com/"
-    ];
-}
-
-- (NSString *) stringByAddingPercentEscapesIncludingReserved {
-    return [(id)CFURLCreateStringByAddingPercentEscapes(
-        kCFAllocatorDefault,
-        (CFStringRef) self,
-        NULL,
-        CFSTR(";/?:@&=+$,"),
-        kCFStringEncodingUTF8
-    ) autorelease];
-}
-
-@end
-/* }}} */
-
-/* C++ NSString Wrapper Cache {{{ */
-class CYString {
-  private:
-    char *data_;
-    size_t size_;
-    CFStringRef cache_;
-
-    _finline void clear_() {
-        if (cache_ != NULL) {
-            CFRelease(cache_);
-            cache_ = NULL;
-        }
-    }
-
-  public:
-    _finline bool empty() const {
-        return size_ == 0;
-    }
-
-    _finline size_t size() const {
-        return size_;
-    }
-
-    _finline char *data() const {
-        return data_;
-    }
-
-    _finline void clear() {
-        size_ = 0;
-        clear_();
-    }
-
-    _finline CYString() :
-        data_(0),
-        size_(0),
-        cache_(NULL)
-    {
-    }
-
-    _finline ~CYString() {
-        clear_();
-    }
-
-    void operator =(const CYString &rhs) {
-        data_ = rhs.data_;
-        size_ = rhs.size_;
-
-        if (rhs.cache_ == nil)
-            cache_ = NULL;
-        else
-            cache_ = reinterpret_cast<CFStringRef>(CFRetain(rhs.cache_));
-    }
-
-    void set(apr_pool_t *pool, const char *data, size_t size) {
-        if (size == 0)
-            clear();
-        else {
-            clear_();
-
-            char *temp(reinterpret_cast<char *>(apr_palloc(pool, size + 1)));
-            memcpy(temp, data, size);
-            temp[size] = '\0';
-            data_ = temp;
-            size_ = size;
-        }
-    }
-
-    _finline void set(apr_pool_t *pool, const char *data) {
-        set(pool, data, data == NULL ? 0 : strlen(data));
-    }
-
-    _finline void set(apr_pool_t *pool, const std::string &rhs) {
-        set(pool, rhs.data(), rhs.size());
-    }
-
-    bool operator ==(const CYString &rhs) const {
-        return size_ == rhs.size_ && memcmp(data_, rhs.data_, size_) == 0;
-    }
-
-    operator CFStringRef() {
-        if (cache_ == NULL) {
-            if (size_ == 0)
-                return nil;
-            cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingUTF8, NO, kCFAllocatorNull);
-            if (cache_ == NULL)
-                cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingISOLatin1, NO, kCFAllocatorNull);
-        } return cache_;
-    }
-
-    _finline operator id() {
-        return (NSString *) static_cast<CFStringRef>(*this);
-    }
-};
-/* }}} */
-/* C++ NSString Algorithm Adapters {{{ */
-extern "C" {
-    CF_EXPORT CFHashCode CFStringHashNSString(CFStringRef str);
-}
-
-struct NSStringMapHash :
-    std::unary_function<NSString *, size_t>
-{
-    _finline size_t operator ()(NSString *value) const {
-        return CFStringHashNSString((CFStringRef) value);
-    }
-};
-
-struct NSStringMapLess :
-    std::binary_function<NSString *, NSString *, bool>
-{
-    _finline bool operator ()(NSString *lhs, NSString *rhs) const {
-        return [lhs compare:rhs] == NSOrderedAscending;
-    }
-};
-
-struct NSStringMapEqual :
-    std::binary_function<NSString *, NSString *, bool>
-{
-    _finline bool operator ()(NSString *lhs, NSString *rhs) const {
-        return CFStringCompare((CFStringRef) lhs, (CFStringRef) rhs, 0) == kCFCompareEqualTo;
-        //CFEqual((CFTypeRef) lhs, (CFTypeRef) rhs);
-        //[lhs isEqualToString:rhs];
-    }
-};
-/* }}} */
-
-/* Perl-Compatible RegEx {{{ */
-class Pcre {
-  private:
-    pcre *code_;
-    pcre_extra *study_;
-    int capture_;
-    int *matches_;
-    const char *data_;
-
-  public:
-    Pcre(const char *regex) :
-        study_(NULL)
-    {
-        const char *error;
-        int offset;
-        code_ = pcre_compile(regex, 0, &error, &offset, NULL);
-
-        if (code_ == NULL) {
-            lprintf("%d:%s\n", offset, error);
-            _assert(false);
-        }
-
-        pcre_fullinfo(code_, study_, PCRE_INFO_CAPTURECOUNT, &capture_);
-        matches_ = new int[(capture_ + 1) * 3];
-    }
-
-    ~Pcre() {
-        pcre_free(code_);
-        delete matches_;
-    }
-
-    NSString *operator [](size_t match) {
-        return [NSString stringWithUTF8Bytes:(data_ + matches_[match * 2]) length:(matches_[match * 2 + 1] - matches_[match * 2])];
-    }
-
-    bool operator ()(NSString *data) {
-        // XXX: length is for characters, not for bytes
-        return operator ()([data UTF8String], [data length]);
-    }
-
-    bool operator ()(const char *data, size_t size) {
-        data_ = data;
-        return pcre_exec(code_, study_, data, size, 0, 0, matches_, (capture_ + 1) * 3) >= 0;
-    }
-};
-/* }}} */
-/* Mime Addresses {{{ */
-@interface Address : NSObject {
-    NSString *name_;
-    NSString *address_;
-}
-
-- (NSString *) name;
-- (NSString *) address;
-
-- (void) setAddress:(NSString *)address;
-
-+ (Address *) addressWithString:(NSString *)string;
-- (Address *) initWithString:(NSString *)string;
-@end
-
-@implementation Address
-
-- (void) dealloc {
-    [name_ release];
-    if (address_ != nil)
-        [address_ release];
-    [super dealloc];
-}
-
-- (NSString *) name {
-    return name_;
-}
-
-- (NSString *) address {
-    return address_;
-}
-
-- (void) setAddress:(NSString *)address {
-    if (address_ != nil)
-        [address_ autorelease];
-    if (address == nil)
-        address_ = nil;
-    else
-        address_ = [address retain];
-}
-
-+ (Address *) addressWithString:(NSString *)string {
-    return [[[Address alloc] initWithString:string] autorelease];
-}
-
-+ (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"address", @"name", nil];
-}
-
-- (NSArray *) attributeKeys {
-    return [[self class] _attributeKeys];
-}
-
-+ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
-    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
-}
-
-- (Address *) initWithString:(NSString *)string {
-    if ((self = [super init]) != nil) {
-        const char *data = [string UTF8String];
-        size_t size = [string length];
-
-        static Pcre address_r("^\"?(.*)\"? <([^>]*)>$");
-
-        if (address_r(data, size)) {
-            name_ = [address_r[1] retain];
-            address_ = [address_r[2] retain];
-        } else {
-            name_ = [string retain];
-            address_ = nil;
-        }
-    } return self;
-}
-
-@end
-/* }}} */
-/* CoreGraphics Primitives {{{ */
-class CYColor {
-  private:
-    CGColorRef color_;
-
-  public:
-    CYColor() :
-        color_(NULL)
-    {
-    }
-
-    CYColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) :
-        color_(NULL)
-    {
-        Set(space, red, green, blue, alpha);
-    }
-
-    void Clear() {
-        if (color_ != NULL)
-            CGColorRelease(color_);
-    }
-
-    ~CYColor() {
-        Clear();
-    }
-
-    void Set(CGColorSpaceRef space, float red, float green, float blue, float alpha) {
-        Clear();
-        float color[] = {red, green, blue, alpha};
-        color_ = CGColorCreate(space, (CGFloat *) color);
-    }
-
-    operator CGColorRef() {
-        return color_;
-    }
-};
-/* }}} */
-
-/* Random Global Variables {{{ */
-static const int PulseInterval_ = 50000;
-static const int ButtonBarWidth_ = 60;
-static const int ButtonBarHeight_ = 48;
-static const float KeyboardTime_ = 0.3f;
-
-static int Finish_;
-static NSArray *Finishes_;
-
-#define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
-#define NotifyConfig_ "/etc/notify.conf"
-
-static bool Queuing_;
-
-static CYColor Blue_;
-static CYColor Blueish_;
-static CYColor Black_;
-static CYColor Off_;
-static CYColor White_;
-static CYColor Gray_;
-static CYColor Green_;
-static CYColor Purple_;
-static CYColor Purplish_;
-
-static UIColor *InstallingColor_;
-static UIColor *RemovingColor_;
-
-static NSString *App_;
-static NSString *Home_;
-
-static BOOL Advanced_;
-static BOOL Ignored_;
-
-static UIFont *Font12_;
-static UIFont *Font12Bold_;
-static UIFont *Font14_;
-static UIFont *Font18Bold_;
-static UIFont *Font22Bold_;
-
-static const char *Machine_ = NULL;
-static NSString *System_ = nil;
-static NSString *SerialNumber_ = nil;
-static NSString *ChipID_ = nil;
-static NSString *Token_ = nil;
-static NSString *UniqueID_ = nil;
-static NSString *Build_ = nil;
-static NSString *Product_ = nil;
-static NSString *Safari_ = nil;
-
-static CFLocaleRef Locale_;
-static NSArray *Languages_;
-static CGColorSpaceRef space_;
-
-static NSDictionary *SectionMap_;
-static NSMutableDictionary *Metadata_;
-static _transient NSMutableDictionary *Settings_;
-static _transient NSString *Role_;
-static _transient NSMutableDictionary *Packages_;
-static _transient NSMutableDictionary *Sections_;
-static _transient NSMutableDictionary *Sources_;
-static bool Changed_;
-static NSDate *now_;
-
-static bool IsWildcat_;
-
-#if RecycleWebViews
-static NSMutableArray *Documents_;
-#endif
-/* }}} */
-
-/* Display Helpers {{{ */
-inline float Interpolate(float begin, float end, float fraction) {
-    return (end - begin) * fraction + begin;
-}
-
-/* XXX: localize this! */
-NSString *SizeString(double size) {
-    bool negative = size < 0;
-    if (negative)
-        size = -size;
-
-    unsigned power = 0;
-    while (size > 1024) {
-        size /= 1024;
-        ++power;
-    }
-
-    static const char *powers_[] = {"B", "kB", "MB", "GB"};
-
-    return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]];
-}
-
-static _finline CFStringRef CFCString(const char *value) {
-    return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
-}
-
-const char *StripVersion_(const char *version) {
-    const char *colon(strchr(version, ':'));
-    if (colon != NULL)
-        version = colon + 1;
-    return version;
-}
-
-CFStringRef StripVersion(const char *version) {
-    const char *colon(strchr(version, ':'));
-    if (colon != NULL)
-        version = colon + 1;
-    return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(version), strlen(version), kCFStringEncodingUTF8, NO);
-    // XXX: performance
-    return CFCString(version);
-}
-
-NSString *LocalizeSection(NSString *section) {
-    static Pcre title_r("^(.*?) \\((.*)\\)$");
-    if (title_r(section)) {
-        NSString *parent(title_r[1]);
-        NSString *child(title_r[2]);
-
-        return [NSString stringWithFormat:UCLocalize("PARENTHETICAL"),
-            LocalizeSection(parent),
-            LocalizeSection(child)
-        ];
-    }
-
-    return [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"];
-}
-
-NSString *Simplify(NSString *title) {
-    const char *data = [title UTF8String];
-    size_t size = [title length];
-
-    static Pcre square_r("^\\[(.*)\\]$");
-    if (square_r(data, size))
-        return Simplify(square_r[1]);
-
-    static Pcre paren_r("^\\((.*)\\)$");
-    if (paren_r(data, size))
-        return Simplify(paren_r[1]);
-
-    static Pcre title_r("^(.*?) \\((.*)\\)$");
-    if (title_r(data, size))
-        return Simplify(title_r[1]);
-
-    return title;
-}
-/* }}} */
-
-NSString *GetLastUpdate() {
-    NSDate *update = [Metadata_ objectForKey:@"LastUpdate"];
-
-    if (update == nil)
-        return UCLocalize("NEVER_OR_UNKNOWN");
-
-    CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle);
-    CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) update);
-
-    CFRelease(formatter);
-
-    return [(NSString *) formatted autorelease];
-}
-
-bool isSectionVisible(NSString *section) {
-    NSDictionary *metadata([Sections_ objectForKey:section]);
-    NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]);
-    return hidden == nil || ![hidden boolValue];
-}
-
-@class Cydia;
-
-/* Delegate Prototypes {{{ */
-@class Package;
-@class Source;
-
-@interface NSObject (ProgressDelegate)
-@end
-
-@protocol ProgressDelegate
-- (void) setProgressError:(NSString *)error withTitle:(NSString *)id;
-- (void) setProgressTitle:(NSString *)title;
-- (void) setProgressPercent:(float)percent;
-- (void) startProgress;
-- (void) addProgressOutput:(NSString *)output;
-- (bool) isCancelling:(size_t)received;
-@end
-
-@protocol ConfigurationDelegate
-- (void) repairWithSelector:(SEL)selector;
-- (void) setConfigurationData:(NSString *)data;
-@end
-
-@class PackageController;
-
-@protocol CydiaDelegate
-- (void) setPackageController:(PackageController *)view;
-- (void) clearPackage:(Package *)package;
-- (void) installPackage:(Package *)package;
-- (void) installPackages:(NSArray *)packages;
-- (void) removePackage:(Package *)package;
-- (void) beginUpdate;
-- (BOOL) updating;
-- (void) distUpgrade;
-- (void) loadData;
-- (void) updateData;
-- (void) syncData;
-- (void) showSettings;
-- (UIProgressHUD *) addProgressHUD;
-- (void) removeProgressHUD:(UIProgressHUD *)hud;
-- (CYViewController *) pageForPackage:(NSString *)name;
-- (PackageController *) packageController;
-- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
-@end
-/* }}} */
-
-/* Status Delegation {{{ */
-class Status :
-    public pkgAcquireStatus
-{
-  private:
-    _transient NSObject<ProgressDelegate> *delegate_;
-
-  public:
-    Status() :
-        delegate_(nil)
-    {
-    }
-
-    void setDelegate(id delegate) {
-        delegate_ = delegate;
-    }
-
-    NSObject<ProgressDelegate> *getDelegate() const {
-        return delegate_;
-    }
-
-    virtual bool MediaChange(std::string media, std::string drive) {
-        return false;
-    }
-
-    virtual void IMSHit(pkgAcquire::ItemDesc &item) {
-    }
-
-    virtual void Fetch(pkgAcquire::ItemDesc &item) {
-        //NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]);
-        [delegate_ setProgressTitle:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), [NSString stringWithUTF8String:item.ShortDesc.c_str()]]];
-    }
-
-    virtual void Done(pkgAcquire::ItemDesc &item) {
-    }
-
-    virtual void Fail(pkgAcquire::ItemDesc &item) {
-        if (
-            item.Owner->Status == pkgAcquire::Item::StatIdle ||
-            item.Owner->Status == pkgAcquire::Item::StatDone
-        )
-            return;
-
-        std::string &error(item.Owner->ErrorText);
-        if (error.empty())
-            return;
-
-        NSString *description([NSString stringWithUTF8String:item.Description.c_str()]);
-        NSArray *fields([description componentsSeparatedByString:@" "]);
-        NSString *source([fields count] == 0 ? nil : [fields objectAtIndex:0]);
-
-        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
-            withObject:[NSArray arrayWithObjects:
-                [NSString stringWithUTF8String:error.c_str()],
-                source,
-            nil]
-            waitUntilDone:YES
-        ];
-    }
-
-    virtual bool Pulse(pkgAcquire *Owner) {
-        bool value = pkgAcquireStatus::Pulse(Owner);
-
-        float percent(
-            double(CurrentBytes + CurrentItems) /
-            double(TotalBytes + TotalItems)
-        );
-
-        [delegate_ setProgressPercent:percent];
-        return [delegate_ isCancelling:CurrentBytes] ? false : value;
-    }
-
-    virtual void Start() {
-        [delegate_ startProgress];
-    }
-
-    virtual void Stop() {
-    }
-};
-/* }}} */
-/* Progress Delegation {{{ */
-class Progress :
-    public OpProgress
-{
-  private:
-    _transient id<ProgressDelegate> delegate_;
-    float percent_;
-
-  protected:
-    virtual void Update() {
-        /*if (abs(Percent - percent_) > 2)
-            //NSLog(@"%s:%s:%f", Op.c_str(), SubOp.c_str(), Percent);
-            percent_ = Percent;
-        }*/
-
-        /*[delegate_ setProgressTitle:[NSString stringWithUTF8String:Op.c_str()]];
-        [delegate_ setProgressPercent:(Percent / 100)];*/
-    }
-
-  public:
-    Progress() :
-        delegate_(nil),
-        percent_(0)
-    {
-    }
-
-    void setDelegate(id delegate) {
-        delegate_ = delegate;
-    }
-
-    id getDelegate() const {
-        return delegate_;
-    }
-
-    virtual void Done() {
-        //NSLog(@"DONE");
-        //[delegate_ setProgressPercent:1];
-    }
-};
-/* }}} */
-
-/* Database Interface {{{ */
-typedef std::map< unsigned long, _H<Source> > SourceMap;
-
-@interface Database : NSObject {
-    NSZone *zone_;
-    apr_pool_t *pool_;
-
-    unsigned era_;
-
-    pkgCacheFile cache_;
-    pkgDepCache::Policy *policy_;
-    pkgRecords *records_;
-    pkgProblemResolver *resolver_;
-    pkgAcquire *fetcher_;
-    FileFd *lock_;
-    SPtr<pkgPackageManager> manager_;
-    pkgSourceList *list_;
-
-    SourceMap sources_;
-    NSMutableArray *packages_;
-
-    _transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
-    Status status_;
-    Progress progress_;
-
-    int cydiafd_;
-    int statusfd_;
-    FILE *input_;
-}
-
-+ (Database *) sharedInstance;
-- (unsigned) era;
-
-- (void) _readCydia:(NSNumber *)fd;
-- (void) _readStatus:(NSNumber *)fd;
-- (void) _readOutput:(NSNumber *)fd;
-
-- (FILE *) input;
-
-- (Package *) packageWithName:(NSString *)name;
-
-- (pkgCacheFile &) cache;
-- (pkgDepCache::Policy *) policy;
-- (pkgRecords *) records;
-- (pkgProblemResolver *) resolver;
-- (pkgAcquire &) fetcher;
-- (pkgSourceList &) list;
-- (NSArray *) packages;
-- (NSArray *) sources;
-- (void) reloadData;
-
-- (void) configure;
-- (bool) prepare;
-- (void) perform;
-- (bool) upgrade;
-- (void) update;
-
-- (void) setVisible;
-
-- (void) updateWithStatus:(Status &)status;
-
-- (void) setDelegate:(id)delegate;
-- (Source *) getSource:(pkgCache::PkgFileIterator)file;
-@end
-/* }}} */
-/* Delegate Helpers {{{ */
-@implementation NSObject (ProgressDelegate)
-
-- (void) _setProgressErrorPackage:(NSArray *)args {
-    [self performSelector:@selector(setProgressError:forPackage:)
-        withObject:[args objectAtIndex:0]
-        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
-    ];
-}
-
-- (void) _setProgressErrorTitle:(NSArray *)args {
-    [self performSelector:@selector(setProgressError:withTitle:)
-        withObject:[args objectAtIndex:0]
-        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
-    ];
-}
-
-- (void) _setProgressError:(NSString *)error withTitle:(NSString *)title {
-    [self performSelectorOnMainThread:@selector(_setProgressErrorTitle:)
-        withObject:[NSArray arrayWithObjects:error, title, nil]
-        waitUntilDone:YES
-    ];
-}
-
-- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
-    Package *package = id == nil ? nil : [[Database sharedInstance] packageWithName:id];
-
-    [self performSelector:@selector(setProgressError:withTitle:)
-        withObject:error
-        withObject:(package == nil ? id : [package name])
-    ];
-}
-
-@end
-/* }}} */
-
-/* Source Class {{{ */
-@interface Source : NSObject {
-    CYString depiction_;
-    CYString description_;
-    CYString label_;
-    CYString origin_;
-    CYString support_;
-
-    CYString uri_;
-    CYString distribution_;
-    CYString type_;
-    CYString version_;
-
-    NSString *host_;
-    NSString *authority_;
-
-    CYString defaultIcon_;
-
-    NSDictionary *record_;
-    BOOL trusted_;
-}
-
-- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool;
-
-- (NSComparisonResult) compareByNameAndType:(Source *)source;
-
-- (NSString *) depictionForPackage:(NSString *)package;
-- (NSString *) supportForPackage:(NSString *)package;
-
-- (NSDictionary *) record;
-- (BOOL) trusted;
-
-- (NSString *) uri;
-- (NSString *) distribution;
-- (NSString *) type;
-- (NSString *) key;
-- (NSString *) host;
-
-- (NSString *) name;
-- (NSString *) description;
-- (NSString *) label;
-- (NSString *) origin;
-- (NSString *) version;
-
-- (NSString *) defaultIcon;
-
-@end
-
-@implementation Source
-
-- (void) _clear {
-    uri_.clear();
-    distribution_.clear();
-    type_.clear();
-
-    description_.clear();
-    label_.clear();
-    origin_.clear();
-    depiction_.clear();
-    support_.clear();
-    version_.clear();
-    defaultIcon_.clear();
-
-    if (record_ != nil) {
-        [record_ release];
-        record_ = nil;
-    }
-
-    if (host_ != nil) {
-        [host_ release];
-        host_ = nil;
-    }
-
-    if (authority_ != nil) {
-        [authority_ release];
-        authority_ = nil;
-    }
-}
-
-- (void) dealloc {
-    [self _clear];
-    [super dealloc];
-}
-
-+ (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"description", @"distribution", @"host", @"key", @"label", @"name", @"origin", @"trusted", @"type", @"uri", @"version", nil];
-}
-
-- (NSArray *) attributeKeys {
-    return [[self class] _attributeKeys];
-}
-
-+ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
-    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
-}
-
-- (void) setMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
-    [self _clear];
-
-    trusted_ = index->IsTrusted();
-
-    uri_.set(pool, index->GetURI());
-    distribution_.set(pool, index->GetDist());
-    type_.set(pool, index->GetType());
-
-    debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
-    if (dindex != NULL) {
-        FileFd fd;
-        if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly))
-            _error->Discard();
-        else {
-            pkgTagFile tags(&fd);
-
-            pkgTagSection section;
-            tags.Step(section);
-
-            struct {
-                const char *name_;
-                CYString *value_;
-            } names[] = {
-                {"default-icon", &defaultIcon_},
-                {"depiction", &depiction_},
-                {"description", &description_},
-                {"label", &label_},
-                {"origin", &origin_},
-                {"support", &support_},
-                {"version", &version_},
-            };
-
-            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
-                const char *start, *end;
-
-                if (section.Find(names[i].name_, start, end)) {
-                    CYString &value(*names[i].value_);
-                    value.set(pool, start, end - start);
-                }
-            }
-        }
-    }
-
-    record_ = [Sources_ objectForKey:[self key]];
-    if (record_ != nil)
-        record_ = [record_ retain];
-
-    NSURL *url([NSURL URLWithString:uri_]);
-
-    host_ = [url host];
-    if (host_ != nil)
-        host_ = [[host_ lowercaseString] retain];
-
-    if (host_ != nil)
-        authority_ = host_;
-    else
-        authority_ = [url path];
-
-    if (authority_ != nil)
-        authority_ = [authority_ retain];
-}
-
-- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
-    if ((self = [super init]) != nil) {
-        [self setMetaIndex:index inPool:pool];
-    } return self;
-}
-
-- (NSComparisonResult) compareByNameAndType:(Source *)source {
-    NSDictionary *lhr = [self record];
-    NSDictionary *rhr = [source record];
-
-    if (lhr != rhr)
-        return lhr == nil ? NSOrderedDescending : NSOrderedAscending;
-
-    NSString *lhs = [self name];
-    NSString *rhs = [source name];
-
-    if ([lhs length] != 0 && [rhs length] != 0) {
-        unichar lhc = [lhs characterAtIndex:0];
-        unichar rhc = [rhs characterAtIndex:0];
-
-        if (isalpha(lhc) && !isalpha(rhc))
-            return NSOrderedAscending;
-        else if (!isalpha(lhc) && isalpha(rhc))
-            return NSOrderedDescending;
-    }
-
-    return [lhs compare:rhs options:LaxCompareOptions_];
-}
-
-- (NSString *) depictionForPackage:(NSString *)package {
-    return depiction_.empty() ? nil : [static_cast<id>(depiction_) stringByReplacingOccurrencesOfString:@"*" withString:package];
-}
-
-- (NSString *) supportForPackage:(NSString *)package {
-    return support_.empty() ? nil : [static_cast<id>(support_) stringByReplacingOccurrencesOfString:@"*" withString:package];
-}
-
-- (NSDictionary *) record {
-    return record_;
-}
-
-- (BOOL) trusted {
-    return trusted_;
-}
-
-- (NSString *) uri {
-    return uri_;
-}
-
-- (NSString *) distribution {
-    return distribution_;
-}
-
-- (NSString *) type {
-    return type_;
-}
-
-- (NSString *) key {
-    return [NSString stringWithFormat:@"%@:%@:%@", (NSString *) type_, (NSString *) uri_, (NSString *) distribution_];
-}
-
-- (NSString *) host {
-    return host_;
-}
-
-- (NSString *) name {
-    return origin_.empty() ? authority_ : origin_;
-}
-
-- (NSString *) description {
-    return description_;
-}
-
-- (NSString *) label {
-    return label_.empty() ? authority_ : label_;
-}
-
-- (NSString *) origin {
-    return origin_;
-}
-
-- (NSString *) version {
-    return version_;
-}
-
-- (NSString *) defaultIcon {
-    return defaultIcon_;
-}
-
-@end
-/* }}} */
-/* Relationship Class {{{ */
-@interface Relationship : NSObject {
-    NSString *type_;
-    NSString *id_;
-}
-
-- (NSString *) type;
-- (NSString *) id;
-- (NSString *) name;
-
-@end
-
-@implementation Relationship
-
-- (void) dealloc {
-    [type_ release];
-    [id_ release];
-    [super dealloc];
-}
-
-- (NSString *) type {
-    return type_;
-}
-
-- (NSString *) id {
-    return id_;
-}
-
-- (NSString *) name {
-    _assert(false);
-    return nil;
-}
-
-@end
-/* }}} */
-/* Package Class {{{ */
-@interface Package : NSObject {
-    unsigned era_;
-    apr_pool_t *pool_;
-
-    pkgCache::VerIterator version_;
-    pkgCache::PkgIterator iterator_;
-    _transient Database *database_;
-    pkgCache::VerFileIterator file_;
-
-    Source *source_;
-    bool cached_;
-    bool parsed_;
-
-    CYString section_;
-    NSString *section$_;
-    bool essential_;
-    bool required_;
-    bool visible_;
-    bool obsolete_;
-
-    NSString *latest_;
-    CYString installed_;
-
-    CYString id_;
-    CYString name_;
-    CYString tagline_;
-    CYString icon_;
-    CYString depiction_;
-    CYString homepage_;
-
-    CYString sponsor_;
-    Address *sponsor$_;
-
-    CYString author_;
-    Address *author$_;
-
-    CYString bugs_;
-    CYString support_;
-    NSMutableArray *tags_;
-    NSString *role_;
-
-    NSArray *relationships_;
-
-    NSMutableDictionary *metadata_;
-    _transient NSDate *firstSeen_;
-    _transient NSDate *lastSeen_;
-    bool subscribed_;
-}
-
-- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
-+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
-
-- (pkgCache::PkgIterator) iterator;
-- (void) parse;
-
-- (NSString *) section;
-- (NSString *) simpleSection;
-
-- (NSString *) longSection;
-- (NSString *) shortSection;
-
-- (NSString *) uri;
-
-- (Address *) maintainer;
-- (size_t) size;
-- (NSString *) longDescription;
-- (NSString *) shortDescription;
-- (unichar) index;
-
-- (NSMutableDictionary *) metadata;
-- (NSDate *) seen;
-- (BOOL) subscribed;
-- (BOOL) ignored;
-
-- (NSString *) latest;
-- (NSString *) installed;
-- (BOOL) uninstalled;
-
-- (BOOL) valid;
-- (BOOL) upgradableAndEssential:(BOOL)essential;
-- (BOOL) essential;
-- (BOOL) broken;
-- (BOOL) unfiltered;
-- (BOOL) visible;
-
-- (BOOL) half;
-- (BOOL) halfConfigured;
-- (BOOL) halfInstalled;
-- (BOOL) hasMode;
-- (NSString *) mode;
-
-- (void) setVisible;
-
-- (NSString *) id;
-- (NSString *) name;
-- (UIImage *) icon;
-- (NSString *) homepage;
-- (NSString *) depiction;
-- (Address *) author;
-
-- (NSString *) support;
-
-- (NSArray *) files;
-- (NSArray *) relationships;
-- (NSArray *) warnings;
-- (NSArray *) applications;
-
-- (Source *) source;
-- (NSString *) role;
-
-- (BOOL) matches:(NSString *)text;
-
-- (bool) hasSupportingRole;
-- (BOOL) hasTag:(NSString *)tag;
-- (NSString *) primaryPurpose;
-- (NSArray *) purposes;
-- (bool) isCommercial;
-
-- (CYString &) cyname;
-
-- (uint32_t) compareBySection:(NSArray *)sections;
-
-- (uint32_t) compareForChanges;
-
-- (void) install;
-- (void) remove;
-
-- (bool) isUnfilteredAndSearchedForBy:(NSString *)search;
-- (bool) isUnfilteredAndSelectedForBy:(NSString *)search;
-- (bool) isInstalledAndVisible:(NSNumber *)number;
-- (bool) isVisibleInSection:(NSString *)section;
-- (bool) isVisibleInSource:(Source *)source;
-
-@end
-
-uint32_t PackageChangesRadix(Package *self, void *) {
-    union {
-        uint32_t key;
-
-        struct {
-            uint32_t timestamp : 30;
-            uint32_t ignored : 1;
-            uint32_t upgradable : 1;
-        } bits;
-    } value;
-
-    bool upgradable([self upgradableAndEssential:YES]);
-    value.bits.upgradable = upgradable ? 1 : 0;
-
-    if (upgradable) {
-        value.bits.timestamp = 0;
-        value.bits.ignored = [self ignored] ? 0 : 1;
-        value.bits.upgradable = 1;
-    } else {
-        value.bits.timestamp = static_cast<uint32_t>([[self seen] timeIntervalSince1970]) >> 2;
-        value.bits.ignored = 0;
-        value.bits.upgradable = 0;
-    }
-
-    return _not(uint32_t) - value.key;
-}
-
-_finline static void Stifle(uint8_t &value) {
-}
-
-uint32_t PackagePrefixRadix(Package *self, void *context) {
-    size_t offset(reinterpret_cast<size_t>(context));
-    CYString &name([self cyname]);
-
-    size_t size(name.size());
-    if (size == 0)
-        return 0;
-    char *text(name.data());
-
-    size_t zeros;
-    if (!isdigit(text[0]))
-        zeros = 0;
-    else {
-        size_t digits(1);
-        while (size != digits && isdigit(text[digits]))
-            if (++digits == 4)
-                break;
-        zeros = 4 - digits;
-    }
-
-    uint8_t data[4];
-
-    // 0.607997
-
-    if (offset == 0 && zeros != 0) {
-        memset(data, '0', zeros);
-        memcpy(data + zeros, text, 4 - zeros);
-    } else {
-        /* XXX: there's some danger here if you request a non-zero offset < 4 and it gets zero padded */
-        if (size <= offset - zeros)
-            return 0;
-
-        text += offset - zeros;
-        size -= offset - zeros;
-
-        if (size >= 4)
-            memcpy(data, text, 4);
-        else {
-            memcpy(data, text, size);
-            memset(data + size, 0, 4 - size);
-        }
-
-        for (size_t i(0); i != 4; ++i)
-            if (isalpha(data[i]))
-                data[i] &= 0xdf;
-    }
-
-    if (offset == 0)
-        data[0] = (data[0] & 0x3f) | "\x80\x00\xc0\x40"[data[0] >> 6];
-
-    /* XXX: ntohl may be more honest */
-    return OSSwapInt32(*reinterpret_cast<uint32_t *>(data));
-}
-
-CYString &(*PackageName)(Package *self, SEL sel);
-
-CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
-    _profile(PackageNameCompare)
-        CYString &lhi(PackageName(lhs, @selector(cyname)));
-        CYString &rhi(PackageName(rhs, @selector(cyname)));
-        CFStringRef lhn(lhi), rhn(rhi);
-
-        if (lhn == NULL)
-            return rhn == NULL ? NSOrderedSame : NSOrderedAscending;
-        else if (rhn == NULL)
-            return NSOrderedDescending;
-
-        _profile(PackageNameCompare$NumbersLast)
-            if (!lhi.empty() && !rhi.empty()) {
-                UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0));
-                UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0));
-                bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet));
-                if (lha != CFUniCharIsMemberOf(rhc, kCFUniCharLetterCharacterSet))
-                    return lha ? NSOrderedAscending : NSOrderedDescending;
-            }
-        _end
-
-        CFIndex length = CFStringGetLength(lhn);
-
-        _profile(PackageNameCompare$Compare)
-            return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, length), LaxCompareFlags_, Locale_);
-        _end
-    _end
-}
-
-CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *context) {
-    return PackageNameCompare(*lhs, *rhs, context);
-}
-
-struct PackageNameOrdering :
-    std::binary_function<Package *, Package *, bool>
-{
-    _finline bool operator ()(Package *lhs, Package *rhs) const {
-        return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending;
-    }
-};
-
-@implementation Package
-
-- (NSString *) description {
-    return [NSString stringWithFormat:@"<Package:%@>", static_cast<NSString *>(name_)];
-}
-
-- (void) dealloc {
-    if (source_ != nil)
-        [source_ release];
-    if (section$_ != nil)
-        [section$_ release];
-
-    if (latest_ != nil)
-        [latest_ release];
-
-    if (sponsor$_ != nil)
-        [sponsor$_ release];
-    if (author$_ != nil)
-        [author$_ release];
-    if (tags_ != nil)
-        [tags_ release];
-    if (role_ != nil)
-        [role_ release];
-
-    if (relationships_ != nil)
-        [relationships_ release];
-    if (metadata_ != nil)
-        [metadata_ release];
-
-    [super dealloc];
-}
-
-+ (NSString *) webScriptNameForSelector:(SEL)selector {
-    if (selector == @selector(hasTag:))
-        return @"hasTag";
-    else
-        return nil;
-}
-
-+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
-    return [self webScriptNameForSelector:selector] == nil;
-}
-
-+ (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"longDescription", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"warnings", nil];
-}
-
-- (NSArray *) attributeKeys {
-    return [[self class] _attributeKeys];
-}
-
-+ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
-    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
-}
-
-- (void) parse {
-    if (parsed_)
-        return;
-    parsed_ = true;
-    if (file_.end())
-        return;
-
-    _profile(Package$parse)
-        pkgRecords::Parser *parser;
-
-        _profile(Package$parse$Lookup)
-            parser = &[database_ records]->Lookup(file_);
-        _end
-
-        CYString website;
-
-        _profile(Package$parse$Find)
-            struct {
-                const char *name_;
-                CYString *value_;
-            } names[] = {
-                {"icon", &icon_},
-                {"depiction", &depiction_},
-                {"homepage", &homepage_},
-                {"website", &website},
-                {"bugs", &bugs_},
-                {"support", &support_},
-                {"sponsor", &sponsor_},
-                {"author", &author_},
-            };
-
-            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
-                const char *start, *end;
-
-                if (parser->Find(names[i].name_, start, end)) {
-                    CYString &value(*names[i].value_);
-                    _profile(Package$parse$Value)
-                        value.set(pool_, start, end - start);
-                    _end
-                }
-            }
-        _end
-
-        _profile(Package$parse$Tagline)
-            const char *start, *end;
-            if (parser->ShortDesc(start, end)) {
-                const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
-                if (stop == NULL)
-                    stop = end;
-                while (stop != start && stop[-1] == '\r')
-                    --stop;
-                tagline_.set(pool_, start, stop - start);
-            }
-        _end
-
-        _profile(Package$parse$Retain)
-            if (homepage_.empty())
-                homepage_ = website;
-            if (homepage_ == depiction_)
-                homepage_.clear();
-        _end
-    _end
-}
-
-- (void) setVisible {
-    visible_ = required_ && [self unfiltered];
-}
-
-- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
-    if ((self = [super init]) != nil) {
-    _profile(Package$initWithVersion)
-    @synchronized (database) {
-        era_ = [database era];
-        pool_ = pool;
-
-        version_ = version;
-        iterator_ = version.ParentPkg();
-        database_ = database;
-
-        _profile(Package$initWithVersion$Latest)
-            latest_ = (NSString *) StripVersion(version_.VerStr());
-        _end
-
-        pkgCache::VerIterator current;
-        _profile(Package$initWithVersion$Versions)
-            current = iterator_.CurrentVer();
-            if (!current.end())
-                installed_.set(pool_, StripVersion_(current.VerStr()));
-
-            if (!version_.end())
-                file_ = version_.FileList();
-            else {
-                pkgCache &cache([database_ cache]);
-                file_ = pkgCache::VerFileIterator(cache, cache.VerFileP);
-            }
-        _end
-
-        _profile(Package$initWithVersion$Name)
-            id_.set(pool_, iterator_.Name());
-            name_.set(pool, iterator_.Display());
-        _end
-
-        if (!file_.end()) {
-            _profile(Package$initWithVersion$Source)
-                source_ = [database_ getSource:file_.File()];
-                if (source_ != nil)
-                    [source_ retain];
-                cached_ = true;
-            _end
-        }
-
-        required_ = true;
-
-        _profile(Package$initWithVersion$Tags)
-            pkgCache::TagIterator tag(iterator_.TagList());
-            if (!tag.end()) {
-                tags_ = [[NSMutableArray alloc] initWithCapacity:8];
-                do {
-                    const char *name(tag.Name());
-                    [tags_ addObject:(NSString *)CFCString(name)];
-                    if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
-                        role_ = (NSString *) CFCString(name + 6);
-                    if (required_ && strncmp(name, "require::", 9) == 0 && (
-                        true
-                    ))
-                        required_ = false;
-                    ++tag;
-                } while (!tag.end());
-            }
-        _end
-
-        bool changed(false);
-        NSString *key([static_cast<id>(id_) lowercaseString]);
-
-        _profile(Package$initWithVersion$Metadata)
-            metadata_ = [Packages_ objectForKey:key];
-
-            if (metadata_ == nil) {
-                firstSeen_ = now_;
-
-                metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
-                    firstSeen_, @"FirstSeen",
-                    latest_, @"LastVersion",
-                nil] mutableCopy];
-
-                changed = true;
-            } else {
-                firstSeen_ = [metadata_ objectForKey:@"FirstSeen"];
-                lastSeen_ = [metadata_ objectForKey:@"LastSeen"];
-
-                if (NSNumber *subscribed = [metadata_ objectForKey:@"IsSubscribed"])
-                    subscribed_ = [subscribed boolValue];
-
-                NSString *version([metadata_ objectForKey:@"LastVersion"]);
-
-                if (firstSeen_ == nil) {
-                    firstSeen_ = lastSeen_ == nil ? now_ : lastSeen_;
-                    [metadata_ setObject:firstSeen_ forKey:@"FirstSeen"];
-                    changed = true;
-                }
-
-                if (version == nil) {
-                    [metadata_ setObject:latest_ forKey:@"LastVersion"];
-                    changed = true;
-                } else if (![version isEqualToString:latest_]) {
-                    [metadata_ setObject:latest_ forKey:@"LastVersion"];
-                    lastSeen_ = now_;
-                    [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
-                    changed = true;
-                }
-            }
-
-            metadata_ = [metadata_ retain];
-
-            if (changed) {
-                [Packages_ setObject:metadata_ forKey:key];
-                Changed_ = true;
-            }
-        _end
-
-        _profile(Package$initWithVersion$Section)
-            section_.set(pool_, iterator_.Section());
-        _end
-
-        obsolete_ = [self hasTag:@"cydia::obsolete"];
-        essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
-        [self setVisible];
-    } _end } return self;
-}
-
-+ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
-@synchronized ([Database class]) {
-    pkgCache::VerIterator version;
-
-    _profile(Package$packageWithIterator$GetCandidateVer)
-        version = [database policy]->GetCandidateVer(iterator);
-    _end
-
-    if (version.end())
-        return nil;
-
-    return [[[Package alloc]
-        initWithVersion:version
-        withZone:zone
-        inPool:pool
-        database:database
-    ] autorelease];
-} }
-
-- (pkgCache::PkgIterator) iterator {
-    return iterator_;
-}
-
-- (NSString *) section {
-    if (section$_ == nil) {
-        if (section_.empty())
-            return nil;
-
-        std::replace(section_.data(), section_.data() + section_.size(), ' ', '_');
-        NSString *name(section_);
-
-      lookup:
-        if (NSDictionary *value = [SectionMap_ objectForKey:name])
-            if (NSString *rename = [value objectForKey:@"Rename"]) {
-                name = rename;
-                goto lookup;
-            }
-
-        section$_ = [[name stringByReplacingCharacter:'_' withCharacter:' '] retain];
-    } return section$_;
-}
-
-- (NSString *) simpleSection {
-    if (NSString *section = [self section])
-        return Simplify(section);
-    else
-        return nil;
-}
-
-- (NSString *) longSection {
-    return LocalizeSection([self section]);
-}
-
-- (NSString *) shortSection {
-    return [[NSBundle mainBundle] localizedStringForKey:[self simpleSection] value:nil table:@"Sections"];
-}
-
-- (NSString *) uri {
-    return nil;
-#if 0
-    pkgIndexFile *index;
-    pkgCache::PkgFileIterator file(file_.File());
-    if (![database_ list].FindIndex(file, index))
-        return nil;
-    return [NSString stringWithUTF8String:iterator_->Path];
-    //return [NSString stringWithUTF8String:file.Site()];
-    //return [NSString stringWithUTF8String:index->ArchiveURI(file.FileName()).c_str()];
-#endif
-}
-
-- (Address *) maintainer {
-    if (file_.end())
-        return nil;
-    pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
-    const std::string &maintainer(parser->Maintainer());
-    return maintainer.empty() ? nil : [Address addressWithString:[NSString stringWithUTF8String:maintainer.c_str()]];
-}
-
-- (size_t) size {
-    return version_.end() ? 0 : version_->InstalledSize;
-}
-
-- (NSString *) longDescription {
-    if (file_.end())
-        return nil;
-    pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
-    NSString *description([NSString stringWithUTF8String:parser->LongDesc().c_str()]);
-
-    NSArray *lines = [description componentsSeparatedByString:@"\n"];
-    NSMutableArray *trimmed = [NSMutableArray arrayWithCapacity:([lines count] - 1)];
-    if ([lines count] < 2)
-        return nil;
-
-    NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet];
-    for (size_t i(1), e([lines count]); i != e; ++i) {
-        NSString *trim = [[lines objectAtIndex:i] stringByTrimmingCharactersInSet:whitespace];
-        [trimmed addObject:trim];
-    }
-
-    return [trimmed componentsJoinedByString:@"\n"];
-}
-
-- (NSString *) shortDescription {
-    return tagline_;
-}
-
-- (unichar) index {
-    _profile(Package$index)
-        CFStringRef name((CFStringRef) [self name]);
-        if (CFStringGetLength(name) == 0)
-            return '#';
-        UniChar character(CFStringGetCharacterAtIndex(name, 0));
-        if (!CFUniCharIsMemberOf(character, kCFUniCharLetterCharacterSet))
-            return '#';
-        return toupper(character);
-    _end
-}
-
-- (NSMutableDictionary *) metadata {
-    return metadata_;
-}
-
-- (NSDate *) seen {
-    if (subscribed_ && lastSeen_ != nil)
-        return lastSeen_;
-    return firstSeen_;
-}
-
-- (BOOL) subscribed {
-    return subscribed_;
-}
-
-- (BOOL) ignored {
-    NSDictionary *metadata([self metadata]);
-    if (NSNumber *ignored = [metadata objectForKey:@"IsIgnored"])
-        return [ignored boolValue];
-    else
-        return false;
-}
-
-- (NSString *) latest {
-    return latest_;
-}
-
-- (NSString *) installed {
-    return installed_;
-}
-
-- (BOOL) uninstalled {
-    return installed_.empty();
-}
-
-- (BOOL) valid {
-    return !version_.end();
-}
-
-- (BOOL) upgradableAndEssential:(BOOL)essential {
-    _profile(Package$upgradableAndEssential)
-        pkgCache::VerIterator current(iterator_.CurrentVer());
-        if (current.end())
-            return essential && essential_ && visible_;
-        else
-            return !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep());
-    _end
-}
-
-- (BOOL) essential {
-    return essential_;
-}
-
-- (BOOL) broken {
-    return [database_ cache][iterator_].InstBroken();
-}
-
-- (BOOL) unfiltered {
-    NSString *section([self section]);
-    return !obsolete_ && [self hasSupportingRole] && (section == nil || isSectionVisible(section));
-}
-
-- (BOOL) visible {
-    return visible_;
-}
-
-- (BOOL) half {
-    unsigned char current(iterator_->CurrentState);
-    return current == pkgCache::State::HalfConfigured || current == pkgCache::State::HalfInstalled;
-}
-
-- (BOOL) halfConfigured {
-    return iterator_->CurrentState == pkgCache::State::HalfConfigured;
-}
-
-- (BOOL) halfInstalled {
-    return iterator_->CurrentState == pkgCache::State::HalfInstalled;
-}
-
-- (BOOL) hasMode {
-    pkgDepCache::StateCache &state([database_ cache][iterator_]);
-    return state.Mode != pkgDepCache::ModeKeep;
-}
-
-- (NSString *) mode {
-    pkgDepCache::StateCache &state([database_ cache][iterator_]);
-
-    switch (state.Mode) {
-        case pkgDepCache::ModeDelete:
-            if ((state.iFlags & pkgDepCache::Purge) != 0)
-                return @"PURGE";
-            else
-                return @"REMOVE";
-        case pkgDepCache::ModeKeep:
-            if ((state.iFlags & pkgDepCache::ReInstall) != 0)
-                return @"REINSTALL";
-            /*else if ((state.iFlags & pkgDepCache::AutoKept) != 0)
-                return nil;*/
-            else
-                return nil;
-        case pkgDepCache::ModeInstall:
-            /*if ((state.iFlags & pkgDepCache::ReInstall) != 0)
-                return @"REINSTALL";
-            else*/ switch (state.Status) {
-                case -1:
-                    return @"DOWNGRADE";
-                case 0:
-                    return @"INSTALL";
-                case 1:
-                    return @"UPGRADE";
-                case 2:
-                    return @"NEW_INSTALL";
-                _nodefault
-            }
-        _nodefault
-    }
-}
-
-- (NSString *) id {
-    return id_;
-}
-
-- (NSString *) name {
-    return name_.empty() ? id_ : name_;
-}
-
-- (UIImage *) icon {
-    NSString *section = [self simpleSection];
-
-    UIImage *icon(nil);
-    if (!icon_.empty())
-        if ([static_cast<id>(icon_) hasPrefix:@"file:///"])
-            // XXX: correct escaping
-            icon = [UIImage imageAtPath:[static_cast<id>(icon_) substringFromIndex:7]];
-    if (icon == nil) if (section != nil)
-        icon = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]];
-    if (icon == nil) if (source_ != nil) if (NSString *dicon = [source_ defaultIcon])
-        if ([dicon hasPrefix:@"file:///"])
-            // XXX: correct escaping
-            icon = [UIImage imageAtPath:[dicon substringFromIndex:7]];
-    if (icon == nil)
-        icon = [UIImage applicationImageNamed:@"unknown.png"];
-    return icon;
-}
-
-- (NSString *) homepage {
-    return homepage_;
-}
-
-- (NSString *) depiction {
-    return !depiction_.empty() ? depiction_ : [[self source] depictionForPackage:id_];
-}
-
-- (Address *) sponsor {
-    if (sponsor$_ == nil) {
-        if (sponsor_.empty())
-            return nil;
-        sponsor$_ = [[Address addressWithString:sponsor_] retain];
-    } return sponsor$_;
-}
-
-- (Address *) author {
-    if (author$_ == nil) {
-        if (author_.empty())
-            return nil;
-        author$_ = [[Address addressWithString:author_] retain];
-    } return author$_;
-}
-
-- (NSString *) support {
-    return !bugs_.empty() ? bugs_ : [[self source] supportForPackage:id_];
-}
-
-- (NSArray *) files {
-    NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", static_cast<NSString *>(id_)];
-    NSMutableArray *files = [NSMutableArray arrayWithCapacity:128];
-
-    std::ifstream fin;
-    fin.open([path UTF8String]);
-    if (!fin.is_open())
-        return nil;
-
-    std::string line;
-    while (std::getline(fin, line))
-        [files addObject:[NSString stringWithUTF8String:line.c_str()]];
-
-    return files;
-}
-
-- (NSArray *) relationships {
-    return relationships_;
-}
-
-- (NSArray *) warnings {
-    NSMutableArray *warnings([NSMutableArray arrayWithCapacity:4]);
-    const char *name(iterator_.Name());
-
-    size_t length(strlen(name));
-    if (length < 2) invalid:
-        [warnings addObject:UCLocalize("ILLEGAL_PACKAGE_IDENTIFIER")];
-    else for (size_t i(0); i != length; ++i)
-        if (
-            /* XXX: technically this is not allowed */
-            (name[i] < 'A' || name[i] > 'Z') &&
-            (name[i] < 'a' || name[i] > 'z') &&
-            (name[i] < '0' || name[i] > '9') &&
-            (i == 0 || name[i] != '+' && name[i] != '-' && name[i] != '.')
-        ) goto invalid;
-
-    if (strcmp(name, "cydia") != 0) {
-        bool cydia = false;
-        bool user = false;
-        bool _private = false;
-        bool stash = false;
-
-        bool repository = [[self section] isEqualToString:@"Repositories"];
-
-        if (NSArray *files = [self files])
-            for (NSString *file in files)
-                if (!cydia && [file isEqualToString:@"/Applications/Cydia.app"])
-                    cydia = true;
-                else if (!user && [file isEqualToString:@"/User"])
-                    user = true;
-                else if (!_private && [file isEqualToString:@"/private"])
-                    _private = true;
-                else if (!stash && [file isEqualToString:@"/var/stash"])
-                    stash = true;
-
-        /* XXX: this is not sensitive enough. only some folders are valid. */
-        if (cydia && !repository)
-            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"Cydia.app"]];
-        if (user)
-            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/User"]];
-        if (_private)
-            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/private"]];
-        if (stash)
-            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/var/stash"]];
-    }
-
-    return [warnings count] == 0 ? nil : warnings;
-}
-
-- (NSArray *) applications {
-    NSString *me([[NSBundle mainBundle] bundleIdentifier]);
-
-    NSMutableArray *applications([NSMutableArray arrayWithCapacity:2]);
-
-    static Pcre application_r("^/Applications/(.*)\\.app/Info.plist$");
-    if (NSArray *files = [self files])
-        for (NSString *file in files)
-            if (application_r(file)) {
-                NSDictionary *info([NSDictionary dictionaryWithContentsOfFile:file]);
-                NSString *id([info objectForKey:@"CFBundleIdentifier"]);
-                if ([id isEqualToString:me])
-                    continue;
-
-                NSString *display([info objectForKey:@"CFBundleDisplayName"]);
-                if (display == nil)
-                    display = application_r[1];
-
-                NSString *bundle([file stringByDeletingLastPathComponent]);
-                NSString *icon([info objectForKey:@"CFBundleIconFile"]);
-                if (icon == nil || [icon length] == 0)
-                    icon = @"icon.png";
-                NSURL *url([NSURL fileURLWithPath:[bundle stringByAppendingPathComponent:icon]]);
-
-                NSMutableArray *application([NSMutableArray arrayWithCapacity:2]);
-                [applications addObject:application];
-
-                [application addObject:id];
-                [application addObject:display];
-                [application addObject:url];
-            }
-
-    return [applications count] == 0 ? nil : applications;
-}
-
-- (Source *) source {
-    if (!cached_) {
-        @synchronized (database_) {
-            if ([database_ era] != era_ || file_.end())
-                source_ = nil;
-            else {
-                source_ = [database_ getSource:file_.File()];
-                if (source_ != nil)
-                    [source_ retain];
-            }
-
-            cached_ = true;
-        }
-    }
-
-    return source_;
-}
-
-- (NSString *) role {
-    return role_;
-}
-
-- (BOOL) matches:(NSString *)text {
-    if (text == nil)
-        return NO;
-
-    NSRange range;
-
-    range = [[self id] rangeOfString:text options:MatchCompareOptions_];
-    if (range.location != NSNotFound)
-        return YES;
-
-    range = [[self name] rangeOfString:text options:MatchCompareOptions_];
-    if (range.location != NSNotFound)
-        return YES;
-
-    range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_];
-    if (range.location != NSNotFound)
-        return YES;
-
-    return NO;
-}
-
-- (bool) hasSupportingRole {
-    if (role_ == nil)
-        return true;
-    if ([role_ isEqualToString:@"enduser"])
-        return true;
-    if ([Role_ isEqualToString:@"User"])
-        return false;
-    if ([role_ isEqualToString:@"hacker"])
-        return true;
-    if ([Role_ isEqualToString:@"Hacker"])
-        return false;
-    if ([role_ isEqualToString:@"developer"])
-        return true;
-    if ([Role_ isEqualToString:@"Developer"])
-        return false;
-    _assert(false);
-}
-
-- (BOOL) hasTag:(NSString *)tag {
-    return tags_ == nil ? NO : [tags_ containsObject:tag];
-}
-
-- (NSString *) primaryPurpose {
-    for (NSString *tag in tags_)
-        if ([tag hasPrefix:@"purpose::"])
-            return [tag substringFromIndex:9];
-    return nil;
-}
-
-- (NSArray *) purposes {
-    NSMutableArray *purposes([NSMutableArray arrayWithCapacity:2]);
-    for (NSString *tag in tags_)
-        if ([tag hasPrefix:@"purpose::"])
-            [purposes addObject:[tag substringFromIndex:9]];
-    return [purposes count] == 0 ? nil : purposes;
-}
-
-- (bool) isCommercial {
-    return [self hasTag:@"cydia::commercial"];
-}
-
-- (CYString &) cyname {
-    return name_.empty() ? id_ : name_;
-}
-
-- (uint32_t) compareBySection:(NSArray *)sections {
-    NSString *section([self section]);
-    for (size_t i(0), e([sections count]); i != e; ++i) {
-        if ([section isEqualToString:[[sections objectAtIndex:i] name]])
-            return i;
-    }
-
-    return _not(uint32_t);
-}
-
-- (uint32_t) compareForChanges {
-    union {
-        uint32_t key;
-
-        struct {
-            uint32_t timestamp : 30;
-            uint32_t ignored : 1;
-            uint32_t upgradable : 1;
-        } bits;
-    } value;
-
-    bool upgradable([self upgradableAndEssential:YES]);
-    value.bits.upgradable = upgradable ? 1 : 0;
-
-    if (upgradable) {
-        value.bits.timestamp = 0;
-        value.bits.ignored = [self ignored] ? 0 : 1;
-        value.bits.upgradable = 1;
-    } else {
-        value.bits.timestamp = static_cast<uint32_t>([[self seen] timeIntervalSince1970]) >> 2;
-        value.bits.ignored = 0;
-        value.bits.upgradable = 0;
-    }
-
-    return _not(uint32_t) - value.key;
-}
-
-- (void) clear {
-    pkgProblemResolver *resolver = [database_ resolver];
-    resolver->Clear(iterator_);
-    resolver->Protect(iterator_);
-}
-
-- (void) install {
-    pkgProblemResolver *resolver = [database_ resolver];
-    resolver->Clear(iterator_);
-    resolver->Protect(iterator_);
-    pkgCacheFile &cache([database_ cache]);
-    cache->MarkInstall(iterator_, false);
-    pkgDepCache::StateCache &state((*cache)[iterator_]);
-    if (!state.Install())
-        cache->SetReInstall(iterator_, true);
-}
-
-- (void) remove {
-    pkgProblemResolver *resolver = [database_ resolver];
-    resolver->Clear(iterator_);
-    resolver->Protect(iterator_);
-    resolver->Remove(iterator_);
-    [database_ cache]->MarkDelete(iterator_, true);
-}
-
-- (bool) isUnfilteredAndSearchedForBy:(NSString *)search {
-    _profile(Package$isUnfilteredAndSearchedForBy)
-        bool value(true);
-
-        _profile(Package$isUnfilteredAndSearchedForBy$Unfiltered)
-            value &= [self unfiltered];
-        _end
-
-        _profile(Package$isUnfilteredAndSearchedForBy$Match)
-            value &= [self matches:search];
-        _end
-
-        return value;
-    _end
-}
-
-- (bool) isUnfilteredAndSelectedForBy:(NSString *)search {
-    if ([search length] == 0)
-        return false;
-
-    _profile(Package$isUnfilteredAndSelectedForBy)
-        bool value(true);
-
-        _profile(Package$isUnfilteredAndSelectedForBy$Unfiltered)
-            value &= [self unfiltered];
-        _end
-
-        _profile(Package$isUnfilteredAndSelectedForBy$Match)
-            value &= [[self name] compare:search options:MatchCompareOptions_ range:NSMakeRange(0, [search length])] == NSOrderedSame;
-        _end
-
-        return value;
-    _end
-}
-
-- (bool) isInstalledAndVisible:(NSNumber *)number {
-    return (![number boolValue] || [self visible]) && ![self uninstalled];
-}
-
-- (bool) isVisibleInSection:(NSString *)name {
-    NSString *section = [self section];
-
-    return
-        [self visible] && (
-            name == nil ||
-            section == nil && [name length] == 0 ||
-            [name isEqualToString:section]
-        );
-}
-
-- (bool) isVisibleInSource:(Source *)source {
-    return [self source] == source && [self visible];
-}
-
-@end
-/* }}} */
-/* Section Class {{{ */
-@interface Section : NSObject {
-    NSString *name_;
-    unichar index_;
-    size_t row_;
-    size_t count_;
-    NSString *localized_;
-}
-
-- (NSComparisonResult) compareByLocalized:(Section *)section;
-- (Section *) initWithName:(NSString *)name localized:(NSString *)localized;
-- (Section *) initWithName:(NSString *)name localize:(BOOL)localize;
-- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize;
-- (Section *) initWithIndex:(unichar)index row:(size_t)row;
-- (NSString *) name;
-- (unichar) index;
-
-- (size_t) row;
-- (size_t) count;
-
-- (void) addToRow;
-- (void) addToCount;
-
-- (void) setCount:(size_t)count;
-- (NSString *) localized;
-
-@end
-
-@implementation Section
-
-- (void) dealloc {
-    [name_ release];
-    if (localized_ != nil)
-        [localized_ release];
-    [super dealloc];
-}
-
-- (NSComparisonResult) compareByLocalized:(Section *)section {
-    NSString *lhs(localized_);
-    NSString *rhs([section localized]);
-
-    /*if ([lhs length] != 0 && [rhs length] != 0) {
-        unichar lhc = [lhs characterAtIndex:0];
-        unichar rhc = [rhs characterAtIndex:0];
-
-        if (isalpha(lhc) && !isalpha(rhc))
-            return NSOrderedAscending;
-        else if (!isalpha(lhc) && isalpha(rhc))
-            return NSOrderedDescending;
-    }*/
-
-    return [lhs compare:rhs options:LaxCompareOptions_];
-}
-
-- (Section *) initWithName:(NSString *)name localized:(NSString *)localized {
-    if ((self = [self initWithName:name localize:NO]) != nil) {
-        if (localized != nil)
-            localized_ = [localized retain];
-    } return self;
-}
-
-- (Section *) initWithName:(NSString *)name localize:(BOOL)localize {
-    return [self initWithName:name row:0 localize:localize];
-}
-
-- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize {
-    if ((self = [super init]) != nil) {
-        name_ = [name retain];
-        index_ = '\0';
-        row_ = row;
-        if (localize)
-            localized_ = [LocalizeSection(name_) retain];
-    } return self;
-}
-
-/* XXX: localize the index thingees */
-- (Section *) initWithIndex:(unichar)index row:(size_t)row {
-    if ((self = [super init]) != nil) {
-        name_ = [[NSString stringWithCharacters:&index length:1] retain];
-        index_ = index;
-        row_ = row;
-    } return self;
-}
-
-- (NSString *) name {
-    return name_;
-}
-
-- (unichar) index {
-    return index_;
-}
-
-- (size_t) row {
-    return row_;
-}
-
-- (size_t) count {
-    return count_;
-}
-
-- (void) addToRow {
-    ++row_;
-}
-
-- (void) addToCount {
-    ++count_;
-}
-
-- (void) setCount:(size_t)count {
-    count_ = count;
-}
-
-- (NSString *) localized {
-    return localized_;
-}
-
-@end
-/* }}} */
-
-static NSString *Colon_;
-static NSString *Error_;
-static NSString *Warning_;
-
-/* Database Implementation {{{ */
-@implementation Database
-
-+ (Database *) sharedInstance {
-    static Database *instance;
-    if (instance == nil)
-        instance = [[Database alloc] init];
-    return instance;
-}
-
-- (unsigned) era {
-    return era_;
-}
-
-- (void) dealloc {
-    _assert(false);
-    NSRecycleZone(zone_);
-    // XXX: malloc_destroy_zone(zone_);
-    apr_pool_destroy(pool_);
-    [super dealloc];
-}
-
-- (void) _readCydia:(NSNumber *)fd { _pooled
-    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
-    std::istream is(&ib);
-    std::string line;
-
-    static Pcre finish_r("^finish:([^:]*)$");
-
-    while (std::getline(is, line)) {
-        const char *data(line.c_str());
-        size_t size = line.size();
-        lprintf("C:%s\n", data);
-
-        if (finish_r(data, size)) {
-            NSString *finish = finish_r[1];
-            int index = [Finishes_ indexOfObject:finish];
-            if (index != INT_MAX && index > Finish_)
-                Finish_ = index;
-        }
-    }
-
-    _assume(false);
-}
-
-- (void) _readStatus:(NSNumber *)fd { _pooled
-    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
-    std::istream is(&ib);
-    std::string line;
-
-    static Pcre conffile_r("^status: [^ ]* : conffile-prompt : (.*?) *$");
-    static Pcre pmstatus_r("^([^:]*):([^:]*):([^:]*):(.*)$");
-
-    while (std::getline(is, line)) {
-        const char *data(line.c_str());
-        size_t size(line.size());
-        lprintf("S:%s\n", data);
-
-        if (conffile_r(data, size)) {
-            [delegate_ setConfigurationData:conffile_r[1]];
-        } else if (strncmp(data, "status: ", 8) == 0) {
-            NSString *string = [NSString stringWithUTF8String:(data + 8)];
-            [delegate_ setProgressTitle:string];
-        } else if (pmstatus_r(data, size)) {
-            std::string type([pmstatus_r[1] UTF8String]);
-            NSString *id = pmstatus_r[2];
-
-            float percent([pmstatus_r[3] floatValue]);
-            [delegate_ setProgressPercent:(percent / 100)];
-
-            NSString *string = pmstatus_r[4];
-
-            if (type == "pmerror")
-                [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
-                    withObject:[NSArray arrayWithObjects:string, id, nil]
-                    waitUntilDone:YES
-                ];
-            else if (type == "pmstatus") {
-                [delegate_ setProgressTitle:string];
-            } else if (type == "pmconffile")
-                [delegate_ setConfigurationData:string];
-            else
-                lprintf("E:unknown pmstatus\n");
-        } else
-            lprintf("E:unknown status\n");
-    }
-
-    _assume(false);
-}
-
-- (void) _readOutput:(NSNumber *)fd { _pooled
-    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
-    std::istream is(&ib);
-    std::string line;
-
-    while (std::getline(is, line)) {
-        lprintf("O:%s\n", line.c_str());
-        [delegate_ addProgressOutput:[NSString stringWithUTF8String:line.c_str()]];
-    }
-
-    _assume(false);
-}
-
-- (FILE *) input {
-    return input_;
-}
-
-- (Package *) packageWithName:(NSString *)name {
-@synchronized ([Database class]) {
-    if (static_cast<pkgDepCache *>(cache_) == NULL)
-        return nil;
-    pkgCache::PkgIterator iterator(cache_->FindPkg([name UTF8String]));
-    return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:pool_ database:self];
-} }
-
-- (id) init {
-    if ((self = [super init]) != nil) {
-        policy_ = NULL;
-        records_ = NULL;
-        resolver_ = NULL;
-        fetcher_ = NULL;
-        lock_ = NULL;
-
-        zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
-        apr_pool_create(&pool_, NULL);
-
-        packages_ = [[NSMutableArray alloc] init];
-
-        int fds[2];
-
-        _assert(pipe(fds) != -1);
-        cydiafd_ = fds[1];
-
-        _config->Set("APT::Keep-Fds::", cydiafd_);
-        setenv("CYDIA", [[[[NSNumber numberWithInt:cydiafd_] stringValue] stringByAppendingString:@" 1"] UTF8String], _not(int));
-
-        [NSThread
-            detachNewThreadSelector:@selector(_readCydia:)
-            toTarget:self
-            withObject:[[NSNumber numberWithInt:fds[0]] retain]
-        ];
-
-        _assert(pipe(fds) != -1);
-        statusfd_ = fds[1];
-
-        [NSThread
-            detachNewThreadSelector:@selector(_readStatus:)
-            toTarget:self
-            withObject:[[NSNumber numberWithInt:fds[0]] retain]
-        ];
-
-        _assert(pipe(fds) != -1);
-        _assert(dup2(fds[0], 0) != -1);
-        _assert(close(fds[0]) != -1);
-
-        input_ = fdopen(fds[1], "a");
-
-        _assert(pipe(fds) != -1);
-        _assert(dup2(fds[1], 1) != -1);
-        _assert(close(fds[1]) != -1);
-
-        [NSThread
-            detachNewThreadSelector:@selector(_readOutput:)
-            toTarget:self
-            withObject:[[NSNumber numberWithInt:fds[0]] retain]
-        ];
-    } return self;
-}
-
-- (pkgCacheFile &) cache {
-    return cache_;
-}
-
-- (pkgDepCache::Policy *) policy {
-    return policy_;
-}
-
-- (pkgRecords *) records {
-    return records_;
-}
-
-- (pkgProblemResolver *) resolver {
-    return resolver_;
-}
-
-- (pkgAcquire &) fetcher {
-    return *fetcher_;
-}
-
-- (pkgSourceList &) list {
-    return *list_;
-}
-
-- (NSArray *) packages {
-    return packages_;
-}
-
-- (NSArray *) sources {
-    NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
-    for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
-        [sources addObject:i->second];
-    return sources;
-}
-
-- (NSArray *) issues {
-    if (cache_->BrokenCount() == 0)
-        return nil;
-
-    NSMutableArray *issues([NSMutableArray arrayWithCapacity:4]);
-
-    for (Package *package in packages_) {
-        if (![package broken])
-            continue;
-        pkgCache::PkgIterator pkg([package iterator]);
-
-        NSMutableArray *entry([NSMutableArray arrayWithCapacity:4]);
-        [entry addObject:[package name]];
-        [issues addObject:entry];
-
-        pkgCache::VerIterator ver(cache_[pkg].InstVerIter(cache_));
-        if (ver.end())
-            continue;
-
-        for (pkgCache::DepIterator dep(ver.DependsList()); !dep.end(); ) {
-            pkgCache::DepIterator start;
-            pkgCache::DepIterator end;
-            dep.GlobOr(start, end); // ++dep
-
-            if (!cache_->IsImportantDep(end))
-                continue;
-            if ((cache_[end] & pkgDepCache::DepGInstall) != 0)
-                continue;
-
-            NSMutableArray *failure([NSMutableArray arrayWithCapacity:4]);
-            [entry addObject:failure];
-            [failure addObject:[NSString stringWithUTF8String:start.DepType()]];
-
-            NSString *name([NSString stringWithUTF8String:start.TargetPkg().Name()]);
-            if (Package *package = [self packageWithName:name])
-                name = [package name];
-            [failure addObject:name];
-
-            pkgCache::PkgIterator target(start.TargetPkg());
-            if (target->ProvidesList != 0)
-                [failure addObject:@"?"];
-            else {
-                pkgCache::VerIterator ver(cache_[target].InstVerIter(cache_));
-                if (!ver.end())
-                    [failure addObject:[NSString stringWithUTF8String:ver.VerStr()]];
-                else if (!cache_[target].CandidateVerIter(cache_).end())
-                    [failure addObject:@"-"];
-                else if (target->ProvidesList == 0)
-                    [failure addObject:@"!"];
-                else
-                    [failure addObject:@"%"];
-            }
-
-            _forever {
-                if (start.TargetVer() != 0)
-                    [failure addObject:[NSString stringWithFormat:@"%s %s", start.CompType(), start.TargetVer()]];
-                if (start == end)
-                    break;
-                ++start;
-            }
-        }
-    }
-
-    return issues;
-}
-
-- (bool) popErrorWithTitle:(NSString *)title {
-    bool fatal(false);
-    std::string message;
-
-    while (!_error->empty()) {
-        std::string error;
-        bool warning(!_error->PopMessage(error));
-        if (!warning)
-            fatal = true;
-        for (;;) {
-            size_t size(error.size());
-            if (size == 0 || error[size - 1] != '\n')
-                break;
-            error.resize(size - 1);
-        }
-        lprintf("%c:[%s]\n", warning ? 'W' : 'E', error.c_str());
-
-        if (!message.empty())
-            message += "\n\n";
-        message += error;
-    }
-
-    if (fatal && !message.empty())
-        [delegate_ _setProgressError:[NSString stringWithUTF8String:message.c_str()] withTitle:[NSString stringWithFormat:Colon_, fatal ? Error_ : Warning_, title]];
-
-    return fatal;
-}
-
-- (bool) popErrorWithTitle:(NSString *)title forOperation:(bool)success {
-    return [self popErrorWithTitle:title] || !success;
-}
-
-- (void) reloadData { _pooled
-@synchronized ([Database class]) {
-    @synchronized (self) {
-        ++era_;
-    }
-
-    [packages_ removeAllObjects];
-    sources_.clear();
-
-    _error->Discard();
-
-    delete list_;
-    list_ = NULL;
-    manager_ = NULL;
-    delete lock_;
-    lock_ = NULL;
-    delete fetcher_;
-    fetcher_ = NULL;
-    delete resolver_;
-    resolver_ = NULL;
-    delete records_;
-    records_ = NULL;
-    delete policy_;
-    policy_ = NULL;
-
-    if (now_ != nil) {
-        [now_ release];
-        now_ = nil;
-    }
-
-    cache_.Close();
-
-    apr_pool_clear(pool_);
-    NSRecycleZone(zone_);
-
-    int chk(creat("/tmp/cydia.chk", 0644));
-    if (chk != -1)
-        close(chk);
-
-    NSString *title(UCLocalize("DATABASE"));
-
-    _trace();
-    if (!cache_.Open(progress_, true)) { pop:
-        std::string error;
-        bool warning(!_error->PopMessage(error));
-        lprintf("cache_.Open():[%s]\n", error.c_str());
-
-        if (error == "dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem. ")
-            [delegate_ repairWithSelector:@selector(configure)];
-        else if (error == "The package lists or status file could not be parsed or opened.")
-            [delegate_ repairWithSelector:@selector(update)];
-        // else if (error == "Could not open lock file /var/lib/dpkg/lock - open (13 Permission denied)")
-        // else if (error == "Could not get lock /var/lib/dpkg/lock - open (35 Resource temporarily unavailable)")
-        // else if (error == "The list of sources could not be read.")
-        else
-            [delegate_ _setProgressError:[NSString stringWithUTF8String:error.c_str()] withTitle:[NSString stringWithFormat:Colon_, warning ? Warning_ : Error_, title]];
-
-        if (warning)
-            goto pop;
-        _error->Discard();
-        return;
-    }
-    _trace();
-
-    unlink("/tmp/cydia.chk");
-
-    now_ = [[NSDate date] retain];
-
-    policy_ = new pkgDepCache::Policy();
-    records_ = new pkgRecords(cache_);
-    resolver_ = new pkgProblemResolver(cache_);
-    fetcher_ = new pkgAcquire(&status_);
-    lock_ = NULL;
-
-    list_ = new pkgSourceList();
-    if ([self popErrorWithTitle:title forOperation:list_->ReadMainList()])
-        return;
-
-    if (cache_->DelCount() != 0 || cache_->InstCount() != 0) {
-        [delegate_ _setProgressError:@"COUNTS_NONZERO_EX" withTitle:title];
-        return;
-    }
-
-    if ([self popErrorWithTitle:title forOperation:pkgApplyStatus(cache_)])
-        return;
-
-    if (cache_->BrokenCount() != 0) {
-        if ([self popErrorWithTitle:title forOperation:pkgFixBroken(cache_)])
-            return;
-
-        if (cache_->BrokenCount() != 0) {
-            [delegate_ _setProgressError:@"STILL_BROKEN_EX" withTitle:title];
-            return;
-        }
-
-        if ([self popErrorWithTitle:title forOperation:pkgMinimizeUpgrade(cache_)])
-            return;
-    }
-
-    _trace();
-
-    for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
-        std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
-        for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
-            // XXX: this could be more intelligent
-            if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
-                pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
-                if (!cached.end())
-                    sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease];
-            }
-    }
-
-    _trace();
-
-    {
-        /*std::vector<Package *> packages;
-        packages.reserve(std::max(10000U, [packages_ count] + 1000));
-        [packages_ release];
-        packages_ = nil;*/
-
-        _trace();
-
-        for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator)
-            if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:pool_ database:self])
-                //packages.push_back(package);
-                [packages_ addObject:package];
-
-        _trace();
-
-        /*if (packages.empty())
-            packages_ = [[NSArray alloc] init];
-        else
-            packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()];
-        _trace();*/
-
-        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(16)];
-        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
-        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
-
-        /*_trace();
-        PrintTimes();
-        _trace();*/
-
-        _trace();
-
-        /*if (!packages.empty())
-            CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);*/
-        //std::sort(packages.begin(), packages.end(), PackageNameOrdering());
-
-        //CFArraySortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
-
-        CFArrayInsertionSortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
-
-        //[packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
-
-        _trace();
-    }
-} }
-
-- (void) configure {
-    NSString *dpkg = [NSString stringWithFormat:@"dpkg --configure -a --status-fd %u", statusfd_];
-    system([dpkg UTF8String]);
-}
-
-- (bool) clean {
-    // XXX: I don't remember this condition
-    if (lock_ != NULL)
-        return false;
-
-    FileFd Lock;
-    Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
-
-    NSString *title(UCLocalize("CLEAN_ARCHIVES"));
-
-    if ([self popErrorWithTitle:title])
-        return false;
-
-    pkgAcquire fetcher;
-    fetcher.Clean(_config->FindDir("Dir::Cache::Archives"));
-
-    class LogCleaner :
-        public pkgArchiveCleaner
-    {
-      protected:
-        virtual void Erase(const char *File, std::string Pkg, std::string Ver, struct stat &St) {
-            unlink(File);
-        }
-    } cleaner;
-
-    if ([self popErrorWithTitle:title forOperation:cleaner.Go(_config->FindDir("Dir::Cache::Archives") + "partial/", cache_)])
-        return false;
-
-    return true;
-}
-
-- (bool) prepare {
-    fetcher_->Shutdown();
-
-    pkgRecords records(cache_);
-
-    lock_ = new FileFd();
-    lock_->Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
-
-    NSString *title(UCLocalize("PREPARE_ARCHIVES"));
-
-    if ([self popErrorWithTitle:title])
-        return false;
-
-    pkgSourceList list;
-    if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
-        return false;
-
-    manager_ = (_system->CreatePM(cache_));
-    if ([self popErrorWithTitle:title forOperation:manager_->GetArchives(fetcher_, &list, &records)])
-        return false;
-
-    return true;
-}
-
-- (void) perform {
-    NSString *title(UCLocalize("PERFORM_SELECTIONS"));
-
-    NSMutableArray *before = [NSMutableArray arrayWithCapacity:16]; {
-        pkgSourceList list;
-        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
-            return;
-        for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
-            [before addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
-    }
-
-    if (fetcher_->Run(PulseInterval_) != pkgAcquire::Continue) {
-        _trace();
-        return;
-    }
-
-    bool failed = false;
-    for (pkgAcquire::ItemIterator item = fetcher_->ItemsBegin(); item != fetcher_->ItemsEnd(); item++) {
-        if ((*item)->Status == pkgAcquire::Item::StatDone && (*item)->Complete)
-            continue;
-        if ((*item)->Status == pkgAcquire::Item::StatIdle)
-            continue;
-
-        std::string uri = (*item)->DescURI();
-        std::string error = (*item)->ErrorText;
-
-        lprintf("pAf:%s:%s\n", uri.c_str(), error.c_str());
-        failed = true;
-
-        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
-            withObject:[NSArray arrayWithObjects:
-                [NSString stringWithUTF8String:error.c_str()],
-            nil]
-            waitUntilDone:YES
-        ];
-    }
-
-    if (failed) {
-        _trace();
-        return;
-    }
-
-    _system->UnLock();
-    pkgPackageManager::OrderResult result = manager_->DoInstall(statusfd_);
-
-    if (_error->PendingError()) {
-        _trace();
-        return;
-    }
-
-    if (result == pkgPackageManager::Failed) {
-        _trace();
-        return;
-    }
-
-    if (result != pkgPackageManager::Completed) {
-        _trace();
-        return;
-    }
-
-    NSMutableArray *after = [NSMutableArray arrayWithCapacity:16]; {
-        pkgSourceList list;
-        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
-            return;
-        for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
-            [after addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
-    }
-
-    if (![before isEqualToArray:after])
-        [self update];
-}
-
-- (bool) upgrade {
-    NSString *title(UCLocalize("UPGRADE"));
-    if ([self popErrorWithTitle:title forOperation:pkgDistUpgrade(cache_)])
-        return false;
-    return true;
-}
-
-- (void) update {
-    [self updateWithStatus:status_];
-}
-
-- (void) setVisible {
-    for (Package *package in packages_)
-        [package setVisible];
-}
-
-- (void) updateWithStatus:(Status &)status {
-    _transient NSObject<ProgressDelegate> *delegate(status.getDelegate());
-    NSString *title(UCLocalize("REFRESHING_DATA"));
-
-    pkgSourceList list;
-    if (!list.ReadMainList())
-        [delegate _setProgressError:@"Unable to read source list." withTitle:title];
-
-    FileFd lock;
-    lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
-    if ([self popErrorWithTitle:title])
-        return;
-
-    if ([self popErrorWithTitle:title forOperation:ListUpdate(status, list, PulseInterval_)])
-        /* XXX: ignore this because users suck and don't understand why refreshing is important: return */
-        /* XXX: why the hell is an empty if statement a clang error? */ (void) 0;
-
-    [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
-    Changed_ = true;
-}
-
-- (void) setDelegate:(id)delegate {
-    delegate_ = delegate;
-    status_.setDelegate(delegate);
-    progress_.setDelegate(delegate);
-}
-
-- (Source *) getSource:(pkgCache::PkgFileIterator)file {
-    SourceMap::const_iterator i(sources_.find(file->ID));
-    return i == sources_.end() ? nil : i->second;
-}
-
-@end
-/* }}} */
-
-/* Confirmation Controller {{{ */
-bool DepSubstrate(const pkgCache::VerIterator &iterator) {
-    if (!iterator.end())
-        for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) {
-            if (dep->Type != pkgCache::Dep::Depends && dep->Type != pkgCache::Dep::PreDepends)
-                continue;
-            pkgCache::PkgIterator package(dep.TargetPkg());
-            if (package.end())
-                continue;
-            if (strcmp(package.Name(), "mobilesubstrate") == 0)
-                return true;
-        }
-
-    return false;
-}
-/* }}} */
-
-/* Web Scripting {{{ */
-@interface CydiaObject : NSObject {
-    id indirect_;
-    id delegate_;
-}
-
-- (id) initWithDelegate:(IndirectDelegate *)indirect;
-@end
-
-@implementation CydiaObject
-
-- (void) dealloc {
-    [indirect_ release];
-    [super dealloc];
-}
-
-- (id) initWithDelegate:(IndirectDelegate *)indirect {
-    if ((self = [super init]) != nil) {
-        indirect_ = [indirect retain];
-    } return self;
-}
-
-- (void) setDelegate:(id)delegate {
-    delegate_ = delegate;
-}
-
-+ (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"device", @"firewire", @"imei", @"mac", @"serial", nil];
-}
-
-- (NSArray *) attributeKeys {
-    return [[self class] _attributeKeys];
-}
-
-+ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
-    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
-}
-
-- (NSString *) device {
-    return [[UIDevice currentDevice] uniqueIdentifier];
-}
-
-#if 0 // XXX: implement!
-- (NSString *) mac {
-    if (![indirect_ promptForSensitive:@"Mac Address"])
-        return nil;
-}
-
-- (NSString *) serial {
-    if (![indirect_ promptForSensitive:@"Serial #"])
-        return nil;
-}
-
-- (NSString *) firewire {
-    if (![indirect_ promptForSensitive:@"Firewire GUID"])
-        return nil;
-}
-
-- (NSString *) imei {
-    if (![indirect_ promptForSensitive:@"IMEI"])
-        return nil;
-}
-#endif
-
-+ (NSString *) webScriptNameForSelector:(SEL)selector {
-    if (selector == @selector(close))
-        return @"close";
-    else if (selector == @selector(getInstalledPackages))
-        return @"getInstalledPackages";
-    else if (selector == @selector(getPackageById:))
-        return @"getPackageById";
-    else if (selector == @selector(installPackages:))
-        return @"installPackages";
-    else if (selector == @selector(setAutoPopup:))
-        return @"setAutoPopup";
-    else if (selector == @selector(setButtonImage:withStyle:toFunction:))
-        return @"setButtonImage";
-    else if (selector == @selector(setButtonTitle:withStyle:toFunction:))
-        return @"setButtonTitle";
-    else if (selector == @selector(setFinishHook:))
-        return @"setFinishHook";
-    else if (selector == @selector(setPopupHook:))
-        return @"setPopupHook";
-    else if (selector == @selector(setSpecial:))
-        return @"setSpecial";
-    else if (selector == @selector(setToken:))
-        return @"setToken";
-    else if (selector == @selector(setViewportWidth:))
-        return @"setViewportWidth";
-    else if (selector == @selector(supports:))
-        return @"supports";
-    else if (selector == @selector(stringWithFormat:arguments:))
-        return @"format";
-    else if (selector == @selector(localizedStringForKey:value:table:))
-        return @"localize";
-    else if (selector == @selector(du:))
-        return @"du";
-    else if (selector == @selector(statfs:))
-        return @"statfs";
-    else
-        return nil;
-}
-
-+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
-    return [self webScriptNameForSelector:selector] == nil;
-}
-
-- (BOOL) supports:(NSString *)feature {
-    return [feature isEqualToString:@"window.open"];
-}
-
-- (NSArray *) getInstalledPackages {
-    NSArray *packages([[Database sharedInstance] packages]);
-    NSMutableArray *installed([NSMutableArray arrayWithCapacity:[packages count]]);
-    for (Package *package in packages)
-        if ([package installed] != nil)
-            [installed addObject:package];
-    return installed;
-}
-
-- (Package *) getPackageById:(NSString *)id {
-    Package *package([[Database sharedInstance] packageWithName:id]);
-    [package parse];
-    return package;
-}
-
-- (NSArray *) statfs:(NSString *)path {
-    struct statfs stat;
-
-    if (path == nil || statfs([path UTF8String], &stat) == -1)
-        return nil;
-
-    return [NSArray arrayWithObjects:
-        [NSNumber numberWithUnsignedLong:stat.f_bsize],
-        [NSNumber numberWithUnsignedLong:stat.f_blocks],
-        [NSNumber numberWithUnsignedLong:stat.f_bfree],
-    nil];
-}
-
-- (NSNumber *) du:(NSString *)path {
-    NSNumber *value(nil);
-
-    int fds[2];
-    _assert(pipe(fds) != -1);
-
-    pid_t pid(ExecFork());
-    if (pid == 0) {
-        _assert(dup2(fds[1], 1) != -1);
-        _assert(close(fds[0]) != -1);
-        _assert(close(fds[1]) != -1);
-        /* XXX: this should probably not use du */
-        execl("/usr/libexec/cydia/du", "du", "-s", [path UTF8String], NULL);
-        exit(1);
-        _assert(false);
-    }
-
-    _assert(close(fds[1]) != -1);
-
-    if (FILE *du = fdopen(fds[0], "r")) {
-        char line[1024];
-        while (fgets(line, sizeof(line), du) != NULL) {
-            size_t length(strlen(line));
-            while (length != 0 && line[length - 1] == '\n')
-                line[--length] = '\0';
-            if (char *tab = strchr(line, '\t')) {
-                *tab = '\0';
-                value = [NSNumber numberWithUnsignedLong:strtoul(line, NULL, 0)];
-            }
-        }
-
-        fclose(du);
-    } else _assert(close(fds[0]));
-
-    int status;
-  wait:
-    if (waitpid(pid, &status, 0) == -1)
-        if (errno == EINTR)
-            goto wait;
-        else _assert(false);
-
-    return value;
-}
-
-- (void) close {
-    [indirect_ close];
-}
-
-- (void) installPackages:(NSArray *)packages {
-    [delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO];
-}
-
-- (void) setAutoPopup:(BOOL)popup {
-    [indirect_ setAutoPopup:popup];
-}
-
-- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
-    [indirect_ setButtonImage:button withStyle:style toFunction:function];
-}
-
-- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
-    [indirect_ setButtonTitle:button withStyle:style toFunction:function];
-}
-
-- (void) setSpecial:(id)function {
-    [indirect_ setSpecial:function];
-}
-
-- (void) setToken:(NSString *)token {
-    if (Token_ != nil)
-        [Token_ release];
-    Token_ = [token retain];
-
-    [Metadata_ setObject:Token_ forKey:@"Token"];
-    Changed_ = true;
-}
-
-- (void) setFinishHook:(id)function {
-    [indirect_ setFinishHook:function];
-}
-
-- (void) setPopupHook:(id)function {
-    [indirect_ setPopupHook:function];
-}
-
-- (void) setViewportWidth:(float)width {
-    [indirect_ setViewportWidth:width];
-}
-
-- (NSString *) stringWithFormat:(NSString *)format arguments:(WebScriptObject *)arguments {
-    //NSLog(@"SWF:\"%@\" A:%@", format, [arguments description]);
-    unsigned count([arguments count]);
-    id values[count];
-    for (unsigned i(0); i != count; ++i)
-        values[i] = [arguments objectAtIndex:i];
-    return [[[NSString alloc] initWithFormat:format arguments:*(reinterpret_cast<va_list *>(&values))] autorelease];
-}
-
-- (NSString *) localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)table {
-    if (reinterpret_cast<id>(value) == [WebUndefined undefined])
-        value = nil;
-    if (reinterpret_cast<id>(table) == [WebUndefined undefined])
-        table = nil;
-    return [[NSBundle mainBundle] localizedStringForKey:key value:value table:table];
-}
-
-@end
-/* }}} */
-
-/* Cydia Browser Controller {{{ */
-@interface CYBrowserController : BrowserController {
-    CydiaObject *cydia_;
-}
-
-@end
-
-@implementation CYBrowserController
-
-- (void) dealloc {
-    [cydia_ release];
-    [super dealloc];
-}
-
-- (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host {
-}
-
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
-
-    WebDataSource *source([frame dataSource]);
-    NSURLResponse *response([source response]);
-    NSURL *url([response URL]);
-    NSString *scheme([url scheme]);
-
-    NSHTTPURLResponse *http;
-    if (scheme != nil && ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]))
-        http = (NSHTTPURLResponse *) response;
-    else
-        http = nil;
-
-    NSDictionary *headers([http allHeaderFields]);
-    NSString *host([url host]);
-    [self setHeaders:headers forHost:host];
-
-    if (
-        [host isEqualToString:@"cydia.saurik.com"] ||
-        [host hasSuffix:@".cydia.saurik.com"] ||
-        [scheme isEqualToString:@"file"]
-    )
-        [window setValue:cydia_ forKey:@"cydia"];
-}
-
-- (void) _setMoreHeaders:(NSMutableURLRequest *)request {
-    if (System_ != NULL)
-        [request setValue:System_ forHTTPHeaderField:@"X-System"];
-    if (Machine_ != NULL)
-        [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
-    if (Token_ != nil)
-        [request setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"];
-    if (Role_ != nil)
-        [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
-}
-
-- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source {
-    NSMutableURLRequest *copy = [request mutableCopy];
-    [self _setMoreHeaders:copy];
-    return copy;
-}
-
-- (void) setDelegate:(id)delegate {
-    [super setDelegate:delegate];
-    [cydia_ setDelegate:delegate];
-}
-
-- (id) init {
-    if ((self = [super initWithWidth:0 ofClass:[CYBrowserController class]]) != nil) {
-        cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_];
-
-        WebView *webview([document_ webView]);
-
-        Package *package([[Database sharedInstance] packageWithName:@"cydia"]);
-
-        NSString *application = package == nil ? @"Cydia" : [NSString
-            stringWithFormat:@"Cydia/%@",
-            [package installed]
-        ];
-
-        if (Safari_ != nil)
-            application = [NSString stringWithFormat:@"Safari/%@ %@", Safari_, application];
-        if (Build_ != nil)
-            application = [NSString stringWithFormat:@"Mobile/%@ %@", Build_, application];
-        if (Product_ != nil)
-            application = [NSString stringWithFormat:@"Version/%@ %@", Product_, application];
-
-        [webview setApplicationNameForUserAgent:application];
-    } return self;
-}
-
-@end
-/* }}} */
-
-/* Confirmation {{{ */
-@protocol ConfirmationControllerDelegate
-- (void) cancelAndClear:(bool)clear;
-- (void) confirmWithNavigationController:(UINavigationController *)navigation;
-- (void) queue;
-@end
-
-@interface ConfirmationController : CYBrowserController {
-    _transient Database *database_;
-    UIAlertView *essential_;
-    NSArray *changes_;
-    NSArray *issues_;
-    NSArray *sizes_;
-    BOOL substrate_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-
-@end
-
-@implementation ConfirmationController
-
-- (void) dealloc {
-    [changes_ release];
-    if (issues_ != nil)
-        [issues_ release];
-    [sizes_ release];
-    if (essential_ != nil)
-        [essential_ release];
-    [super dealloc];
-}
-
-- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
-    NSString *context([alert context]);
-
-    if ([context isEqualToString:@"remove"]) {
-        if (button == [alert cancelButtonIndex]) {
-            [self dismissModalViewControllerAnimated:YES];
-        } else if (button == [alert firstOtherButtonIndex]) {
-            if (substrate_)
-                Finish_ = 2;
-            [delegate_ confirmWithNavigationController:[self navigationController]];
-        }
-
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    } else if ([context isEqualToString:@"unable"]) {
-        [self dismissModalViewControllerAnimated:YES];
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    } else {
-        [super alertView:alert clickedButtonAtIndex:button];
-    }
-}
-
-- (id) invokeDefaultMethodWithArguments:(NSArray *)args {
-    [self dismissModalViewControllerAnimated:YES];
-    [delegate_ cancelAndClear:NO];
-
-    return nil;
-}
-
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
-    [window setValue:changes_ forKey:@"changes"];
-    [window setValue:issues_ forKey:@"issues"];
-    [window setValue:sizes_ forKey:@"sizes"];
-    [window setValue:self forKey:@"queue"];
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-
-        [[self navigationItem] setTitle:UCLocalize("CONFIRM")];
-
-        NSMutableArray *installing = [NSMutableArray arrayWithCapacity:16];
-        NSMutableArray *reinstalling = [NSMutableArray arrayWithCapacity:16];
-        NSMutableArray *upgrading = [NSMutableArray arrayWithCapacity:16];
-        NSMutableArray *downgrading = [NSMutableArray arrayWithCapacity:16];
-        NSMutableArray *removing = [NSMutableArray arrayWithCapacity:16];
-
-        bool remove(false);
-
-        pkgDepCache::Policy *policy([database_ policy]);
-
-        pkgCacheFile &cache([database_ cache]);
-        NSArray *packages = [database_ packages];
-        for (Package *package in packages) {
-            pkgCache::PkgIterator iterator = [package iterator];
-            pkgDepCache::StateCache &state(cache[iterator]);
-
-            NSString *name([package name]);
-
-            if (state.NewInstall())
-                [installing addObject:name];
-            else if (!state.Delete() && (state.iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
-                [reinstalling addObject:name];
-            else if (state.Upgrade())
-                [upgrading addObject:name];
-            else if (state.Downgrade())
-                [downgrading addObject:name];
-            else if (state.Delete()) {
-                if ([package essential])
-                    remove = true;
-                [removing addObject:name];
-            } else continue;
-
-            substrate_ |= DepSubstrate(policy->GetCandidateVer(iterator));
-            substrate_ |= DepSubstrate(iterator.CurrentVer());
-        }
-
-        if (!remove)
-            essential_ = nil;
-        else if (Advanced_) {
-            NSString *parenthetical(UCLocalize("PARENTHETICAL"));
-
-            essential_ = [[UIAlertView alloc]
-                initWithTitle:UCLocalize("REMOVING_ESSENTIALS")
-                message:UCLocalize("REMOVING_ESSENTIALS_EX")
-                delegate:self
-                cancelButtonTitle:[NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")]
-                otherButtonTitles:[NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")], nil
-            ];
-
-            [essential_ setContext:@"remove"];
-        } else {
-            essential_ = [[UIAlertView alloc]
-                initWithTitle:UCLocalize("UNABLE_TO_COMPLY")
-                message:UCLocalize("UNABLE_TO_COMPLY_EX")
-                delegate:self
-                cancelButtonTitle:UCLocalize("OKAY")
-                otherButtonTitles:nil
-            ];
-
-            [essential_ setContext:@"unable"];
-        }
-
-        changes_ = [[NSArray alloc] initWithObjects:
-            installing,
-            reinstalling,
-            upgrading,
-            downgrading,
-            removing,
-        nil];
-
-        issues_ = [database_ issues];
-        if (issues_ != nil)
-            issues_ = [issues_ retain];
-
-        sizes_ = [[NSArray alloc] initWithObjects:
-            SizeString([database_ fetcher].FetchNeeded()),
-            SizeString([database_ fetcher].PartialPresent()),
-        nil];
-
-        [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"confirm" ofType:@"html"]]];
-
-        UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("CANCEL")
-            // OLD: [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")]
-            style:UIBarButtonItemStylePlain
-            target:self
-            action:@selector(cancelButtonClicked)
-        ];
-        [[self navigationItem] setLeftBarButtonItem:leftItem];
-        [leftItem release];
-    } return self;
-}
-
-- (void) applyRightButton {
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:UCLocalize("CONFIRM")
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(confirmButtonClicked)
-    ];
-#if !AlwaysReload && !IgnoreInstall
-    if (issues_ == nil && ![self isLoading]) [[self navigationItem] setRightBarButtonItem:rightItem];
-    else [super applyRightButton];
-#else
-    [[self navigationItem] setRightBarButtonItem:nil];
-#endif
-    [rightItem release];
-}
-
-- (void) cancelButtonClicked {
-    [self dismissModalViewControllerAnimated:YES];
-    [delegate_ cancelAndClear:YES];
-}
-
-#if !AlwaysReload
-- (void) confirmButtonClicked {
-#if IgnoreInstall
-    return;
-#endif
-    if (essential_ != nil)
-        [essential_ show];
-    else {
-        if (substrate_)
-            Finish_ = 2;
-        [delegate_ confirmWithNavigationController:[self navigationController]];
-    }
-}
-#endif
-
-@end
-/* }}} */
-
-/* Progress Data {{{ */
-@interface ProgressData : NSObject {
-    SEL selector_;
-    id target_;
-    id object_;
-}
-
-- (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object;
-
-- (SEL) selector;
-- (id) target;
-- (id) object;
-@end
-
-@implementation ProgressData
-
-- (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object {
-    if ((self = [super init]) != nil) {
-        selector_ = selector;
-        target_ = target;
-        object_ = object;
-    } return self;
-}
-
-- (SEL) selector {
-    return selector_;
-}
-
-- (id) target {
-    return target_;
-}
-
-- (id) object {
-    return object_;
-}
-
-@end
-/* }}} */
-/* Progress Controller {{{ */
-@interface ProgressController : CYViewController <
-    ConfigurationDelegate,
-    ProgressDelegate
-> {
-    _transient Database *database_;
-    UIProgressBar *progress_;
-    UITextView *output_;
-    UITextLabel *status_;
-    UIPushButton *close_;
-    BOOL running_;
-    SHA1SumValue springlist_;
-    SHA1SumValue notifyconf_;
-    NSString *title_;
-}
-
-- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
-
-- (void) _retachThread;
-- (void) _detachNewThreadData:(ProgressData *)data;
-- (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title;
-
-- (BOOL) isRunning;
-
-@end
-
-@protocol ProgressControllerDelegate
-- (void) progressControllerIsComplete:(ProgressController *)sender;
-@end
-
-@implementation ProgressController
-
-- (void) dealloc {
-    [database_ setDelegate:nil];
-    [progress_ release];
-    [output_ release];
-    [status_ release];
-    [close_ release];
-    if (title_ != nil)
-        [title_ release];
-    [super dealloc];
-}
-
-- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-        [database_ setDelegate:self];
-        delegate_ = delegate;
-
-        [[self view] setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]];
-
-        progress_ = [[UIProgressBar alloc] init];
-        [progress_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
-        [progress_ setStyle:0];
-
-        status_ = [[UITextLabel alloc] init];
-        [status_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
-        [status_ setColor:[UIColor whiteColor]];
-        [status_ setBackgroundColor:[UIColor clearColor]];
-        [status_ setCentersHorizontally:YES];
-        //[status_ setFont:font];
-
-        output_ = [[UITextView alloc] init];
-
-        [output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        //[output_ setTextFont:@"Courier New"];
-        [output_ setFont:[[output_ font] fontWithSize:12]];
-        [output_ setTextColor:[UIColor whiteColor]];
-        [output_ setBackgroundColor:[UIColor clearColor]];
-        [output_ setMarginTop:0];
-        [output_ setAllowsRubberBanding:YES];
-        [output_ setEditable:NO];
-        [[self view] addSubview:output_];
-
-        close_ = [[UIPushButton alloc] init];
-        [close_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
-        [close_ setAutosizesToFit:NO];
-        [close_ setDrawsShadow:YES];
-        [close_ setStretchBackground:YES];
-        [close_ setEnabled:YES];
-        [close_ setTitleFont:[UIFont boldSystemFontOfSize:22]];
-        [close_ addTarget:self action:@selector(closeButtonPushed) forEvents:UIControlEventTouchUpInside];
-        [close_ setBackground:[UIImage applicationImageNamed:@"green-up.png"] forState:0];
-        [close_ setBackground:[UIImage applicationImageNamed:@"green-dn.png"] forState:1];
-    } return self;
-}
-
-- (void) positionViews {
-    CGRect bounds = [[self view] bounds];
-    CGSize prgsize = [UIProgressBar defaultSize];
-
-    CGRect prgrect = {{
-        (bounds.size.width - prgsize.width) / 2,
-        bounds.size.height - prgsize.height - 64
-    }, prgsize};
-
-    float closewidth = bounds.size.width - 20;
-    if (closewidth > 300) closewidth = 300;
-
-    [progress_ setFrame:prgrect];
-    [status_ setFrame:CGRectMake(
-        10,
-        bounds.size.height - prgsize.height - 94,
-        bounds.size.width - 20,
-        24
-    )];
-    [output_ setFrame:CGRectMake(
-        10,
-        20,
-        bounds.size.width - 20,
-        bounds.size.height - 106
-    )];
-    [close_ setFrame:CGRectMake(
-        (bounds.size.width - closewidth) / 2,
-        bounds.size.height - prgsize.height - 94,
-        closewidth,
-        32 + prgsize.height
-    )];
-}
-
-- (void) viewWillAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    [[self navigationItem] setHidesBackButton:YES];
-    [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
-
-    [self positionViews];
-}
-
-- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
-    [self positionViews];
-}
-
-- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
-    NSString *context([alert context]);
-
-    if ([context isEqualToString:@"conffile"]) {
-        FILE *input = [database_ input];
-        if (button == [alert cancelButtonIndex]) fprintf(input, "N\n");
-        else if (button == [alert firstOtherButtonIndex]) fprintf(input, "Y\n");
-        fflush(input);
-    }
-}
-
-- (void) closeButtonPushed {
-    running_ = NO;
-
-    UpdateExternalStatus(0);
-
-    switch (Finish_) {
-        case 0:
-            [self dismissModalViewControllerAnimated:YES];
-        break;
-
-        case 1:
-            [delegate_ terminateWithSuccess];
-            /*if ([delegate_ respondsToSelector:@selector(suspendWithAnimation:)])
-                [delegate_ suspendWithAnimation:YES];
-            else
-                [delegate_ suspend];*/
-        break;
-
-        case 2:
-            system("launchctl stop com.apple.SpringBoard");
-        break;
-
-        case 3:
-            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
-        break;
-
-        case 4:
-            system("reboot");
-        break;
-    }
-}
-
-- (void) _retachThread {
-    [[self navigationItem] setTitle:UCLocalize("COMPLETE")];
-
-    [[self view] addSubview:close_];
-    [progress_ removeFromSuperview];
-    [status_ removeFromSuperview];
-
-    [database_ popErrorWithTitle:title_];
-    [delegate_ progressControllerIsComplete:self];
-
-    if (Finish_ < 4) {
-        FileFd file;
-        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
-            _error->Discard();
-        else {
-            MMap mmap(file, MMap::ReadOnly);
-            SHA1Summation sha1;
-            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-            if (!(notifyconf_ == sha1.Result()))
-                Finish_ = 4;
-        }
-    }
-
-    if (Finish_ < 3) {
-        FileFd file;
-        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
-            _error->Discard();
-        else {
-            MMap mmap(file, MMap::ReadOnly);
-            SHA1Summation sha1;
-            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-            if (!(springlist_ == sha1.Result()))
-                Finish_ = 3;
-        }
-    }
-
-    switch (Finish_) {
-        case 0: [close_ setTitle:UCLocalize("RETURN_TO_CYDIA")]; break; /* XXX: Maybe UCLocalize("DONE")? */
-        case 1: [close_ setTitle:UCLocalize("CLOSE_CYDIA")]; break;
-        case 2: [close_ setTitle:UCLocalize("RESTART_SPRINGBOARD")]; break;
-        case 3: [close_ setTitle:UCLocalize("RELOAD_SPRINGBOARD")]; break;
-        case 4: [close_ setTitle:UCLocalize("REBOOT_DEVICE")]; break;
-    }
-
-    system("su -c /usr/bin/uicache mobile");
-
-    UpdateExternalStatus(Finish_ == 0 ? 2 : 0);
-
-    [delegate_ setStatusBarShowsProgress:NO];
-}
-
-- (void) _detachNewThreadData:(ProgressData *)data { _pooled
-    [[data target] performSelector:[data selector] withObject:[data object]];
-    [data release];
-
-    [self performSelectorOnMainThread:@selector(_retachThread) withObject:nil waitUntilDone:YES];
-}
-
-- (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title {
-    UpdateExternalStatus(1);
-
-    if (title_ != nil)
-        [title_ release];
-    if (title == nil)
-        title_ = nil;
-    else
-        title_ = [title retain];
-
-    [[self navigationItem] setTitle:title_];
-
-    [status_ setText:nil];
-    [output_ setText:@""];
-    [progress_ setProgress:0];
-
-    [close_ removeFromSuperview];
-    [[self view] addSubview:progress_];
-    [[self view] addSubview:status_];
-
-    [delegate_ setStatusBarShowsProgress:YES];
-    running_ = YES;
-
-    {
-        FileFd file;
-        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
-            _error->Discard();
-        else {
-            MMap mmap(file, MMap::ReadOnly);
-            SHA1Summation sha1;
-            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-            notifyconf_ = sha1.Result();
-        }
-    }
-
-    {
-        FileFd file;
-        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
-            _error->Discard();
-        else {
-            MMap mmap(file, MMap::ReadOnly);
-            SHA1Summation sha1;
-            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-            springlist_ = sha1.Result();
-        }
-    }
-
-    [NSThread
-        detachNewThreadSelector:@selector(_detachNewThreadData:)
-        toTarget:self
-        withObject:[[ProgressData alloc]
-            initWithSelector:selector
-            target:target
-            object:object
-        ]
-    ];
-}
-
-- (void) repairWithSelector:(SEL)selector {
-    [self
-        detachNewThreadSelector:selector
-        toTarget:database_
-        withObject:nil
-        title:UCLocalize("REPAIRING")
-    ];
-}
-
-- (void) setConfigurationData:(NSString *)data {
-    [self
-        performSelectorOnMainThread:@selector(_setConfigurationData:)
-        withObject:data
-        waitUntilDone:YES
-    ];
-}
-
-- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
-    CYActionSheet *sheet([[[CYActionSheet alloc]
-        initWithTitle:title
-        buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil]
-        defaultButtonIndex:0
-    ] autorelease]);
-
-    [sheet setMessage:error];
-    [sheet yieldToPopupAlertAnimated:YES];
-    [sheet dismiss];
-}
-
-- (void) setProgressTitle:(NSString *)title {
-    [self
-        performSelectorOnMainThread:@selector(_setProgressTitle:)
-        withObject:title
-        waitUntilDone:YES
-    ];
-}
-
-- (void) setProgressPercent:(float)percent {
-    [self
-        performSelectorOnMainThread:@selector(_setProgressPercent:)
-        withObject:[NSNumber numberWithFloat:percent]
-        waitUntilDone:YES
-    ];
-}
-
-- (void) startProgress {
-}
-
-- (void) addProgressOutput:(NSString *)output {
-    [self
-        performSelectorOnMainThread:@selector(_addProgressOutput:)
-        withObject:output
-        waitUntilDone:YES
-    ];
-}
-
-- (bool) isCancelling:(size_t)received {
-    return false;
-}
-
-- (void) _setConfigurationData:(NSString *)data {
-    static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$");
-
-    if (!conffile_r(data)) {
-        lprintf("E:invalid conffile\n");
-        return;
-    }
-
-    NSString *ofile = conffile_r[1];
-    //NSString *nfile = conffile_r[2];
-
-    UIAlertView *alert = [[[UIAlertView alloc]
-        initWithTitle:UCLocalize("CONFIGURATION_UPGRADE")
-        message:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]
-        delegate:self
-        cancelButtonTitle:UCLocalize("KEEP_OLD_COPY")
-        otherButtonTitles:UCLocalize("ACCEPT_NEW_COPY"),
-        // XXX: UCLocalize("SEE_WHAT_CHANGED"),
-        nil
-    ] autorelease];
-
-    [alert setContext:@"conffile"];
-    [alert show];
-}
-
-- (void) _setProgressTitle:(NSString *)title {
-    NSMutableArray *words([[title componentsSeparatedByString:@" "] mutableCopy]);
-    for (size_t i(0), e([words count]); i != e; ++i) {
-        NSString *word([words objectAtIndex:i]);
-        if (Package *package = [database_ packageWithName:word])
-            [words replaceObjectAtIndex:i withObject:[package name]];
-    }
-
-    [status_ setText:[words componentsJoinedByString:@" "]];
-}
-
-- (void) _setProgressPercent:(NSNumber *)percent {
-    [progress_ setProgress:[percent floatValue]];
-}
-
-- (void) _addProgressOutput:(NSString *)output {
-    [output_ setText:[NSString stringWithFormat:@"%@\n%@", [output_ text], output]];
-    CGSize size = [output_ contentSize];
-    CGRect rect = {{0, size.height}, {size.width, 0}};
-    [output_ scrollRectToVisible:rect animated:YES];
-}
-
-- (BOOL) isRunning {
-    return running_;
-}
-
-@end
-/* }}} */
-
-/* Cell Content View {{{ */
-@protocol ContentDelegate
-- (void) drawContentRect:(CGRect)rect;
-@end
-
-@interface ContentView : UIView {
-    _transient id<ContentDelegate> delegate_;
-}
-
-@end
-
-@implementation ContentView
-- (id) initWithFrame:(CGRect)frame {
-    if ((self = [super initWithFrame:frame]) != nil) {
-        /* Fix landscape stretching. */
-        [self setNeedsDisplayOnBoundsChange:YES];
-    } return self;
-}
-
-- (void) setDelegate:(id<ContentDelegate>)delegate {
-    delegate_ = delegate;
-}
-
-- (void) drawRect:(CGRect)rect {
-    [super drawRect:rect];
-    [delegate_ drawContentRect:rect];
-}
-@end
-/* }}} */
-/* Package Cell {{{ */
-@interface PackageCell : UITableViewCell <
-    ContentDelegate
-> {
-    UIImage *icon_;
-    NSString *name_;
-    NSString *description_;
-    bool commercial_;
-    NSString *source_;
-    UIImage *badge_;
-    Package *package_;
-    UIColor *color_;
-    ContentView *content_;
-    BOOL faded_;
-    float fade_;
-    UIImage *placard_;
-}
-
-- (PackageCell *) init;
-- (void) setPackage:(Package *)package;
-
-+ (int) heightForPackage:(Package *)package;
-- (void) drawContentRect:(CGRect)rect;
-
-@end
-
-@implementation PackageCell
-
-- (void) clearPackage {
-    if (icon_ != nil) {
-        [icon_ release];
-        icon_ = nil;
-    }
-
-    if (name_ != nil) {
-        [name_ release];
-        name_ = nil;
-    }
-
-    if (description_ != nil) {
-        [description_ release];
-        description_ = nil;
-    }
-
-    if (source_ != nil) {
-        [source_ release];
-        source_ = nil;
-    }
-
-    if (badge_ != nil) {
-        [badge_ release];
-        badge_ = nil;
-    }
-
-    if (placard_ != nil) {
-        [placard_ release];
-        placard_ = nil;
-    }
-
-    [package_ release];
-    package_ = nil;
-}
-
-- (void) dealloc {
-    [self clearPackage];
-    [content_ release];
-    [color_ release];
-    [super dealloc];
-}
-
-- (float) fade {
-    return faded_ ? [self selectionPercent] : fade_;
-}
-
-- (PackageCell *) init {
-    CGRect frame(CGRectMake(0, 0, 320, 74));
-    if ((self = [super initWithFrame:frame reuseIdentifier:@"Package"]) != nil) {
-        UIView *content([self contentView]);
-        CGRect bounds([content bounds]);
-
-        content_ = [[ContentView alloc] initWithFrame:bounds];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content addSubview:content_];
-
-        [content_ setDelegate:self];
-        [content_ setOpaque:YES];
-        if ([self respondsToSelector:@selector(selectionPercent)])
-            faded_ = YES;
-    } return self;
-}
-
-- (void) _setBackgroundColor {
-    UIColor *color;
-    if (NSString *mode = [package_ mode]) {
-        bool remove([mode isEqualToString:@"REMOVE"] || [mode isEqualToString:@"PURGE"]);
-        color = remove ? RemovingColor_ : InstallingColor_;
-    } else
-        color = [UIColor whiteColor];
-
-    [content_ setBackgroundColor:color];
-    [self setNeedsDisplay];
-}
-
-- (void) setPackage:(Package *)package {
-    [self clearPackage];
-    [package parse];
-
-    Source *source = [package source];
-
-    icon_ = [[package icon] retain];
-    name_ = [[package name] retain];
-
-    if (IsWildcat_)
-        description_ = [package longDescription];
-    if (description_ == nil)
-        description_ = [package shortDescription];
-    if (description_ != nil)
-        description_ = [description_ retain];
-
-    commercial_ = [package isCommercial];
-
-    package_ = [package retain];
-
-    NSString *label = nil;
-    bool trusted = false;
-
-    if (source != nil) {
-        label = [source label];
-        trusted = [source trusted];
-    } else if ([[package id] isEqualToString:@"firmware"])
-        label = UCLocalize("APPLE");
-    else
-        label = [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("UNKNOWN"), UCLocalize("LOCAL")];
-
-    NSString *from(label);
-
-    NSString *section = [package simpleSection];
-    if (section != nil && ![section isEqualToString:label]) {
-        section = [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"];
-        from = [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), from, section];
-    }
-
-    from = [NSString stringWithFormat:UCLocalize("FROM"), from];
-    source_ = [from retain];
-
-    if (NSString *purpose = [package primaryPurpose])
-        if ((badge_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Purposes/%@.png", App_, purpose]]) != nil)
-            badge_ = [badge_ retain];
-
-    if ([package installed] != nil)
-        if ((placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/installed.png", App_]]) != nil)
-            placard_ = [placard_ retain];
-
-    [self _setBackgroundColor];
-    [content_ setNeedsDisplay];
-}
-
-- (void) drawContentRect:(CGRect)rect {
-    bool selected([self isSelected]);
-    float width([self bounds].size.width);
-
-#if 0
-    CGContextRef context(UIGraphicsGetCurrentContext());
-    [([[self selectedBackgroundView] superview] != nil ? [UIColor clearColor] : [self backgroundColor]) set];
-    CGContextFillRect(context, rect);
-#endif
-
-    if (icon_ != nil) {
-        CGRect rect;
-        rect.size = [icon_ size];
-
-        rect.size.width /= 2;
-        rect.size.height /= 2;
-
-        rect.origin.x = 25 - rect.size.width / 2;
-        rect.origin.y = 25 - rect.size.height / 2;
-
-        [icon_ drawInRect:rect];
-    }
-
-    if (badge_ != nil) {
-        CGSize size = [badge_ size];
-
-        [badge_ drawAtPoint:CGPointMake(
-            36 - size.width / 2,
-            36 - size.height / 2
-        )];
-    }
-
-    if (selected)
-        UISetColor(White_);
-
-    if (!selected)
-        UISetColor(commercial_ ? Purple_ : Black_);
-    [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation];
-    [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation];
-
-    if (!selected)
-        UISetColor(commercial_ ? Purplish_ : Gray_);
-    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation];
-
-    if (placard_ != nil)
-        [placard_ drawAtPoint:CGPointMake(width - 52, 9)];
-}
-
-- (void) setSelected:(BOOL)selected animated:(BOOL)fade {
-    //[self _setBackgroundColor];
-    [super setSelected:selected animated:fade];
-    [content_ setNeedsDisplay];
-}
-
-+ (int) heightForPackage:(Package *)package {
-    return 73;
-}
-
-@end
-/* }}} */
-/* Section Cell {{{ */
-@interface SectionCell : UITableViewCell <
-    ContentDelegate
-> {
-    NSString *basic_;
-    NSString *section_;
-    NSString *name_;
-    NSString *count_;
-    UIImage *icon_;
-    ContentView *content_;
-    id switch_;
-    BOOL editing_;
-}
-
-- (void) setSection:(Section *)section editing:(BOOL)editing;
-
-@end
-
-@implementation SectionCell
-
-- (void) clearSection {
-    if (basic_ != nil) {
-        [basic_ release];
-        basic_ = nil;
-    }
-
-    if (section_ != nil) {
-        [section_ release];
-        section_ = nil;
-    }
-
-    if (name_ != nil) {
-        [name_ release];
-        name_ = nil;
-    }
-
-    if (count_ != nil) {
-        [count_ release];
-        count_ = nil;
-    }
-}
-
-- (void) dealloc {
-    [self clearSection];
-    [icon_ release];
-    [switch_ release];
-    [content_ release];
-
-    [super dealloc];
-}
-
-- (id) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
-    if ((self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) != nil) {
-        icon_ = [[UIImage applicationImageNamed:@"folder.png"] retain];
-        switch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(218, 9, 60, 25)];
-        [switch_ addTarget:self action:@selector(onSwitch:) forEvents:UIControlEventValueChanged];
-
-        UIView *content([self contentView]);
-        CGRect bounds([content bounds]);
-
-        content_ = [[ContentView alloc] initWithFrame:bounds];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content addSubview:content_];
-        [content_ setBackgroundColor:[UIColor whiteColor]];
-
-        [content_ setDelegate:self];
-    } return self;
-}
-
-- (void) onSwitch:(id)sender {
-    NSMutableDictionary *metadata = [Sections_ objectForKey:basic_];
-    if (metadata == nil) {
-        metadata = [NSMutableDictionary dictionaryWithCapacity:2];
-        [Sections_ setObject:metadata forKey:basic_];
-    }
-
-    Changed_ = true;
-    [metadata setObject:[NSNumber numberWithBool:([switch_ isOn] == NO)] forKey:@"Hidden"];
-}
-
-- (void) setSection:(Section *)section editing:(BOOL)editing {
-    if (editing != editing_) {
-        if (editing_)
-            [switch_ removeFromSuperview];
-        else
-            [self addSubview:switch_];
-        editing_ = editing;
-    }
-
-    [self clearSection];
-
-    if (section == nil) {
-        name_ = [UCLocalize("ALL_PACKAGES") retain];
-        count_ = nil;
-    } else {
-        basic_ = [section name];
-        if (basic_ != nil)
-            basic_ = [basic_ retain];
-
-        section_ = [section localized];
-        if (section_ != nil)
-            section_ = [section_ retain];
-
-        name_  = [(section_ == nil || [section_ length] == 0 ? UCLocalize("NO_SECTION") : section_) retain];
-        count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
-
-        if (editing_)
-            [switch_ setOn:(isSectionVisible(basic_) ? 1 : 0) animated:NO];
-    }
-
-    [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator];
-    [content_ setNeedsDisplay];
-}
-
-- (void) setFrame:(CGRect)frame {
-    [super setFrame:frame];
-
-    CGRect rect([switch_ frame]);
-    [switch_ setFrame:CGRectMake(frame.size.width - 102, 9, rect.size.width, rect.size.height)];
-}
-
-- (void) drawContentRect:(CGRect)rect {
-    BOOL selected = [self isSelected];
-
-    [icon_ drawInRect:CGRectMake(8, 7, 32, 32)];
-
-    if (selected)
-        UISetColor(White_);
-
-    if (!selected)
-        UISetColor(Black_);
-
-    float width(rect.size.width);
-    if (editing_)
-        width -= 87;
-
-    [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(width - 70) withFont:Font22Bold_ lineBreakMode:UILineBreakModeTailTruncation];
-
-    CGSize size = [count_ sizeWithFont:Font14_];
-
-    UISetColor(White_);
-    if (count_ != nil)
-        [count_ drawAtPoint:CGPointMake(13 + (29 - size.width) / 2, 16) withFont:Font12Bold_];
-}
-
-@end
-/* }}} */
-
-/* File Table {{{ */
-@interface FileTable : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    Package *package_;
-    NSString *name_;
-    NSMutableArray *files_;
-    UITableView *list_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-- (void) setPackage:(Package *)package;
-
-@end
-
-@implementation FileTable
-
-- (void) dealloc {
-    if (package_ != nil)
-        [package_ release];
-    if (name_ != nil)
-        [name_ release];
-    [files_ release];
-    [list_ release];
-    [super dealloc];
-}
-
-- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    return files_ == nil ? 0 : [files_ count];
-}
-
-/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
-    return 24.0f;
-}*/
-
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    static NSString *reuseIdentifier = @"Cell";
-
-    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
-    if (cell == nil) {
-        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
-        [cell setFont:[UIFont systemFontOfSize:16]];
-    }
-    [cell setText:[files_ objectAtIndex:indexPath.row]];
-    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
-
-    return cell;
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-
-        [[self navigationItem] setTitle:UCLocalize("INSTALLED_FILES")];
-
-        files_ = [[NSMutableArray arrayWithCapacity:32] retain];
-
-        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [list_ setRowHeight:24.0f];
-        [[self view] addSubview:list_];
-
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-    } return self;
-}
-
-- (void) setPackage:(Package *)package {
-    if (package_ != nil) {
-        [package_ autorelease];
-        package_ = nil;
-    }
-
-    if (name_ != nil) {
-        [name_ release];
-        name_ = nil;
-    }
-
-    [files_ removeAllObjects];
-
-    if (package != nil) {
-        package_ = [package retain];
-        name_ = [[package id] retain];
-
-        if (NSArray *files = [package files])
-            [files_ addObjectsFromArray:files];
-
-        if ([files_ count] != 0) {
-            if ([[files_ objectAtIndex:0] isEqualToString:@"/."])
-                [files_ removeObjectAtIndex:0];
-            [files_ sortUsingSelector:@selector(compareByPath:)];
-
-            NSMutableArray *stack = [NSMutableArray arrayWithCapacity:8];
-            [stack addObject:@"/"];
-
-            for (int i(0), e([files_ count]); i != e; ++i) {
-                NSString *file = [files_ objectAtIndex:i];
-                while (![file hasPrefix:[stack lastObject]])
-                    [stack removeLastObject];
-                NSString *directory = [stack lastObject];
-                [stack addObject:[file stringByAppendingString:@"/"]];
-                [files_ replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%*s%@",
-                    ([stack count] - 2) * 3, "",
-                    [file substringFromIndex:[directory length]]
-                ]];
-            }
-        }
-    }
-
-    [list_ reloadData];
-}
-
-- (void) reloadData {
-    [self setPackage:[database_ packageWithName:name_]];
-}
-
-@end
-/* }}} */
-/* Package Controller {{{ */
-@interface PackageController : CYBrowserController <
-    UIActionSheetDelegate
-> {
-    _transient Database *database_;
-    Package *package_;
-    NSString *name_;
-    bool commercial_;
-    NSMutableArray *buttons_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-- (void) setPackage:(Package *)package;
-
-@end
-
-@implementation PackageController
-
-- (void) dealloc {
-    if (package_ != nil)
-        [package_ release];
-    if (name_ != nil)
-        [name_ release];
-    [buttons_ release];
-    [super dealloc];
-}
-
-- (void) release {
-    if ([self retainCount] == 1)
-        [delegate_ setPackageController:self];
-    [super release];
-}
-
-/* XXX: this is not safe at all... localization of /fail/ */
-- (void) _clickButtonWithName:(NSString *)name {
-    if ([name isEqualToString:UCLocalize("CLEAR")])
-        [delegate_ clearPackage:package_];
-    else if ([name isEqualToString:UCLocalize("INSTALL")])
-        [delegate_ installPackage:package_];
-    else if ([name isEqualToString:UCLocalize("REINSTALL")])
-        [delegate_ installPackage:package_];
-    else if ([name isEqualToString:UCLocalize("REMOVE")])
-        [delegate_ removePackage:package_];
-    else if ([name isEqualToString:UCLocalize("UPGRADE")])
-        [delegate_ installPackage:package_];
-    else _assert(false);
-}
-
-- (void) actionSheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)button {
-    NSString *context([sheet context]);
-
-    if ([context isEqualToString:@"modify"]) {
-        if (button != [sheet cancelButtonIndex]) {
-            NSString *buttonName = [buttons_ objectAtIndex:button];
-            [self _clickButtonWithName:buttonName];
-        }
-
-        [sheet dismissWithClickedButtonIndex:-1 animated:YES];
-    }
-}
-
-- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
-    return [super webView:sender didFinishLoadForFrame:frame];
-}
-
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    [super webView:sender didClearWindowObject:window forFrame:frame];
-    [window setValue:package_ forKey:@"package"];
-}
-
-- (bool) _allowJavaScriptPanel {
-    return commercial_;
-}
-
-#if !AlwaysReload
-- (void) _customButtonClicked {
-    int count([buttons_ count]);
-    if (count == 0)
-        return;
-
-    if (count == 1)
-        [self _clickButtonWithName:[buttons_ objectAtIndex:0]];
-    else {
-        NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:count];
-        [buttons addObjectsFromArray:buttons_];
-
-        UIActionSheet *sheet = [[[UIActionSheet alloc]
-            initWithTitle:nil
-            delegate:self
-            cancelButtonTitle:nil
-            destructiveButtonTitle:nil
-            otherButtonTitles:nil
-        ] autorelease];
-
-        for (NSString *button in buttons) [sheet addButtonWithTitle:button];
-        if (!IsWildcat_) {
-           [sheet addButtonWithTitle:UCLocalize("CANCEL")];
-           [sheet setCancelButtonIndex:[sheet numberOfButtons] - 1];
-        }
-        [sheet setContext:@"modify"];
-
-        [delegate_ showActionSheet:sheet fromItem:[[self navigationItem] rightBarButtonItem]];
-    }
-}
-
-// We don't want to allow non-commercial packages to do custom things to the install button,
-// so it must call customButtonClicked with a custom commercial_ == 1 fallthrough.
-- (void) customButtonClicked {
-    if (commercial_)
-        [super customButtonClicked];
-    else
-        [self _customButtonClicked];
-}
-
-- (void) reloadButtonClicked {
-    // Don't reload a package view by clicking the button.
-}
-
-- (void) applyLoadingTitle {
-    // Don't show "Loading" as the title. Ever.
-}
-
-- (UIBarButtonItem *) rightButton {
-    int count = [buttons_ count];
-    return [[[UIBarButtonItem alloc]
-        initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0]
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(customButtonClicked)
-    ] autorelease];
-}
-#endif
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-        buttons_ = [[NSMutableArray alloc] initWithCapacity:4];
-        [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]];
-    } return self;
-}
-
-- (void) setPackage:(Package *)package {
-    if (package_ != nil) {
-        [package_ autorelease];
-        package_ = nil;
-    }
-
-    if (name_ != nil) {
-        [name_ release];
-        name_ = nil;
-    }
-
-    [buttons_ removeAllObjects];
-
-    if (package != nil) {
-        [package parse];
-
-        package_ = [package retain];
-        name_ = [[package id] retain];
-        commercial_ = [package isCommercial];
-
-        if ([package_ mode] != nil)
-            [buttons_ addObject:UCLocalize("CLEAR")];
-        if ([package_ source] == nil);
-        else if ([package_ upgradableAndEssential:NO])
-            [buttons_ addObject:UCLocalize("UPGRADE")];
-        else if ([package_ uninstalled])
-            [buttons_ addObject:UCLocalize("INSTALL")];
-        else
-            [buttons_ addObject:UCLocalize("REINSTALL")];
-        if (![package_ uninstalled])
-            [buttons_ addObject:UCLocalize("REMOVE")];
-
-        if (special_ != NULL) {
-            CGRect frame([document_ frame]);
-            frame.size.height = 0;
-            [document_ setFrame:frame];
-
-            if ([scroller_ respondsToSelector:@selector(scrollPointVisibleAtTopLeft:)])
-                [scroller_ scrollPointVisibleAtTopLeft:CGPointZero];
-            else
-                [scroller_ scrollRectToVisible:CGRectZero animated:NO];
-
-            WebThreadLock();
-            [[[document_ webView] windowScriptObject] setValue:package_ forKey:@"package"];
-
-            [self setButtonTitle:nil withStyle:nil toFunction:nil];
-
-            [self setFinishHook:nil];
-            [self setPopupHook:nil];
-            WebThreadUnlock();
-
-            //[self yieldToSelector:@selector(callFunction:) withObject:special_];
-            [super callFunction:special_];
-        }
-    }
-}
-
-- (bool) isLoading {
-    return commercial_ ? [super isLoading] : false;
-}
-
-- (void) reloadData {
-    [self setPackage:[database_ packageWithName:name_]];
-}
-
-@end
-/* }}} */
-/* Package Table {{{ */
-@interface PackageTable : UIView <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    NSMutableArray *packages_;
-    NSMutableArray *sections_;
-    UITableView *list_;
-    NSMutableArray *index_;
-    NSMutableDictionary *indices_;
-    id target_;
-    SEL action_;
-    id delegate_;
-}
-
-- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action;
-
-- (void) setDelegate:(id)delegate;
-
-- (void) reloadData;
-- (void) resetCursor;
-
-- (UITableView *) list;
-
-- (void) setShouldHideHeaderInShortLists:(BOOL)hide;
-
-- (void) deselectWithAnimation:(BOOL)animated;
-
-@end
-
-@implementation PackageTable
-
-- (void) dealloc {
-    [packages_ release];
-    [sections_ release];
-    [list_ release];
-    [index_ release];
-    [indices_ release];
-
-    [super dealloc];
-}
-
-- (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
-    NSInteger count([sections_ count]);
-    return count == 0 ? 1 : count;
-}
-
-- (NSString *) tableView:(UITableView *)list titleForHeaderInSection:(NSInteger)section {
-    if ([sections_ count] == 0)
-        return nil;
-    return [[sections_ objectAtIndex:section] name];
-}
-
-- (NSInteger) tableView:(UITableView *)list numberOfRowsInSection:(NSInteger)section {
-    if ([sections_ count] == 0)
-        return 0;
-    return [[sections_ objectAtIndex:section] count];
-}
-
-- (Package *) packageAtIndexPath:(NSIndexPath *)path {
-    Section *section([sections_ objectAtIndex:[path section]]);
-    NSInteger row([path row]);
-    Package *package([packages_ objectAtIndex:([section row] + row)]);
-    return package;
-}
-
-- (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path {
-    PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]);
-    if (cell == nil)
-        cell = [[[PackageCell alloc] init] autorelease];
-    [cell setPackage:[self packageAtIndexPath:path]];
-    return cell;
-}
-
-- (void) deselectWithAnimation:(BOOL)animated {
-    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
-}
-
-/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path {
-    return [PackageCell heightForPackage:[self packageAtIndexPath:path]];
-}*/
-
-- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path {
-    Package *package([self packageAtIndexPath:path]);
-    package = [database_ packageWithName:[package id]];
-    [target_ performSelector:action_ withObject:package];
-    return path;
-}
-
-- (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView {
-    return [packages_ count] > 20 ? index_ : nil;
-}
-
-- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
-    return index;
-}
-
-- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action {
-    if ((self = [super initWithFrame:frame]) != nil) {
-        database_ = database;
-
-        target_ = target;
-        action_ = action;
-
-        index_ = [[NSMutableArray alloc] initWithCapacity:32];
-        indices_ = [[NSMutableDictionary alloc] initWithCapacity:32];
-
-        packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
-        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
-
-        list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [list_ setRowHeight:73.0f];
-        [self addSubview:list_];
-
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-    } return self;
-}
-
-- (void) setDelegate:(id)delegate {
-    delegate_ = delegate;
-}
-
-- (bool) hasPackage:(Package *)package {
-    return true;
-}
-
-- (void) reloadData {
-    NSArray *packages = [database_ packages];
-
-    [packages_ removeAllObjects];
-    [sections_ removeAllObjects];
-
-    _profile(PackageTable$reloadData$Filter)
-        for (Package *package in packages)
-            if ([self hasPackage:package])
-                [packages_ addObject:package];
-    _end
-
-    [index_ removeAllObjects];
-    [indices_ removeAllObjects];
-
-    Section *section = nil;
-
-    _profile(PackageTable$reloadData$Section)
-        for (size_t offset(0), end([packages_ count]); offset != end; ++offset) {
-            Package *package;
-            unichar index;
-
-            _profile(PackageTable$reloadData$Section$Package)
-                package = [packages_ objectAtIndex:offset];
-                index = [package index];
-            _end
-
-            if (section == nil || [section index] != index) {
-                _profile(PackageTable$reloadData$Section$Allocate)
-                    section = [[[Section alloc] initWithIndex:index row:offset] autorelease];
-                _end
-
-                [index_ addObject:[section name]];
-                //[indices_ setObject:[NSNumber numberForInt:[sections_ count]] forKey:index];
-
-                _profile(PackageTable$reloadData$Section$Add)
-                    [sections_ addObject:section];
-                _end
-            }
-
-            [section addToCount];
-        }
-    _end
-
-    _profile(PackageTable$reloadData$List)
-        [list_ reloadData];
-    _end
-}
-
-- (void) resetCursor {
-    [list_ scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:NO];
-}
-
-- (UITableView *) list {
-    return list_;
-}
-
-- (void) setShouldHideHeaderInShortLists:(BOOL)hide {
-    //XXX:[list_ setShouldHideHeaderInShortLists:hide];
-}
-
-@end
-/* }}} */
-/* Filtered Package Table {{{ */
-@interface FilteredPackageTable : PackageTable {
-    SEL filter_;
-    IMP imp_;
-    id object_;
-}
-
-- (void) setObject:(id)object;
-- (void) setObject:(id)object forFilter:(SEL)filter;
-
-- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object;
-
-@end
-
-@implementation FilteredPackageTable
-
-- (void) dealloc {
-    if (object_ != nil)
-        [object_ release];
-    [super dealloc];
-}
-
-- (void) setFilter:(SEL)filter {
-    filter_ = filter;
-
-    /* XXX: this is an unsafe optimization of doomy hell */
-    Method method(class_getInstanceMethod([Package class], filter));
-    _assert(method != NULL);
-    imp_ = method_getImplementation(method);
-    _assert(imp_ != NULL);
-}
-
-- (void) setObject:(id)object {
-    if (object_ != nil)
-        [object_ release];
-    if (object == nil)
-        object_ = nil;
-    else
-        object_ = [object retain];
-}
-
-- (void) setObject:(id)object forFilter:(SEL)filter {
-    [self setFilter:filter];
-    [self setObject:object];
-}
-
-- (bool) hasPackage:(Package *)package {
-    _profile(FilteredPackageTable$hasPackage)
-        return [package valid] && (*reinterpret_cast<bool (*)(id, SEL, id)>(imp_))(package, filter_, object_);
-    _end
-}
-
-- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object {
-    if ((self = [super initWithFrame:frame database:database target:target action:action]) != nil) {
-        [self setFilter:filter];
-        object_ = [object retain];
-        [self reloadData];
-    } return self;
-}
-
-@end
-/* }}} */
-
-/* Filtered Package Controller {{{ */
-@interface FilteredPackageController : CYViewController {
-    _transient Database *database_;
-    FilteredPackageTable *packages_;
-    NSString *title_;
-}
-
-- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
-
-@end
-
-@implementation FilteredPackageController
-
-- (void) dealloc {
-    [packages_ release];
-    [title_ release];
-
-    [super dealloc];
-}
-
-- (void) viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    [packages_ deselectWithAnimation:animated];
-}
-
-- (void) didSelectPackage:(Package *)package {
-    PackageController *view([delegate_ packageController]);
-    [view setPackage:package];
-    [view setDelegate:delegate_];
-    [[self navigationController] pushViewController:view animated:YES];
-}
-
-- (NSString *) title { return title_; }
-
-- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-        title_ = [title copy];
-        [[self navigationItem] setTitle:title_];
-
-        packages_ = [[FilteredPackageTable alloc]
-            initWithFrame:[[self view] bounds]
-            database:database
-            target:self
-            action:@selector(didSelectPackage:)
-            filter:filter
-            with:object
-        ];
-
-        [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [[self view] addSubview:packages_];
-    } return self;
-}
-
-- (void) reloadData {
-    [packages_ reloadData];
-}
-
-- (void) setDelegate:(id)delegate {
-    [super setDelegate:delegate];
-    [packages_ setDelegate:delegate];
-}
-
-@end
-
-/* }}} */
-
-/* Add Source Controller {{{ */
-@interface AddSourceController : CYViewController {
-    _transient Database *database_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-
-@end
-
-@implementation AddSourceController
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-    } return self;
-}
-
-@end
-/* }}} */
-/* Source Cell {{{ */
-@interface SourceCell : UITableViewCell <
-    ContentDelegate
-> {
-    UIImage *icon_;
-    NSString *origin_;
-    NSString *description_;
-    NSString *label_;
-    ContentView *content_;
-}
-
-- (void) setSource:(Source *)source;
-
-@end
-
-@implementation SourceCell
-
-- (void) clearSource {
-    [icon_ release];
-    [origin_ release];
-    [description_ release];
-    [label_ release];
-
-    icon_ = nil;
-    origin_ = nil;
-    description_ = nil;
-    label_ = nil;
-}
-
-- (void) setSource:(Source *)source {
-    [self clearSource];
-
-    if (icon_ == nil)
-        icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sources/%@.png", [source host]]];
-    if (icon_ == nil)
-        icon_ = [UIImage applicationImageNamed:@"unknown.png"];
-    icon_ = [icon_ retain];
-
-    origin_ = [[source name] retain];
-    label_ = [[source uri] retain];
-    description_ = [[source description] retain];
-
-    [content_ setNeedsDisplay];
-}
-
-- (void) dealloc {
-    [self clearSource];
-    [content_ release];
-    [super dealloc];
-}
-
-- (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
-    if ((self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) != nil) {
-        UIView *content([self contentView]);
-        CGRect bounds([content bounds]);
-
-        content_ = [[ContentView alloc] initWithFrame:bounds];
-        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [content_ setBackgroundColor:[UIColor whiteColor]];
-        [content addSubview:content_];
-
-        [content_ setDelegate:self];
-        [content_ setOpaque:YES];
-    } return self;
-}
-
-- (void) setSelected:(BOOL)selected animated:(BOOL)animated {
-    [super setSelected:selected animated:animated];
-    [content_ setNeedsDisplay];
-}
-
-- (void) drawContentRect:(CGRect)rect {
-    bool selected([self isSelected]);
-    float width(rect.size.width);
-
-    if (icon_ != nil)
-        [icon_ drawInRect:CGRectMake(10, 10, 30, 30)];
-
-    if (selected)
-        UISetColor(White_);
-
-    if (!selected)
-        UISetColor(Black_);
-    [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation];
-
-    if (!selected)
-        UISetColor(Blue_);
-    [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation];
-
-    if (!selected)
-        UISetColor(Gray_);
-    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 40) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation];
-}
-
-@end
-/* }}} */
-/* Source Table {{{ */
-@interface SourceTable : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    UITableView *list_;
-    NSMutableArray *sources_;
-    int offset_;
-
-    NSString *href_;
-    UIProgressHUD *hud_;
-    NSError *error_;
-
-    //NSURLConnection *installer_;
-    NSURLConnection *trivial_;
-    NSURLConnection *trivial_bz2_;
-    NSURLConnection *trivial_gz_;
-    //NSURLConnection *automatic_;
-
-    BOOL cydia_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-
-- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated;
-
-@end
-
-@implementation SourceTable
-
-- (void) _deallocConnection:(NSURLConnection *)connection {
-    if (connection != nil) {
-        [connection cancel];
-        //[connection setDelegate:nil];
-        [connection release];
-    }
-}
-
-- (void) dealloc {
-    if (href_ != nil)
-        [href_ release];
-    if (hud_ != nil)
-        [hud_ release];
-    if (error_ != nil)
-        [error_ release];
-
-    //[self _deallocConnection:installer_];
-    [self _deallocConnection:trivial_];
-    [self _deallocConnection:trivial_gz_];
-    [self _deallocConnection:trivial_bz2_];
-    //[self _deallocConnection:automatic_];
-
-    [sources_ release];
-    [list_ release];
-    [super dealloc];
-}
-
-- (void) viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
-}
-
-- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
-    return offset_ == 0 ? 1 : 2;
-}
-
-- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
-    switch (section + (offset_ == 0 ? 1 : 0)) {
-        case 0: return UCLocalize("ENTERED_BY_USER");
-        case 1: return UCLocalize("INSTALLED_BY_PACKAGE");
-
-        _nodefault
-    }
-}
-
-- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    int count = [sources_ count];
-    switch (section) {
-        case 0: return (offset_ == 0 ? count : offset_);
-        case 1: return count - offset_;
-
-        _nodefault
-    }
-}
-
-- (Source *) sourceAtIndexPath:(NSIndexPath *)indexPath {
-    unsigned idx = 0;
-    switch (indexPath.section) {
-        case 0: idx = indexPath.row; break;
-        case 1: idx = indexPath.row + offset_; break;
-
-        _nodefault
-    }
-    return [sources_ objectAtIndex:idx];
-}
-
-- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
-    Source *source = [self sourceAtIndexPath:indexPath];
-    return [source description] == nil ? 56 : 73;
-}
-
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    static NSString *cellIdentifier = @"SourceCell";
-
-    SourceCell *cell = (SourceCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
-    if(cell == nil) cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
-    [cell setSource:[self sourceAtIndexPath:indexPath]];
-
-    return cell;
-}
-
-- (UITableViewCellAccessoryType) tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
-    return UITableViewCellAccessoryDisclosureIndicator;
-}
-
-- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    Source *source = [self sourceAtIndexPath:indexPath];
-
-    FilteredPackageController *packages = [[[FilteredPackageController alloc]
-        initWithDatabase:database_
-        title:[source label]
-        filter:@selector(isVisibleInSource:)
-        with:source
-    ] autorelease];
-
-    [packages setDelegate:delegate_];
-
-    [[self navigationController] pushViewController:packages animated:YES];
-}
-
-- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
-    Source *source = [self sourceAtIndexPath:indexPath];
-    return [source record] != nil;
-}
-
-- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
-    Source *source = [self sourceAtIndexPath:indexPath];
-    [Sources_ removeObjectForKey:[source key]];
-    [delegate_ syncData];
-}
-
-- (void) complete {
-    [Sources_ setObject:[NSDictionary dictionaryWithObjectsAndKeys:
-        @"deb", @"Type",
-        href_, @"URI",
-        @"./", @"Distribution",
-    nil] forKey:[NSString stringWithFormat:@"deb:%@:./", href_]];
-
-    [delegate_ syncData];
-}
-
-- (NSString *) getWarning {
-    NSString *href(href_);
-    NSRange colon([href rangeOfString:@"://"]);
-    if (colon.location != NSNotFound)
-        href = [href substringFromIndex:(colon.location + 3)];
-    href = [href stringByAddingPercentEscapes];
-    href = [CydiaURL(@"api/repotag/") stringByAppendingString:href];
-    href = [href stringByCachingURLWithCurrentCDN];
-
-    NSURL *url([NSURL URLWithString:href]);
-
-    NSStringEncoding encoding;
-    NSError *error(nil);
-
-    if (NSString *warning = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:&error])
-        return [warning length] == 0 ? nil : warning;
-    return nil;
-}
-
-- (void) _endConnection:(NSURLConnection *)connection {
-    NSURLConnection **field = NULL;
-    if (connection == trivial_)
-        field = &trivial_;
-    else if (connection == trivial_bz2_)
-        field = &trivial_bz2_;
-    else if (connection == trivial_gz_)
-        field = &trivial_gz_;
-    _assert(field != NULL);
-    [connection release];
-    *field = nil;
-
-    if (
-        trivial_ == nil &&
-        trivial_bz2_ == nil &&
-        trivial_gz_ == nil
-    ) {
-        bool defer(false);
-
-        if (cydia_) {
-            if (NSString *warning = [self yieldToSelector:@selector(getWarning)]) {
-                defer = true;
-
-                UIAlertView *alert = [[[UIAlertView alloc]
-                    initWithTitle:UCLocalize("SOURCE_WARNING")
-                    message:warning
-                    delegate:self
-                    cancelButtonTitle:UCLocalize("CANCEL")
-                    otherButtonTitles:UCLocalize("ADD_ANYWAY"), nil
-                ] autorelease];
-
-                [alert setContext:@"warning"];
-                [alert setNumberOfRows:1];
-                [alert show];
-            } else
-                [self complete];
-        } else if (error_ != nil) {
-            UIAlertView *alert = [[[UIAlertView alloc]
-                initWithTitle:UCLocalize("VERIFICATION_ERROR")
-                message:[error_ localizedDescription]
-                delegate:self
-                cancelButtonTitle:UCLocalize("OK")
-                otherButtonTitles:nil
-            ] autorelease];
-
-            [alert setContext:@"urlerror"];
-            [alert show];
-        } else {
-            UIAlertView *alert = [[[UIAlertView alloc]
-                initWithTitle:UCLocalize("NOT_REPOSITORY")
-                message:UCLocalize("NOT_REPOSITORY_EX")
-                delegate:self
-                cancelButtonTitle:UCLocalize("OK")
-                otherButtonTitles:nil
-            ] autorelease];
-
-            [alert setContext:@"trivial"];
-            [alert show];
-        }
-
-        [delegate_ setStatusBarShowsProgress:NO];
-        [delegate_ removeProgressHUD:hud_];
-
-        [hud_ autorelease];
-        hud_ = nil;
-
-        if (!defer) {
-            [href_ release];
-            href_ = nil;
-        }
-
-        if (error_ != nil) {
-            [error_ release];
-            error_ = nil;
-        }
-    }
-}
-
-- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
-    switch ([response statusCode]) {
-        case 200:
-            cydia_ = YES;
-    }
-}
-
-- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
-    lprintf("connection:\"%s\" didFailWithError:\"%s\"", [href_ UTF8String], [[error localizedDescription] UTF8String]);
-    if (error_ != nil)
-        error_ = [error retain];
-    [self _endConnection:connection];
-}
-
-- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
-    [self _endConnection:connection];
-}
-
-- (NSString *) title { return UCLocalize("SOURCES"); }
-
-- (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method {
-    NSMutableURLRequest *request = [NSMutableURLRequest
-        requestWithURL:[NSURL URLWithString:href]
-        cachePolicy:NSURLRequestUseProtocolCachePolicy
-        timeoutInterval:120.0
-    ];
-
-    [request setHTTPMethod:method];
-
-    if (Machine_ != NULL)
-        [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
-    if (UniqueID_ != nil)
-        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
-    if (Role_ != nil)
-        [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
-
-    return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
-}
-
-- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
-    NSString *context([alert context]);
-
-    if ([context isEqualToString:@"source"]) {
-        switch (button) {
-            case 1: {
-                NSString *href = [[alert textField] text];
-
-                //installer_ = [[self _requestHRef:href method:@"GET"] retain];
-
-                if (![href hasSuffix:@"/"])
-                    href_ = [href stringByAppendingString:@"/"];
-                else
-                    href_ = href;
-                href_ = [href_ retain];
-
-                trivial_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages"] method:@"HEAD"] retain];
-                trivial_bz2_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.bz2"] method:@"HEAD"] retain];
-                trivial_gz_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.gz"] method:@"HEAD"] retain];
-                //trivial_bz2_ = [[self _requestHRef:[href stringByAppendingString:@"dists/Release"] method:@"HEAD"] retain];
-
-                cydia_ = false;
-
-                hud_ = [[delegate_ addProgressHUD] retain];
-                [hud_ setText:UCLocalize("VERIFYING_URL")];
-            } break;
-
-            case 0:
-            break;
-
-            _nodefault
-        }
-
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    } else if ([context isEqualToString:@"trivial"])
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    else if ([context isEqualToString:@"urlerror"])
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    else if ([context isEqualToString:@"warning"]) {
-        switch (button) {
-            case 1:
-                [self complete];
-            break;
-
-            case 0:
-            break;
-
-            _nodefault
-        }
-
-        [href_ release];
-        href_ = nil;
-
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    }
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        [[self navigationItem] setTitle:UCLocalize("SOURCES")];
-        [self updateButtonsForEditingStatus:NO animated:NO];
-
-        database_ = database;
-        sources_ = [[NSMutableArray arrayWithCapacity:16] retain];
-
-        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [[self view] addSubview:list_];
-
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-
-        [self reloadData];
-    } return self;
-}
-
-- (void) reloadData {
-    pkgSourceList list;
-    if (!list.ReadMainList())
-        return;
-
-    [sources_ removeAllObjects];
-    [sources_ addObjectsFromArray:[database_ sources]];
-    _trace();
-    [sources_ sortUsingSelector:@selector(compareByNameAndType:)];
-    _trace();
-
-     int count([sources_ count]);
-    offset_ = 0;
-    for (int i = 0; i != count; i++) {
-        if ([[sources_ objectAtIndex:i] record] == nil) break;
-        else offset_++;
-    }
-
-    [list_ setEditing:NO];
-    [self updateButtonsForEditingStatus:NO animated:NO];
-    [list_ reloadData];
-}
-
-- (void) addButtonClicked {
-    /*[book_ pushPage:[[[AddSourceController alloc]
-        initWithBook:book_
-        database:database_
-    ] autorelease]];*/
-
-    UIAlertView *alert = [[[UIAlertView alloc]
-        initWithTitle:UCLocalize("ENTER_APT_URL")
-        message:nil
-        delegate:self
-        cancelButtonTitle:UCLocalize("CANCEL")
-        otherButtonTitles:UCLocalize("ADD_SOURCE"), nil
-    ] autorelease];
-
-    [alert setContext:@"source"];
-    [alert setTransform:CGAffineTransformTranslate([alert transform], 0.0, 100.0)];
-
-    [alert setNumberOfRows:1];
-    [alert addTextFieldWithValue:@"http://" label:@""];
-
-    UITextInputTraits *traits = [[alert textField] textInputTraits];
-    [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
-    [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
-    [traits setKeyboardType:UIKeyboardTypeURL];
-    // XXX: UIReturnKeyDone
-    [traits setReturnKeyType:UIReturnKeyNext];
-
-    [alert show];
-}
-
-- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated {
-    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
-        initWithTitle:UCLocalize("ADD")
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(addButtonClicked)
-    ];
-    [[self navigationItem] setLeftBarButtonItem:editing ? leftItem : [[self navigationItem] backBarButtonItem] animated:animated];
-    [leftItem release];
-
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:editing ? UCLocalize("DONE") : UCLocalize("EDIT")
-        style:editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
-        target:self
-        action:@selector(editButtonClicked)
-    ];
-    [[self navigationItem] setRightBarButtonItem:rightItem animated:animated];
-    [rightItem release];
-
-    if (IsWildcat_ && !editing) {
-        UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("SETTINGS")
-            style:UIBarButtonItemStylePlain
-            target:self
-            action:@selector(settingsButtonClicked)
-            ];
-        [[self navigationItem] setLeftBarButtonItem:settingsItem];
-        [settingsItem release];
-    }
-}
-
-- (void) settingsButtonClicked {
-    [delegate_ showSettings];
-}
-
-- (void) editButtonClicked {
-    [list_ setEditing:![list_ isEditing] animated:YES];
-
-    [self updateButtonsForEditingStatus:[list_ isEditing] animated:YES];
-}
-
-@end
-/* }}} */
-
-/* Installed Controller {{{ */
-@interface InstalledController : FilteredPackageController {
-    BOOL expert_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-
-- (void) updateRoleButton;
-- (void) queueStatusDidChange;
-
-@end
-
-@implementation InstalledController
-
-- (void) dealloc {
-    [super dealloc];
-}
-
-- (NSString *) title { return UCLocalize("INSTALLED"); }
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndVisible:) with:[NSNumber numberWithBool:YES]]) != nil) {
-        [self updateRoleButton];
-        [self queueStatusDidChange];
-    } return self;
-}
-
-#if !AlwaysReload
-- (void) queueButtonClicked {
-    [delegate_ queue];
-}
-#endif
-
-- (void) queueStatusDidChange {
-#if !AlwaysReload
-    if (IsWildcat_) {
-        UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("QUEUE")
-            style:UIBarButtonItemStyleDone
-            target:self
-            action:@selector(queueButtonClicked)
-        ];
-        if (Queuing_) [[self navigationItem] setLeftBarButtonItem:queueItem];
-        else [[self navigationItem] setLeftBarButtonItem:nil];
-        [queueItem release];
-    }
-#endif
-}
-
-- (void) reloadData {
-    [packages_ reloadData];
-}
-
-- (void) updateRoleButton {
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE")
-        style:expert_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
-        target:self
-        action:@selector(roleButtonClicked)
-    ];
-    if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) [[self navigationItem] setRightBarButtonItem:rightItem];
-    [rightItem release];
-}
-
-- (void) roleButtonClicked {
-    [packages_ setObject:[NSNumber numberWithBool:expert_]];
-    [packages_ reloadData];
-    expert_ = !expert_;
-
-    [self updateRoleButton];
-}
-
-- (void) setDelegate:(id)delegate {
-    [super setDelegate:delegate];
-    [packages_ setDelegate:delegate];
-}
-
-@end
-/* }}} */
-
-/* Home Controller {{{ */
-@interface HomeController : CYBrowserController {
-}
-
-@end
-
-@implementation HomeController
-
-- (void) _setMoreHeaders:(NSMutableURLRequest *)request {
-    [super _setMoreHeaders:request];
-    if (ChipID_ != nil)
-        [request setValue:ChipID_ forHTTPHeaderField:@"X-Chip-ID"];
-    if (UniqueID_ != nil)
-        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
-}
-
-- (void) aboutButtonClicked {
-    UIAlertView *alert = [[[UIAlertView alloc] init] autorelease];
-    [alert setTitle:UCLocalize("ABOUT_CYDIA")];
-    [alert addButtonWithTitle:UCLocalize("CLOSE")];
-    [alert setCancelButtonIndex:0];
-
-    [alert setMessage:
-        @"Copyright (C) 2008-2010\n"
-        "Jay Freeman (saurik)\n"
-        "saurik@saurik.com\n"
-        "http://www.saurik.com/"
-    ];
-
-    [alert show];
-}
-
-- (void) viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
-    [[self navigationController] setNavigationBarHidden:YES animated:animated];
-}
-
-- (void) viewWillDisappear:(BOOL)animated {
-    [super viewWillDisappear:animated];
-    [[self navigationController] setNavigationBarHidden:NO animated:animated];
-}
-
-- (id) init {
-    if ((self = [super init]) != nil) {
-        UIBarButtonItem *aboutItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("ABOUT")
-            style:UIBarButtonItemStylePlain
-            target:self
-            action:@selector(aboutButtonClicked)
-        ];
-        [[self navigationItem] setLeftBarButtonItem:aboutItem];
-        [aboutItem release];
-    } return self;
-}
-
-@end
-/* }}} */
-/* Manage Controller {{{ */
-@interface ManageController : CYBrowserController {
-}
-
-- (void) queueStatusDidChange;
-@end
-
-@implementation ManageController
-
-- (id) init {
-    if ((self = [super init]) != nil) {
-        [[self navigationItem] setTitle:UCLocalize("MANAGE")];
-
-        UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("SETTINGS")
-            style:UIBarButtonItemStylePlain
-            target:self
-            action:@selector(settingsButtonClicked)
-        ];
-        [[self navigationItem] setLeftBarButtonItem:settingsItem];
-        [settingsItem release];
-
-        [self queueStatusDidChange];
-    } return self;
-}
-
-- (void) settingsButtonClicked {
-    [delegate_ showSettings];
-}
-
-#if !AlwaysReload
-- (void) queueButtonClicked {
-    [delegate_ queue];
-}
-
-- (void) applyLoadingTitle {
-    // No "Loading" title.
-}
-
-- (void) applyRightButton {
-    // No right button.
-}
-#endif
-
-- (void) queueStatusDidChange {
-#if !AlwaysReload
-    if (!IsWildcat_ && Queuing_) {
-        UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
-            initWithTitle:UCLocalize("QUEUE")
-            style:UIBarButtonItemStyleDone
-            target:self
-            action:@selector(queueButtonClicked)
-        ];
-        [[self navigationItem] setRightBarButtonItem:queueItem];
-
-        [queueItem release];
-    } else {
-        [[self navigationItem] setRightBarButtonItem:nil];
-    }
-#endif
-}
-
-- (bool) isLoading {
-    return false;
-}
-
-@end
-/* }}} */
-
-/* Refresh Bar {{{ */
-@interface RefreshBar : UINavigationBar {
-    UIProgressIndicator *indicator_;
-    UITextLabel *prompt_;
-    UIProgressBar *progress_;
-    UINavigationButton *cancel_;
-}
-
-@end
-
-@implementation RefreshBar
-
-- (void) positionViews {
-    CGRect frame = [cancel_ frame];
-    frame.origin.x = [self frame].size.width - frame.size.width - 5;
-    frame.origin.y = ([self frame].size.height - frame.size.height) / 2;
-    [cancel_ setFrame:frame];
-
-    CGSize prgsize = {75, 100};
-    CGRect prgrect = {{
-        [self frame].size.width - prgsize.width - 10,
-        ([self frame].size.height - prgsize.height) / 2
-    } , prgsize};
-    [progress_ setFrame:prgrect];
-
-    CGSize indsize([UIProgressIndicator defaultSizeForStyle:[indicator_ activityIndicatorViewStyle]]);
-    unsigned indoffset = ([self frame].size.height - indsize.height) / 2;
-    CGRect indrect = {{indoffset, indoffset}, indsize};
-    [indicator_ setFrame:indrect];
-
-    CGSize prmsize = {215, indsize.height + 4};
-    CGRect prmrect = {{
-        indoffset * 2 + indsize.width,
-        unsigned([self frame].size.height - prmsize.height) / 2 - 1
-    }, prmsize};
-    [prompt_ setFrame:prmrect];
-}
-
-- (void)setFrame:(CGRect)frame {
-    [super setFrame:frame];
-
-    [self positionViews];
-}
-
-- (id) initWithFrame:(CGRect)frame delegate:(id)delegate {
-    if ((self = [super initWithFrame:frame])) {
-        [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
-
-        [self setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
-        [self setBarStyle:UIBarStyleBlack];
-
-        UIBarStyle barstyle([self _barStyle:NO]);
-        bool ugly(barstyle == UIBarStyleDefault);
-
-        UIProgressIndicatorStyle style = ugly ?
-            UIProgressIndicatorStyleMediumBrown :
-            UIProgressIndicatorStyleMediumWhite;
-
-        indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectZero];
-        [indicator_ setStyle:style];
-        [indicator_ startAnimation];
-        [self addSubview:indicator_];
-
-        prompt_ = [[UITextLabel alloc] initWithFrame:CGRectZero];
-        [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]];
-        [prompt_ setBackgroundColor:[UIColor clearColor]];
-        [prompt_ setFont:[UIFont systemFontOfSize:15]];
-        [self addSubview:prompt_];
-
-        progress_ = [[UIProgressBar alloc] initWithFrame:CGRectZero];
-        [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin];
-        [progress_ setStyle:0];
-        [self addSubview:progress_];
-
-        cancel_ = [[UINavigationButton alloc] initWithTitle:UCLocalize("CANCEL") style:UINavigationButtonStyleHighlighted];
-        [cancel_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
-        [cancel_ addTarget:delegate action:@selector(cancelPressed) forControlEvents:UIControlEventTouchUpInside];
-        [cancel_ setBarStyle:barstyle];
-
-        [self positionViews];
-    } return self;
-}
-
-- (void) cancel {
-    [cancel_ removeFromSuperview];
-}
-
-- (void) start {
-    [prompt_ setText:UCLocalize("UPDATING_DATABASE")];
-    [progress_ setProgress:0];
-    [self addSubview:cancel_];
-}
-
-- (void) stop {
-    [cancel_ removeFromSuperview];
-}
-
-- (void) setPrompt:(NSString *)prompt {
-    [prompt_ setText:prompt];
-}
-
-- (void) setProgress:(float)progress {
-    [progress_ setProgress:progress];
-}
-
-@end
-/* }}} */
-
-@class CYNavigationController;
-
-/* Cydia Tab Bar Controller {{{ */
-@interface CYTabBarController : UITabBarController {
-    Database *database_;
-}
-
-@end
-
-@implementation CYTabBarController
-
-/* XXX: some logic should probably go here related to
-freeing the view controllers on tab change */
-
-- (void) reloadData {
-    size_t count([[self viewControllers] count]);
-    for (size_t i(0); i != count; ++i) {
-        CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
-        [page reloadData];
-    }
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-    } return self;
-}
-
-@end
-/* }}} */
-
-/* Cydia Navigation Controller {{{ */
-@interface CYNavigationController : UINavigationController {
-    _transient Database *database_;
-    id<UINavigationControllerDelegate> delegate_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-- (void) reloadData;
-
-@end
-
-
-@implementation CYNavigationController
-
-- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
-    // Inherit autorotation settings for modal parents.
-    if ([self parentViewController] && [[self parentViewController] modalViewController] == self) {
-        return [[self parentViewController] shouldAutorotateToInterfaceOrientation:orientation];
-    } else {
-        return [super shouldAutorotateToInterfaceOrientation:orientation];
-    }
-}
-
-- (void) dealloc {
-    [super dealloc];
-}
-
-- (void) reloadData {
-    size_t count([[self viewControllers] count]);
-    for (size_t i(0); i != count; ++i) {
-        CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
-        [page reloadData];
-    }
-}
-
-- (void) setDelegate:(id<UINavigationControllerDelegate>)delegate {
-    delegate_ = delegate;
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-    } return self;
-}
-
-@end
-/* }}} */
-/* Cydia:// Protocol {{{ */
-@interface CydiaURLProtocol : NSURLProtocol {
-}
-
-@end
-
-@implementation CydiaURLProtocol
-
-+ (BOOL) canInitWithRequest:(NSURLRequest *)request {
-    NSURL *url([request URL]);
-    if (url == nil)
-        return NO;
-    NSString *scheme([[url scheme] lowercaseString]);
-    if (scheme == nil || ![scheme isEqualToString:@"cydia"])
-        return NO;
-    return YES;
-}
-
-+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
-    return request;
-}
-
-- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request {
-    id<NSURLProtocolClient> client([self client]);
-    if (icon == nil)
-        [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]];
-    else {
-        NSData *data(UIImagePNGRepresentation(icon));
-
-        NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]);
-        [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
-        [client URLProtocol:self didLoadData:data];
-        [client URLProtocolDidFinishLoading:self];
-    }
-}
-
-- (void) startLoading {
-    id<NSURLProtocolClient> client([self client]);
-    NSURLRequest *request([self request]);
-
-    NSURL *url([request URL]);
-    NSString *href([url absoluteString]);
-
-    NSString *path([href substringFromIndex:8]);
-    NSRange slash([path rangeOfString:@"/"]);
-
-    NSString *command;
-    if (slash.location == NSNotFound) {
-        command = path;
-        path = nil;
-    } else {
-        command = [path substringToIndex:slash.location];
-        path = [path substringFromIndex:(slash.location + 1)];
-    }
-
-    Database *database([Database sharedInstance]);
-
-    if ([command isEqualToString:@"package-icon"]) {
-        if (path == nil)
-            goto fail;
-        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-        Package *package([database packageWithName:path]);
-        if (package == nil)
-            goto fail;
-        UIImage *icon([package icon]);
-        [self _returnPNGWithImage:icon forRequest:request];
-    } else if ([command isEqualToString:@"source-icon"]) {
-        if (path == nil)
-            goto fail;
-        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-        NSString *source(Simplify(path));
-        UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sources/%@.png", App_, source]]);
-        if (icon == nil)
-            icon = [UIImage applicationImageNamed:@"unknown.png"];
-        [self _returnPNGWithImage:icon forRequest:request];
-    } else if ([command isEqualToString:@"uikit-image"]) {
-        if (path == nil)
-            goto fail;
-        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-        UIImage *icon(_UIImageWithName(path));
-        [self _returnPNGWithImage:icon forRequest:request];
-    } else if ([command isEqualToString:@"section-icon"]) {
-        if (path == nil)
-            goto fail;
-        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-        NSString *section(Simplify(path));
-        UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]);
-        if (icon == nil)
-            icon = [UIImage applicationImageNamed:@"unknown.png"];
-        [self _returnPNGWithImage:icon forRequest:request];
-    } else fail: {
-        [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]];
-    }
-}
-
-- (void) stopLoading {
-}
-
-@end
-/* }}} */
-
-/* Sections Controller {{{ */
-@interface SectionsController : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    NSMutableArray *sections_;
-    NSMutableArray *filtered_;
-    UITableView *list_;
-    UIView *accessory_;
-    BOOL editing_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-- (void) reloadData;
-- (void) resetView;
-
-- (void) editButtonClicked;
-
-@end
-
-@implementation SectionsController
-
-- (void) dealloc {
-    [list_ setDataSource:nil];
-    [list_ setDelegate:nil];
-
-    [sections_ release];
-    [filtered_ release];
-    [list_ release];
-    [accessory_ release];
-    [super dealloc];
-}
-
-- (void) viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
-}
-
-- (Section *) sectionAtIndexPath:(NSIndexPath *)indexPath {
-    Section *section = (editing_ ? [sections_ objectAtIndex:[indexPath row]] : ([indexPath row] == 0 ? nil : [filtered_ objectAtIndex:([indexPath row] - 1)]));
-    return section;
-}
-
-- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    return editing_ ? [sections_ count] : [filtered_ count] + 1;
-}
-
-/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
-    return 45.0f;
-}*/
-
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    static NSString *reuseIdentifier = @"SectionCell";
-
-    SectionCell *cell = (SectionCell *) [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
-    if (cell == nil) cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
-    [cell setSection:[self sectionAtIndexPath:indexPath] editing:editing_];
-
-    return cell;
-}
-
-- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    Section *section = [self sectionAtIndexPath:indexPath];
-    NSString *name = [section name];
-    NSString *title;
-
-    if ([indexPath row] == 0) {
-        section = nil;
-        name = nil;
-        title = UCLocalize("ALL_PACKAGES");
-    } else {
-        if (name != nil) {
-            name = [NSString stringWithString:name];
-            title = [[NSBundle mainBundle] localizedStringForKey:Simplify(name) value:nil table:@"Sections"];
-        } else {
-            name = @"";
-            title = UCLocalize("NO_SECTION");
-        }
-    }
-
-    FilteredPackageController *table = [[[FilteredPackageController alloc]
-        initWithDatabase:database_
-        title:title
-        filter:@selector(isVisibleInSection:)
-        with:name
-    ] autorelease];
-
-    [table setDelegate:delegate_];
-
-    [[self navigationController] pushViewController:table animated:YES];
-}
-
-- (NSString *) title { return UCLocalize("SECTIONS"); }
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-
-        [[self navigationItem] setTitle:UCLocalize("SECTIONS")];
-
-        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
-        filtered_ = [[NSMutableArray arrayWithCapacity:16] retain];
-
-        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [list_ setRowHeight:45.0f];
-        [[self view] addSubview:list_];
-
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-
-        [self reloadData];
-    } return self;
-}
-
-- (void) reloadData {
-    NSArray *packages = [database_ packages];
-
-    [sections_ removeAllObjects];
-    [filtered_ removeAllObjects];
-
-#if 0
-    typedef __gnu_cxx::hash_map<NSString *, Section *, NSStringMapHash, NSStringMapEqual> SectionMap;
-    SectionMap sections;
-    sections.resize(64);
-#else
-    NSMutableDictionary *sections([NSMutableDictionary dictionaryWithCapacity:32]);
-#endif
-
-    _trace();
-    for (Package *package in packages) {
-        NSString *name([package section]);
-        NSString *key(name == nil ? @"" : name);
-
-#if 0
-        Section **section;
-
-        _profile(SectionsView$reloadData$Section)
-            section = &sections[key];
-            if (*section == nil) {
-                _profile(SectionsView$reloadData$Section$Allocate)
-                    *section = [[[Section alloc] initWithName:name localize:YES] autorelease];
-                _end
-            }
-        _end
-
-        [*section addToCount];
-
-        _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || ![package visible])
-                continue;
-        _end
-
-        [*section addToRow];
-#else
-        Section *section;
-
-        _profile(SectionsView$reloadData$Section)
-            section = [sections objectForKey:key];
-            if (section == nil) {
-                _profile(SectionsView$reloadData$Section$Allocate)
-                    section = [[[Section alloc] initWithName:name localize:YES] autorelease];
-                    [sections setObject:section forKey:key];
-                _end
-            }
-        _end
-
-        [section addToCount];
-
-        _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || ![package visible])
-                continue;
-        _end
-
-        [section addToRow];
-#endif
-    }
-    _trace();
-
-#if 0
-    for (SectionMap::const_iterator i(sections.begin()), e(sections.end()); i != e; ++i)
-        [sections_ addObject:i->second];
-#else
-    [sections_ addObjectsFromArray:[sections allValues]];
-#endif
-
-    [sections_ sortUsingSelector:@selector(compareByLocalized:)];
-
-    for (Section *section in sections_) {
-        size_t count([section row]);
-        if (count == 0)
-            continue;
-
-        section = [[[Section alloc] initWithName:[section name] localized:[section localized]] autorelease];
-        [section setCount:count];
-        [filtered_ addObject:section];
-    }
-
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:[sections_ count] == 0 ? nil : UCLocalize("EDIT")
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(editButtonClicked)
-    ];
-    [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] != nil];
-    [rightItem release];
-
-    [list_ reloadData];
-    _trace();
-}
-
-- (void) resetView {
-    if (editing_)
-        [self editButtonClicked];
-}
-
-- (void) editButtonClicked {
-    if ((editing_ = !editing_))
-        [list_ reloadData];
-    else
-        [delegate_ updateData];
-
-    [[self navigationItem] setTitle:editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")];
-    [[[self navigationItem] rightBarButtonItem] setTitle:[sections_ count] == 0 ? nil : editing_ ? UCLocalize("DONE") : UCLocalize("EDIT")];
-    [[[self navigationItem] rightBarButtonItem] setStyle:editing_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain];
-}
-
-- (UIView *) accessoryView {
-    return accessory_;
-}
-
-@end
-/* }}} */
-/* Changes Controller {{{ */
-@interface ChangesController : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    NSMutableArray *packages_;
-    NSMutableArray *sections_;
-    UITableView *list_;
-    unsigned upgrades_;
-    BOOL hasSentFirstLoad_;
-}
-
-- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
-- (void) reloadData;
-
-@end
-
-@implementation ChangesController
-
-- (void) dealloc {
-    [list_ setDelegate:nil];
-    [list_ setDataSource:nil];
-
-    [packages_ release];
-    [sections_ release];
-    [list_ release];
-    [super dealloc];
-}
-
-- (void) viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    if (!hasSentFirstLoad_) {
-        hasSentFirstLoad_ = YES;
-        [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0];
-    } else {
-        [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
-    }
-}
-
-- (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
-    NSInteger count([sections_ count]);
-    return count == 0 ? 1 : count;
-}
-
-- (NSString *) tableView:(UITableView *)list titleForHeaderInSection:(NSInteger)section {
-    if ([sections_ count] == 0)
-        return nil;
-    return [[sections_ objectAtIndex:section] name];
-}
-
-- (NSInteger) tableView:(UITableView *)list numberOfRowsInSection:(NSInteger)section {
-    if ([sections_ count] == 0)
-        return 0;
-    return [[sections_ objectAtIndex:section] count];
-}
-
-- (Package *) packageAtIndexPath:(NSIndexPath *)path {
-    Section *section([sections_ objectAtIndex:[path section]]);
-    NSInteger row([path row]);
-    return [packages_ objectAtIndex:([section row] + row)];
-}
-
-- (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path {
-    PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]);
-    if (cell == nil)
-        cell = [[[PackageCell alloc] init] autorelease];
-    [cell setPackage:[self packageAtIndexPath:path]];
-    return cell;
-}
-
-/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path {
-    return [PackageCell heightForPackage:[self packageAtIndexPath:path]];
-}*/
-
-- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path {
-    Package *package([self packageAtIndexPath:path]);
-    PackageController *view([delegate_ packageController]);
-    [view setDelegate:delegate_];
-    [view setPackage:package];
-    [[self navigationController] pushViewController:view animated:YES];
-    return path;
-}
-
-- (void) refreshButtonClicked {
-    [delegate_ beginUpdate];
-    [[self navigationItem] setLeftBarButtonItem:nil];
-}
-
-- (void) upgradeButtonClicked {
-    [delegate_ distUpgrade];
-}
-
-- (NSString *) title { return UCLocalize("CHANGES"); }
-
-- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-        [[self navigationItem] setTitle:UCLocalize("CHANGES")];
-
-        packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
-        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
-
-        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
-        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [list_ setRowHeight:73.0f];
-        [[self view] addSubview:list_];
-
-        [list_ setDataSource:self];
-        [list_ setDelegate:self];
-
-        delegate_ = delegate;
-    } return self;
-}
-
-- (void) _reloadPackages:(NSArray *)packages {
-    _trace();
-    for (Package *package in packages)
-        if (
-            [package uninstalled] && [package valid] && [package visible] ||
-            [package upgradableAndEssential:YES]
-        )
-            [packages_ addObject:package];
-
-    _trace();
-    [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
-    _trace();
-}
-
-- (void) reloadData {
-    NSArray *packages = [database_ packages];
-
-    [packages_ removeAllObjects];
-    [sections_ removeAllObjects];
-
-    UIProgressHUD *hud([delegate_ addProgressHUD]);
-    // XXX: localize
-    [hud setText:@"Loading Changes"];
-    NSLog(@"HUD:%@::%@", delegate_, hud);
-    [self yieldToSelector:@selector(_reloadPackages:) withObject:packages];
-    [delegate_ removeProgressHUD:hud];
-
-    Section *upgradable = [[[Section alloc] initWithName:UCLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease];
-    Section *ignored = [[[Section alloc] initWithName:UCLocalize("IGNORED_UPGRADES") localize:NO] autorelease];
-    Section *section = nil;
-    NSDate *last = nil;
-
-    upgrades_ = 0;
-    bool unseens = false;
-
-    CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle));
-
-    for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
-        Package *package = [packages_ objectAtIndex:offset];
-
-        BOOL uae = [package upgradableAndEssential:YES];
-
-        if (!uae) {
-            unseens = true;
-            NSDate *seen;
-
-            _profile(ChangesController$reloadData$Remember)
-                seen = [package seen];
-            _end
-
-            if (section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame)) {
-                last = seen;
-
-                NSString *name;
-                if (seen == nil)
-                    name = UCLocalize("UNKNOWN");
-                else {
-                    name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen);
-                    [name autorelease];
-                }
-
-                _profile(ChangesController$reloadData$Allocate)
-                    name = [NSString stringWithFormat:UCLocalize("NEW_AT"), name];
-                    section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease];
-                    [sections_ addObject:section];
-                _end
-            }
-
-            [section addToCount];
-        } else if ([package ignored])
-            [ignored addToCount];
-        else {
-            ++upgrades_;
-            [upgradable addToCount];
-        }
-    }
-    _trace();
-
-    CFRelease(formatter);
-
-    if (unseens) {
-        Section *last = [sections_ lastObject];
-        size_t count = [last count];
-        [packages_ removeObjectsInRange:NSMakeRange([packages_ count] - count, count)];
-        [sections_ removeLastObject];
-    }
-
-    if ([ignored count] != 0)
-        [sections_ insertObject:ignored atIndex:0];
-    if (upgrades_ != 0)
-        [sections_ insertObject:upgradable atIndex:0];
-
-    [list_ reloadData];
-
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:[NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]]
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(upgradeButtonClicked)
-    ];
-    if (upgrades_ > 0) [[self navigationItem] setRightBarButtonItem:rightItem];
-    [rightItem release];
-
-    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
-        initWithTitle:UCLocalize("REFRESH")
-        style:UIBarButtonItemStylePlain
-        target:self
-        action:@selector(refreshButtonClicked)
-    ];
-    if (![delegate_ updating]) [[self navigationItem] setLeftBarButtonItem:leftItem];
-    [leftItem release];
-}
-
-@end
-/* }}} */
-/* Search Controller {{{ */
-@interface SearchController : FilteredPackageController <
-    UISearchBarDelegate
-> {
-    UISearchBar *search_;
-}
-
-- (id) initWithDatabase:(Database *)database;
-- (void) reloadData;
-
-@end
-
-@implementation SearchController
-
-- (void) dealloc {
-    [search_ release];
-    [super dealloc];
-}
-
-- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
-    [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
-    [search_ resignFirstResponder];
-    [self reloadData];
-}
-
-- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text {
-    [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
-    [self reloadData];
-}
-
-- (NSString *) title { return nil; }
-
-- (id) initWithDatabase:(Database *)database {
-    return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil];
-}
-
-- (void)viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    if (!search_) {
-        search_ = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, 44.0f)];
-        [search_ layoutSubviews];
-        [search_ setPlaceholder:UCLocalize("SEARCH_EX")];
-        UITextField *textField = [search_ searchField];
-        [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
-        [search_ setDelegate:self];
-        [textField setEnablesReturnKeyAutomatically:NO];
-        [[self navigationItem] setTitleView:textField];
-    }
-}
-
-- (void) _reloadData {
-}
-
-- (void) reloadData {
-    _profile(SearchController$reloadData)
-        [packages_ reloadData];
-    _end
-    PrintTimes();
-    [packages_ resetCursor];
-}
-
-- (void) didSelectPackage:(Package *)package {
-    [search_ resignFirstResponder];
-    [super didSelectPackage:package];
-}
-
-@end
-/* }}} */
-/* Settings Controller {{{ */
-@interface SettingsController : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    NSString *name_;
-    Package *package_;
-    UITableView *table_;
-    id subscribedSwitch_;
-    id ignoredSwitch_;
-    UITableViewCell *subscribedCell_;
-    UITableViewCell *ignoredCell_;
-}
-
-- (id) initWithDatabase:(Database *)database package:(NSString *)package;
-
-@end
-
-@implementation SettingsController
-
-- (void) dealloc {
-    [name_ release];
-    if (package_ != nil)
-        [package_ release];
-    [table_ release];
-    [subscribedSwitch_ release];
-    [ignoredSwitch_ release];
-    [subscribedCell_ release];
-    [ignoredCell_ release];
-
-    [super dealloc];
-}
-
-- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
-    if (package_ == nil)
-        return 0;
-
-    return 1;
-}
-
-- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    if (package_ == nil)
-        return 0;
-
-    return 1;
-}
-
-- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
-    return UCLocalize("SHOW_ALL_CHANGES_EX");
-}
-
-- (void) onSomething:(BOOL)value withKey:(NSString *)key {
-    if (package_ == nil)
-        return;
-
-    NSMutableDictionary *metadata([package_ metadata]);
-
-    BOOL before;
-    if (NSNumber *number = [metadata objectForKey:key])
-        before = [number boolValue];
-    else
-        before = NO;
-
-    if (value != before) {
-        [metadata setObject:[NSNumber numberWithBool:value] forKey:key];
-        Changed_ = true;
-        [delegate_ updateData];
-    }
-}
-
-- (void) onSubscribed:(id)control {
-    [self onSomething:(int) [control isOn] withKey:@"IsSubscribed"];
-}
-
-- (void) onIgnored:(id)control {
-    [self onSomething:(int) [control isOn] withKey:@"IsIgnored"];
-}
-
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    if (package_ == nil)
-        return nil;
-
-    switch ([indexPath row]) {
-        case 0: return subscribedCell_;
-        case 1: return ignoredCell_;
-
-        _nodefault
-    }
-
-    return nil;
-}
-
-- (NSString *) title { return UCLocalize("SETTINGS"); }
-
-- (id) initWithDatabase:(Database *)database package:(NSString *)package {
-    if ((self = [super init])) {
-        database_ = database;
-        name_ = [package retain];
-
-        [[self navigationItem] setTitle:UCLocalize("SETTINGS")];
-
-        table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
-        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [[self view] addSubview:table_];
-
-        subscribedSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
-        [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
-        [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged];
-
-        ignoredSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
-        [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
-        [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged];
-
-        subscribedCell_ = [[UITableViewCell alloc] init];
-        [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
-        [subscribedCell_ setAccessoryView:subscribedSwitch_];
-        [subscribedCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
-
-        ignoredCell_ = [[UITableViewCell alloc] init];
-        [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")];
-        [ignoredCell_ setAccessoryView:ignoredSwitch_];
-        [ignoredCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
-
-        [table_ setDataSource:self];
-        [table_ setDelegate:self];
-        [self reloadData];
-    } return self;
-}
-
-- (void) reloadData {
-    if (package_ != nil)
-        [package_ autorelease];
-    package_ = [database_ packageWithName:name_];
-    if (package_ != nil) {
-        [package_ retain];
-        [subscribedSwitch_ setOn:([package_ subscribed] ? 1 : 0) animated:NO];
-        [ignoredSwitch_ setOn:([package_ ignored] ? 1 : 0) animated:NO];
-    }
-
-    [table_ reloadData];
-}
-
-@end
-/* }}} */
-
-/* Signature Controller {{{ */
-@interface SignatureController : CYBrowserController {
-    _transient Database *database_;
-    NSString *package_;
-}
-
-- (id) initWithDatabase:(Database *)database package:(NSString *)package;
-
-@end
-
-@implementation SignatureController
-
-- (void) dealloc {
-    [package_ release];
-    [super dealloc];
-}
-
-- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
-    // XXX: dude!
-    [super webView:sender didClearWindowObject:window forFrame:frame];
-}
-
-- (id) initWithDatabase:(Database *)database package:(NSString *)package {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-        package_ = [package retain];
-        [self reloadData];
-    } return self;
-}
-
-- (void) reloadData {
-    [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]];
-}
-
-@end
-/* }}} */
-/* Role Controller {{{ */
-@interface RoleController : CYViewController <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    _transient Database *database_;
-    id roledelegate_;
-    UITableView *table_;
-    UISegmentedControl *segment_;
-    UIView *container_;
-}
-
-- (void) showDoneButton;
-- (void) resizeSegmentedControl;
-
-@end
-
-@implementation RoleController
-- (void) dealloc {
-    [table_ release];
-    [segment_ release];
-    [container_ release];
-
-    [super dealloc];
-}
-
-- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
-    if ((self = [super init])) {
-        database_ = database;
-        roledelegate_ = delegate;
-
-        [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")];
-
-        NSArray *items = [NSArray arrayWithObjects:
-            UCLocalize("USER"),
-            UCLocalize("HACKER"),
-            UCLocalize("DEVELOPER"),
-        nil];
-        segment_ = [[UISegmentedControl alloc] initWithItems:items];
-        container_ = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)];
-        [container_ addSubview:segment_];
-
-        int index = -1;
-        if ([Role_ isEqualToString:@"User"]) index = 0;
-        if ([Role_ isEqualToString:@"Hacker"]) index = 1;
-        if ([Role_ isEqualToString:@"Developer"]) index = 2;
-        if (index != -1) {
-            [segment_ setSelectedSegmentIndex:index];
-            [self showDoneButton];
-        }
-
-        [segment_ addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];
-        [self resizeSegmentedControl];
-
-        table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
-        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [table_ setDelegate:self];
-        [table_ setDataSource:self];
-        [[self view] addSubview:table_];
-        [table_ reloadData];
-    } return self;
-}
-
-- (void) resizeSegmentedControl {
-    CGFloat width = [[self view] frame].size.width;
-    [segment_ setFrame:CGRectMake(width / 32.0f, 0, width - (width / 32.0f * 2.0f), 44.0f)];
-}
-
-- (void) viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
-
-    [self resizeSegmentedControl];
-}
-
-- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
-    [self resizeSegmentedControl];
-}
-
-- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
-    [self resizeSegmentedControl];
-}
-
-- (void) save {
-    NSString *role(nil);
-
-    switch ([segment_ selectedSegmentIndex]) {
-        case 0: role = @"User"; break;
-        case 1: role = @"Hacker"; break;
-        case 2: role = @"Developer"; break;
-
-        _nodefault
-    }
-
-    if (![role isEqualToString:Role_]) {
-        bool rolling(Role_ == nil);
-        Role_ = role;
-
-        Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-            Role_, @"Role",
-        nil];
-
-        [Metadata_ setObject:Settings_ forKey:@"Settings"];
-
-        Changed_ = true;
-
-        if (rolling)
-            [roledelegate_ loadData];
-        else
-            [roledelegate_ updateData];
-    }
-}
-
-- (void) segmentChanged:(UISegmentedControl *)control {
-    [self showDoneButton];
-}
-
-- (void) doneButtonClicked {
-    [self save];
-    [[self navigationController] dismissModalViewControllerAnimated:YES];
-}
-
-- (void) showDoneButton {
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
-        initWithTitle:UCLocalize("DONE")
-        style:UIBarButtonItemStyleDone
-        target:self
-        action:@selector(doneButtonClicked)
-    ];
-    [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] == nil];
-    [rightItem release];
-}
-
-- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
-    // XXX: For not having a single cell in the table, this sure is a lot of sections.
-    return 6;
-}
-
-- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    return 0; // :(
-}
-
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    return nil; // This method is required by the protocol.
-}
-
-- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
-    if (section == 1)
-        return UCLocalize("ROLE_EX");
-    if (section == 4)
-        return [NSString stringWithFormat:
-            @"%@: %@\n%@: %@\n%@: %@",
-            UCLocalize("USER"), UCLocalize("USER_EX"),
-            UCLocalize("HACKER"), UCLocalize("HACKER_EX"),
-            UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX")
-        ];
-    else return nil;
-}
-
-- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
-    if (section == 3) return 44.0f;
-    else return 0;
-}
-
-- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
-    if (section == 3) return container_;
-    else return nil;
-}
-
-@end
-/* }}} */
-
-/* Cydia Container {{{ */
-@interface CYContainer : UIViewController <ProgressDelegate> {
-    _transient Database *database_;
-    RefreshBar *refreshbar_;
-
-    bool dropped_;
-    bool updating_;
-    id updatedelegate_;
-    UITabBarController *root_;
-}
-
-- (void) setTabBarController:(UITabBarController *)controller;
-
-- (void) dropBar:(BOOL)animated;
-- (void) beginUpdate;
-- (void) raiseBar:(BOOL)animated;
-- (BOOL) updating;
-
-@end
-
-@implementation CYContainer
-
-- (BOOL) _reallyWantsFullScreenLayout {
-    return YES;
-}
-
-// NOTE: UIWindow only sends the top controller these messages,
-//       So we have to forward them on.
-
-- (void) viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];
-    [root_ viewDidAppear:animated];
-}
-
-- (void) viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
-    [root_ viewWillAppear:animated];
-}
-
-- (void) viewDidDisappear:(BOOL)animated {
-    [super viewDidDisappear:animated];
-    [root_ viewDidDisappear:animated];
-}
-
-- (void) viewWillDisappear:(BOOL)animated {
-    [super viewWillDisappear:animated];
-    [root_ viewWillDisappear:animated];
-}
-
-- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
-    return IsWildcat_;
-}
-
-- (void) setTabBarController:(UITabBarController *)controller {
-    root_ = controller;
-    [[self view] addSubview:[root_ view]];
-}
-
-- (void) setUpdate:(NSDate *)date {
-    [self beginUpdate];
-}
-
-- (void) beginUpdate {
-    [self dropBar:YES];
-    [refreshbar_ start];
-
-    updating_ = true;
-
-    [NSThread
-        detachNewThreadSelector:@selector(performUpdate)
-        toTarget:self
-        withObject:nil
-    ];
-}
-
-- (void) performUpdate { _pooled
-    Status status;
-    status.setDelegate(self);
-    [database_ updateWithStatus:status];
-
-    [self
-        performSelectorOnMainThread:@selector(completeUpdate)
-        withObject:nil
-        waitUntilDone:NO
-    ];
-}
-
-- (void) completeUpdate {
-    updating_ = false;
-
-    [self raiseBar:YES];
-    [refreshbar_ stop];
-    [updatedelegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
-}
-
-- (void) cancelUpdate {
-    [refreshbar_ cancel];
-    [self completeUpdate];
-}
-
-- (void) cancelPressed {
-    [self cancelUpdate];
-}
-
-- (BOOL) updating {
-    return updating_;
-}
-
-- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
-    [refreshbar_ setPrompt:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), error]];
-}
-
-- (void) startProgress {
-}
-
-- (void) setProgressTitle:(NSString *)title {
-    [self
-        performSelectorOnMainThread:@selector(_setProgressTitle:)
-        withObject:title
-        waitUntilDone:YES
-    ];
-}
-
-- (bool) isCancelling:(size_t)received {
-    return !updating_;
-}
-
-- (void) setProgressPercent:(float)percent {
-    [self
-        performSelectorOnMainThread:@selector(_setProgressPercent:)
-        withObject:[NSNumber numberWithFloat:percent]
-        waitUntilDone:YES
-    ];
-}
-
-- (void) addProgressOutput:(NSString *)output {
-    [self
-        performSelectorOnMainThread:@selector(_addProgressOutput:)
-        withObject:output
-        waitUntilDone:YES
-    ];
-}
-
-- (void) _setProgressTitle:(NSString *)title {
-    [refreshbar_ setPrompt:title];
-}
-
-- (void) _setProgressPercent:(NSNumber *)percent {
-    [refreshbar_ setProgress:[percent floatValue]];
-}
-
-- (void) _addProgressOutput:(NSString *)output {
-}
-
-- (void) setUpdateDelegate:(id)delegate {
-    updatedelegate_ = delegate;
-}
-
-- (CGFloat) statusBarHeight {
-    if (UIInterfaceOrientationIsPortrait([self interfaceOrientation])) {
-        return [[UIApplication sharedApplication] statusBarFrame].size.height;
-    } else {
-        return [[UIApplication sharedApplication] statusBarFrame].size.width;
-    }
-}
-
-- (void) dropBar:(BOOL)animated {
-    if (dropped_) return;
-    dropped_ = true;
-
-    [[self view] addSubview:refreshbar_];
-
-    CGFloat sboffset = [self statusBarHeight];
-
-    CGRect barframe = [refreshbar_ frame];
-    barframe.origin.y = sboffset;
-    [refreshbar_ setFrame:barframe];
-
-    if (animated) [UIView beginAnimations:nil context:NULL];
-    CGRect viewframe = [[root_ view] frame];
-    viewframe.origin.y += barframe.size.height + sboffset;
-    viewframe.size.height -= barframe.size.height + sboffset;
-    [[root_ view] setFrame:viewframe];
-    if (animated) [UIView commitAnimations];
-
-    // Ensure bar has the proper width for our view, it might have changed
-    barframe.size.width = viewframe.size.width;
-    [refreshbar_ setFrame:barframe];
-
-    // XXX: fix Apple's layout bug
-    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
-}
-
-- (void) raiseBar:(BOOL)animated {
-    if (!dropped_) return;
-    dropped_ = false;
-
-    [refreshbar_ removeFromSuperview];
-
-    CGFloat sboffset = [self statusBarHeight];
-
-    if (animated) [UIView beginAnimations:nil context:NULL];
-    CGRect barframe = [refreshbar_ frame];
-    CGRect viewframe = [[root_ view] frame];
-    viewframe.origin.y -= barframe.size.height + sboffset;
-    viewframe.size.height += barframe.size.height + sboffset;
-    [[root_ view] setFrame:viewframe];
-    if (animated) [UIView commitAnimations];
-
-    // XXX: fix Apple's layout bug
-    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
-}
-
-- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
-    // XXX: fix Apple's layout bug
-    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
-}
-
-- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
-    if (dropped_) {
-        [self raiseBar:NO];
-        [self dropBar:NO];
-    }
-
-    // XXX: fix Apple's layout bug
-    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
-}
-
-- (void) statusBarFrameChanged:(NSNotification *)notification {
-    if (dropped_) {
-        [self raiseBar:NO];
-        [self dropBar:NO];
-    }
-}
-
-- (void) dealloc {
-    [refreshbar_ release];
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    [super dealloc];
-}
-
-- (id) initWithDatabase:(Database *)database {
-    if ((self = [super init]) != nil) {
-        database_ = database;
-
-        [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
-
-        refreshbar_ = [[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self];
-    } return self;
-}
-
-@end
-/* }}} */
-
-typedef enum {
-    kCydiaTag = 0,
-    kSectionsTag = 1,
-    kChangesTag = 2,
-    kManageTag = 3,
-    kInstalledTag = 4,
-    kSourcesTag = 5,
-    kSearchTag = 6
-} CYTabTag;
-
-@interface Cydia : UIApplication <
-    ConfirmationControllerDelegate,
-    ProgressControllerDelegate,
-    CydiaDelegate,
-    UINavigationControllerDelegate
-> {
-    UIWindow *window_;
-    CYContainer *container_;
-
-    id tabbar_;
-
-    NSMutableArray *essential_;
-    NSMutableArray *broken_;
-
-    Database *database_;
-
-    int tag_;
-
-    UIKeyboard *keyboard_;
-    UIProgressHUD *hud_;
-
-    SectionsController *sections_;
-    ChangesController *changes_;
-    ManageController *manage_;
-    SearchController *search_;
-    SourceTable *sources_;
-    InstalledController *installed_;
-    id queueDelegate_;
-
-#if RecyclePackageViews
-    NSMutableArray *details_;
-#endif
-
-    bool loaded_;
-}
-
-- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class;
-- (void) setPage:(CYViewController *)page;
-- (void) loadData;
-
-@end
-
-static _finline void _setHomePage(Cydia *self) {
-    [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeController class]]];
-}
-
-@implementation Cydia
-
-- (void) beginUpdate {
-    [container_ beginUpdate];
-}
-
-- (BOOL) updating {
-    return [container_ updating];
-}
-
-- (UIView *) rotatingContentViewForWindow:(UIWindow *)window {
-    return window_;
-}
-
-- (void) _loaded {
-    if ([broken_ count] != 0) {
-        int count = [broken_ count];
-
-        UIAlertView *alert = [[[UIAlertView alloc]
-            initWithTitle:(count == 1 ? UCLocalize("HALFINSTALLED_PACKAGE") : [NSString stringWithFormat:UCLocalize("HALFINSTALLED_PACKAGES"), count])
-            message:UCLocalize("HALFINSTALLED_PACKAGE_EX")
-            delegate:self
-            cancelButtonTitle:UCLocalize("FORCIBLY_CLEAR")
-            otherButtonTitles:UCLocalize("TEMPORARY_IGNORE"), nil
-        ] autorelease];
-
-        [alert setContext:@"fixhalf"];
-        [alert show];
-    } else if (!Ignored_ && [essential_ count] != 0) {
-        int count = [essential_ count];
-
-        UIAlertView *alert = [[[UIAlertView alloc]
-            initWithTitle:(count == 1 ? UCLocalize("ESSENTIAL_UPGRADE") : [NSString stringWithFormat:UCLocalize("ESSENTIAL_UPGRADES"), count])
-            message:UCLocalize("ESSENTIAL_UPGRADE_EX")
-            delegate:self
-            cancelButtonTitle:UCLocalize("TEMPORARY_IGNORE")
-            otherButtonTitles:UCLocalize("UPGRADE_ESSENTIAL"), UCLocalize("COMPLETE_UPGRADE"), nil
-        ] autorelease];
-
-        [alert setContext:@"upgrade"];
-        [alert show];
-    }
-}
-
-- (void) _saveConfig {
-    if (Changed_) {
-        _trace();
-        NSString *error(nil);
-        if (NSData *data = [NSPropertyListSerialization dataFromPropertyList:Metadata_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]) {
-            _trace();
-            NSError *error(nil);
-            if (![data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error])
-                NSLog(@"failure to save metadata data: %@", error);
-            _trace();
-        } else {
-            NSLog(@"failure to serialize metadata: %@", error);
-            return;
-        }
-
-        Changed_ = false;
-    }
-}
-
-- (void) _updateData {
-    [self _saveConfig];
-
-    /* XXX: this is just stupid */
-    if (tag_ != 1 && sections_ != nil)
-        [sections_ reloadData];
-    if (tag_ != 2 && changes_ != nil)
-        [changes_ reloadData];
-    if (tag_ != 4 && search_ != nil)
-        [search_ reloadData];
-
-    [(CYNavigationController *)[tabbar_ selectedViewController] reloadData];
-}
-
-- (int)indexOfTabWithTag:(int)tag {
-    int i = 0;
-    for (UINavigationController *controller in [tabbar_ viewControllers]) {
-        if ([[controller tabBarItem] tag] == tag) return i;
-        i += 1;
-    }
-
-    return -1;
-}
-
-- (void) _refreshIfPossible {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    SCNetworkReachabilityFlags flags; {
-        SCNetworkReachabilityRef reachability(SCNetworkReachabilityCreateWithName(NULL, "cydia.saurik.com"));
-        SCNetworkReachabilityGetFlags(reachability, &flags);
-        CFRelease(reachability);
-    }
-
-    // XXX: this elaborate mess is what Apple is using to determine this? :(
-    // XXX: do we care if the user has to intervene? maybe that's ok?
-    bool reachable(
-        (flags & kSCNetworkReachabilityFlagsReachable) != 0 && (
-            (flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0 || (
-                (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0 ||
-                (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0
-            ) && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0 ||
-            (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0
-        )
-    );
-
-    if (loaded_ || ManualRefresh || !reachable) loaded:
-        [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO];
-    else {
-        loaded_ = true;
-
-        NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
-
-        if (update != nil) {
-            NSTimeInterval interval([update timeIntervalSinceNow]);
-            if (interval <= 0 && interval > -(15*60))
-                goto loaded;
-        }
-
-        [container_ performSelectorOnMainThread:@selector(setUpdate:) withObject:update waitUntilDone:NO];
-    }
-
-    [pool release];
-}
-
-- (void) refreshIfPossible {
-    [NSThread detachNewThreadSelector:@selector(_refreshIfPossible) toTarget:self withObject:nil];
-}
-
-- (void) _reloadData {
-    UIProgressHUD *hud([self addProgressHUD]);
-    [hud setText:(loaded_ ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))];
-
-    [database_ yieldToSelector:@selector(reloadData) withObject:nil];
-    _trace();
-
-    [self removeProgressHUD:hud];
-
-    size_t changes(0);
-
-    [essential_ removeAllObjects];
-    [broken_ removeAllObjects];
-
-    NSArray *packages([database_ packages]);
-    for (Package *package in packages) {
-        if ([package half])
-            [broken_ addObject:package];
-        if ([package upgradableAndEssential:NO]) {
-            if ([package essential])
-                [essential_ addObject:package];
-            ++changes;
-        }
-    }
-
-    if (changes != 0) {
-        NSString *badge([[NSNumber numberWithInt:changes] stringValue]);
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:badge];
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:YES];
-
-        if ([self respondsToSelector:@selector(setApplicationBadge:)])
-            [self setApplicationBadge:badge];
-        else
-            [self setApplicationBadgeString:badge];
-    } else {
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:nil];
-        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:NO];
-
-        if ([self respondsToSelector:@selector(removeApplicationBadge)])
-            [self removeApplicationBadge];
-        else // XXX: maybe use setApplicationBadgeString also?
-            [self setApplicationIconBadgeNumber:0];
-    }
-
-    [self _updateData];
-
-    [self refreshIfPossible];
-}
-
-- (void) updateData {
-    [database_ setVisible];
-    [self _updateData];
-}
-
-- (void) update_ {
-    [database_ update];
-}
-
-- (void) syncData {
-    FILE *file(fopen("/etc/apt/sources.list.d/cydia.list", "w"));
-    _assert(file != NULL);
-
-    for (NSString *key in [Sources_ allKeys]) {
-        NSDictionary *source([Sources_ objectForKey:key]);
-
-        fprintf(file, "%s %s %s\n",
-            [[source objectForKey:@"Type"] UTF8String],
-            [[source objectForKey:@"URI"] UTF8String],
-            [[source objectForKey:@"Distribution"] UTF8String]
-        );
-    }
-
-    fclose(file);
-
-    [self _saveConfig];
-
-    ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
-    CYNavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
-    if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
-    [container_ presentModalViewController:navigation animated:YES];
-
-    [progress
-        detachNewThreadSelector:@selector(update_)
-        toTarget:self
-        withObject:nil
-        title:UCLocalize("UPDATING_SOURCES")
-    ];
-}
-
-- (void) reloadData {
-    @synchronized (self) {
-        [self _reloadData];
-    }
-}
-
-- (void) resolve {
-    pkgProblemResolver *resolver = [database_ resolver];
-
-    resolver->InstallProtect();
-    if (!resolver->Resolve(true))
-        _error->Discard();
-}
-
-- (CGRect) popUpBounds {
-    return [[tabbar_ view] bounds];
-}
-
-- (bool) perform {
-    if (![database_ prepare])
-        return false;
-
-    ConfirmationController *page([[[ConfirmationController alloc] initWithDatabase:database_] autorelease]);
-    [page setDelegate:self];
-    CYNavigationController *confirm_ = [[CYNavigationController alloc] initWithRootViewController:page];
-    [confirm_ setDelegate:self];
-
-    if (IsWildcat_) [confirm_ setModalPresentationStyle:UIModalPresentationFormSheet];
-    [container_ presentModalViewController:confirm_ animated:YES];
-
-    return true;
-}
-
-- (void) queue {
-    @synchronized (self) {
-        [self perform];
-    }
-}
-
-- (void) clearPackage:(Package *)package {
-    @synchronized (self) {
-        [package clear];
-        [self resolve];
-        [self perform];
-    }
-}
-
-- (void) installPackages:(NSArray *)packages {
-    @synchronized (self) {
-        for (Package *package in packages)
-            [package install];
-        [self resolve];
-        [self perform];
-    }
-}
-
-- (void) installPackage:(Package *)package {
-    @synchronized (self) {
-        [package install];
-        [self resolve];
-        [self perform];
-    }
-}
-
-- (void) removePackage:(Package *)package {
-    @synchronized (self) {
-        [package remove];
-        [self resolve];
-        [self perform];
-    }
-}
-
-- (void) distUpgrade {
-    @synchronized (self) {
-        if (![database_ upgrade])
-            return;
-        [self perform];
-    }
-}
-
-- (void) complete {
-    @synchronized (self) {
-        [self _reloadData];
-    }
-}
-
-- (void) confirmWithNavigationController:(UINavigationController *)navigation {
-    ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
-
-    if (navigation != nil) {
-        [navigation pushViewController:progress animated:YES];
-    } else {
-        navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
-        if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
-        [container_ presentModalViewController:navigation animated:YES];
-    }
-
-    [progress
-        detachNewThreadSelector:@selector(perform)
-        toTarget:database_
-        withObject:nil
-        title:UCLocalize("RUNNING")
-    ];
-}
-
-- (void) progressControllerIsComplete:(ProgressController *)progress {
-    [self complete];
-}
-
-- (void) setPage:(CYViewController *)page {
-    [page setDelegate:self];
-
-    CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController];
-    [navController setViewControllers:[NSArray arrayWithObject:page]];
-    for (CYNavigationController *page in [tabbar_ viewControllers]) {
-        if (page != navController) [page setViewControllers:nil];
-    }
-}
-
-- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class {
-    CYBrowserController *browser = [[[_class alloc] init] autorelease];
-    [browser loadURL:url];
-    return browser;
-}
-
-- (SectionsController *) sectionsController {
-    if (sections_ == nil)
-        sections_ = [[SectionsController alloc] initWithDatabase:database_];
-    return sections_;
-}
-
-- (ChangesController *) changesController {
-    if (changes_ == nil)
-        changes_ = [[ChangesController alloc] initWithDatabase:database_ delegate:self];
-    return changes_;
-}
-
-- (ManageController *) manageController {
-    if (manage_ == nil) {
-        manage_ = (ManageController *) [[self
-            _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]
-            withClass:[ManageController class]
-        ] retain];
-        if (!IsWildcat_) queueDelegate_ = manage_;
-    }
-    return manage_;
-}
-
-- (SearchController *) searchController {
-    if (search_ == nil)
-        search_ = [[SearchController alloc] initWithDatabase:database_];
-    return search_;
-}
-
-- (SourceTable *) sourcesController {
-    if (sources_ == nil)
-        sources_ = [[SourceTable alloc] initWithDatabase:database_];
-    return sources_;
-}
-
-- (InstalledController *) installedController {
-    if (installed_ == nil) {
-        installed_ = [[InstalledController alloc] initWithDatabase:database_];
-        if (IsWildcat_) queueDelegate_ = installed_;
-    }
-    return installed_;
-}
-
-- (void) tabBarController:(id)tabBarController didSelectViewController:(UIViewController *)viewController {
-    int tag = [[viewController tabBarItem] tag];
-    if (tag == tag_) {
-        [(CYNavigationController *)[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES];
-        return;
-    } else if (tag_ == 1) {
-        [[self sectionsController] resetView];
-    }
-
-    switch (tag) {
-        case kCydiaTag: _setHomePage(self); break;
-
-        case kSectionsTag: [self setPage:[self sectionsController]]; break;
-        case kChangesTag: [self setPage:[self changesController]]; break;
-        case kManageTag: [self setPage:[self manageController]]; break;
-        case kInstalledTag: [self setPage:[self installedController]]; break;
-        case kSourcesTag: [self setPage:[self sourcesController]]; break;
-        case kSearchTag: [self setPage:[self searchController]]; break;
-
-        _nodefault
-    }
-
-    tag_ = tag;
-}
-
-- (void) showSettings {
-    RoleController *role = [[RoleController alloc] initWithDatabase:database_ delegate:self];
-    CYNavigationController *nav = [[CYNavigationController alloc] initWithRootViewController:role];
-    if (IsWildcat_) [nav setModalPresentationStyle:UIModalPresentationFormSheet];
-    [container_ presentModalViewController:nav animated:YES];
-}
-
-- (void) setPackageController:(PackageController *)view {
-    WebThreadLock();
-    [view setPackage:nil];
-#if RecyclePackageViews
-    if ([details_ count] < 3)
-        [details_ addObject:view];
-#endif
-    WebThreadUnlock();
-}
-
-- (PackageController *) _packageController {
-    return [[[PackageController alloc] initWithDatabase:database_] autorelease];
-}
-
-- (PackageController *) packageController {
-#if RecyclePackageViews
-    PackageController *view;
-    size_t count([details_ count]);
-
-    if (count == 0) {
-        view = [self _packageController];
-      renew:
-        [details_ addObject:[self _packageController]];
-    } else {
-        view = [[[details_ lastObject] retain] autorelease];
-        [details_ removeLastObject];
-        if (count == 1)
-            goto renew;
-    }
-
-    return view;
-#else
-    return [self _packageController];
-#endif
-}
-
-// Returns the navigation controller for the queuing badge.
-- (id) queueBadgeController {
-    int index = [self indexOfTabWithTag:kManageTag];
-    if (index == -1) index = [self indexOfTabWithTag:kInstalledTag];
-
-    return [[tabbar_ viewControllers] objectAtIndex:index];
-}
-
-- (void) cancelAndClear:(bool)clear {
-    @synchronized (self) {
-        if (clear) {
-            // Clear all marks.
-            pkgCacheFile &cache([database_ cache]);
-            for (pkgCache::PkgIterator iterator = cache->PkgBegin(); !iterator.end(); ++iterator) {
-                // Unmark method taken from Synaptic Package Manager.
-                // Thanks for being sane, unlike Aptitude.
-                if (!cache[iterator].Keep()) {
-                    cache->MarkKeep(iterator, false);
-                    cache->SetReInstall(iterator, false);
-                }
-            }
-
-            // Stop queuing.
-            Queuing_ = false;
-            [[[self queueBadgeController] tabBarItem] setBadgeValue:nil];
-        } else {
-            // Start queuing.
-            Queuing_ = true;
-            [[[self queueBadgeController] tabBarItem] setBadgeValue:UCLocalize("Q_D")];
-        }
-
-        // Show the changes in the current view.
-        [(CYNavigationController *) [tabbar_ selectedViewController] reloadData];
-        [queueDelegate_ queueStatusDidChange];
-    }
-}
-
-- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
-    NSString *context([alert context]);
-
-    if ([context isEqualToString:@"fixhalf"]) {
-        if (button == [alert firstOtherButtonIndex]) {
-            @synchronized (self) {
-                for (Package *broken in broken_) {
-                    [broken remove];
-
-                    NSString *id = [broken id];
-                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
-                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
-                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
-                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
-                }
-
-                [self resolve];
-                [self perform];
-            }
-        } else if (button == [alert cancelButtonIndex]) {
-            [broken_ removeAllObjects];
-            [self _loaded];
-        }
-
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    } else if ([context isEqualToString:@"upgrade"]) {
-        if (button == [alert firstOtherButtonIndex]) {
-            @synchronized (self) {
-                for (Package *essential in essential_)
-                    [essential install];
-
-                [self resolve];
-                [self perform];
-            }
-        } else if (button == [alert firstOtherButtonIndex] + 1) {
-            [self distUpgrade];
-        } else if (button == [alert cancelButtonIndex]) {
-            Ignored_ = YES;
-        }
-
-        [alert dismissWithClickedButtonIndex:-1 animated:YES];
-    }
-}
-
-- (void) system:(NSString *)command { _pooled
-    system([command UTF8String]);
-}
-
-- (void) applicationWillSuspend {
-    [database_ clean];
-    [super applicationWillSuspend];
-}
-
-- (void) applicationSuspend:(__GSEvent *)event {
-    // FIXME: This needs to be fixed, but we no longer have a progress_.
-    //        What's the best solution?
-    if (hud_ == nil)// && ![progress_ isRunning])
-        [super applicationSuspend:event];
-}
-
-- (void) _animateSuspension:(BOOL)arg0 duration:(double)arg1 startTime:(double)arg2 scale:(float)arg3 {
-    if (hud_ == nil)
-        [super _animateSuspension:arg0 duration:arg1 startTime:arg2 scale:arg3];
-}
-
-- (void) _setSuspended:(BOOL)value {
-    if (hud_ == nil)
-        [super _setSuspended:value];
-}
-
-- (UIProgressHUD *) addProgressHUD {
-    UIProgressHUD *hud([[[UIProgressHUD alloc] initWithWindow:window_] autorelease]);
-    [hud setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
-
-    [window_ setUserInteractionEnabled:NO];
-    [hud show:YES];
-    [[container_ view] addSubview:hud];
-    return hud;
-}
-
-- (void) removeProgressHUD:(UIProgressHUD *)hud {
-    [hud show:NO];
-    [hud removeFromSuperview];
-    [window_ setUserInteractionEnabled:YES];
-}
-
-- (CYViewController *) pageForPackage:(NSString *)name {
-    if (Package *package = [database_ packageWithName:name]) {
-        PackageController *view([self packageController]);
-        [view setPackage:package];
-        return view;
-    } else {
-        NSURL *url([NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"unknown" ofType:@"html"]]);
-        url = [NSURL URLWithString:[[url absoluteString] stringByAppendingString:[NSString stringWithFormat:@"?%@", name]]];
-        return [self _pageForURL:url withClass:[CYBrowserController class]];
-    }
-}
-
-- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
-    if (tag != NULL)
-        *tag = -1;
-
-    NSString *href([url absoluteString]);
-    if ([href hasPrefix:@"apptapp://package/"])
-        return [self pageForPackage:[href substringFromIndex:18]];
-
-    NSString *scheme([[url scheme] lowercaseString]);
-    if (![scheme isEqualToString:@"cydia"])
-        return nil;
-    NSString *path([url absoluteString]);
-    if ([path length] < 8)
-        return nil;
-    path = [path substringFromIndex:8];
-    if (![path hasPrefix:@"/"])
-        path = [@"/" stringByAppendingString:path];
-
-    if ([path isEqualToString:@"/add-source"])
-        return [[[AddSourceController alloc] initWithDatabase:database_] autorelease];
-    else if ([path isEqualToString:@"/storage"])
-        return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[CYBrowserController class]];
-    else if ([path isEqualToString:@"/sources"])
-        return [[[SourceTable alloc] initWithDatabase:database_] autorelease];
-    else if ([path isEqualToString:@"/packages"])
-        return [[[InstalledController alloc] initWithDatabase:database_] autorelease];
-    else if ([path hasPrefix:@"/url/"])
-        return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[CYBrowserController class]];
-    else if ([path hasPrefix:@"/launch/"])
-        [self launchApplicationWithIdentifier:[path substringFromIndex:8] suspended:NO];
-    else if ([path hasPrefix:@"/package-settings/"])
-        return [[[SettingsController alloc] initWithDatabase:database_ package:[path substringFromIndex:18]] autorelease];
-    else if ([path hasPrefix:@"/package-signature/"])
-        return [[[SignatureController alloc] initWithDatabase:database_ package:[path substringFromIndex:19]] autorelease];
-    else if ([path hasPrefix:@"/package/"])
-        return [self pageForPackage:[path substringFromIndex:9]];
-    else if ([path hasPrefix:@"/files/"]) {
-        NSString *name = [path substringFromIndex:7];
-
-        if (Package *package = [database_ packageWithName:name]) {
-            FileTable *files = [[[FileTable alloc] initWithDatabase:database_] autorelease];
-            [files setPackage:package];
-            return files;
-        }
-    }
-
-    return nil;
-}
-
-- (void) applicationOpenURL:(NSURL *)url {
-    [super applicationOpenURL:url];
-    int tag;
-    if (CYViewController *page = [self pageForURL:url hasTag:&tag]) {
-        [self setPage:page];
-        tag_ = tag;
-        [tabbar_ setSelectedViewController:(tag_ == -1 ? nil : [[tabbar_ viewControllers] objectAtIndex:tag_])];
-    }
-}
-
-- (void) applicationWillResignActive:(UIApplication *)application {
-    // Stop refreshing if you get a phone call or lock the device.
-    if ([container_ updating]) [container_ cancelUpdate];
-
-    if ([[self superclass] instancesRespondToSelector:@selector(applicationWillResignActive:)])
-        [super applicationWillResignActive:application];
-}
-
-- (void) applicationDidFinishLaunching:(id)unused {
-    [CYBrowserController _initialize];
-
-    [NSURLProtocol registerClass:[CydiaURLProtocol class]];
-
-    Font12_ = [[UIFont systemFontOfSize:12] retain];
-    Font12Bold_ = [[UIFont boldSystemFontOfSize:12] retain];
-    Font14_ = [[UIFont systemFontOfSize:14] retain];
-    Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
-    Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
-
-    tag_ = 0;
-
-    essential_ = [[NSMutableArray alloc] initWithCapacity:4];
-    broken_ = [[NSMutableArray alloc] initWithCapacity:4];
-
-    UIScreen *screen([UIScreen mainScreen]);
-
-    window_ = [[UIWindow alloc] initWithFrame:[screen bounds]];
-    [window_ orderFront:self];
-    [window_ makeKey:self];
-    [window_ setHidden:NO];
-
-    database_ = [Database sharedInstance];
-
-    if (
-        readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
-        //readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL ||
-        //readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL ||
-        false
-    ) {
-        [self setIdleTimerDisabled:YES];
-
-        hud_ = [self addProgressHUD];
-        [hud_ setText:@"Reorganizing:\n\nWill Automatically\nClose When Done"];
-        [self setStatusBarShowsProgress:YES];
-
-        [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
-
-        [self setStatusBarShowsProgress:NO];
-        [self removeProgressHUD:hud_];
-        hud_ = nil;
-
-        if (ExecFork() == 0) {
-            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
-            perror("launchctl stop");
-        }
-
-        return;
-    }
-
-    _trace();
-
-    NSMutableArray *items([NSMutableArray arrayWithObjects:
-        [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:kCydiaTag] autorelease],
-        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:kSectionsTag] autorelease],
-        [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:kChangesTag] autorelease],
-        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:kSearchTag] autorelease],
-    nil]);
-
-    if (IsWildcat_) {
-        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source.png"] tag:kSourcesTag] autorelease] atIndex:3];
-        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:kInstalledTag] autorelease] atIndex:3];
-    } else {
-        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:kManageTag] autorelease] atIndex:3];
-    }
-
-    NSMutableArray *controllers([NSMutableArray array]);
-
-    for (UITabBarItem *item in items) {
-        CYNavigationController *controller([[[CYNavigationController alloc] initWithDatabase:database_] autorelease]);
-        [controller setTabBarItem:item];
-        [controllers addObject:controller];
-    }
-
-    tabbar_ = [[CYTabBarController alloc] initWithDatabase:database_];
-    [tabbar_ setViewControllers:controllers];
-    [tabbar_ setDelegate:self];
-    [tabbar_ setSelectedIndex:0];
-
-    container_ = [[CYContainer alloc] initWithDatabase:database_];
-    [container_ setUpdateDelegate:self];
-    [container_ setTabBarController:tabbar_];
-    [window_ addSubview:[container_ view]];
-
-    [self performSelector:@selector(loadData) withObject:nil afterDelay:0];
-}
-
-- (void) loadData {
-    if (Role_ == nil) {
-        [self showSettings];
-        return;
-    }
-
-    [UIKeyboard initImplementationNow];
-
-    [self reloadData];
-
-#if RecyclePackageViews
-    details_ = [[NSMutableArray alloc] initWithCapacity:4];
-    [details_ addObject:[self _packageController]];
-    [details_ addObject:[self _packageController]];
-#endif
-
-    PrintTimes();
-
-    _setHomePage(self);
-}
-
-- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item {
-    if (item != nil && IsWildcat_) {
-        [sheet showFromBarButtonItem:item animated:YES];
-    } else {
-        [sheet showInView:window_];
-    }
-}
-
-@end
-
-/*IMP alloc_;
-id Alloc_(id self, SEL selector) {
-    id object = alloc_(self, selector);
-    lprintf("[%s]A-%p\n", self->isa->name, object);
-    return object;
-}*/
-
-/*IMP dealloc_;
-id Dealloc_(id self, SEL selector) {
-    id object = dealloc_(self, selector);
-    lprintf("[%s]D-%p\n", self->isa->name, object);
-    return object;
-}*/
-
-Class $WebDefaultUIKitDelegate;
-
-MSHook(void, UIWebDocumentView$_setUIKitDelegate$, UIWebDocumentView *self, SEL _cmd, id delegate) {
-    if (delegate == nil && $WebDefaultUIKitDelegate != nil)
-        delegate = [$WebDefaultUIKitDelegate sharedUIKitDelegate];
-    return _UIWebDocumentView$_setUIKitDelegate$(self, _cmd, delegate);
-}
-
-static NSNumber *shouldPlayKeyboardSounds;
-
-Class $UIHardware;
-
-MSHook(void, UIHardware$_playSystemSound$, Class self, SEL _cmd, int sound) {
-    switch (sound) {
-        case 1104: // Keyboard Button Clicked
-        case 1105: // Keyboard Delete Repeated
-            if (shouldPlayKeyboardSounds == nil) {
-                NSDictionary *dict([[[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.apple.preferences.sounds.plist"] autorelease]);
-                shouldPlayKeyboardSounds = [([dict objectForKey:@"keyboard"] ?: (id) kCFBooleanTrue) retain];
-            }
-
-            if (![shouldPlayKeyboardSounds boolValue])
-                break;
-
-        default:
-            _UIHardware$_playSystemSound$(self, _cmd, sound);
-    }
-}
-
-int main(int argc, char *argv[]) { _pooled
-    _trace();
-
-    if (Class $UIDevice = objc_getClass("UIDevice")) {
-        UIDevice *device([$UIDevice currentDevice]);
-        IsWildcat_ = [device respondsToSelector:@selector(isWildcat)] && [device isWildcat];
-    } else
-        IsWildcat_ = false;
-
-    PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
-
-    /* Library Hacks {{{ */
-    class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
-
-    $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate");
-    Method UIWebDocumentView$_setUIKitDelegate$(class_getInstanceMethod([WebView class], @selector(_setUIKitDelegate:)));
-    if (UIWebDocumentView$_setUIKitDelegate$ != NULL) {
-        _UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast<void (*)(UIWebDocumentView *, SEL, id)>(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$));
-        method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
-    }
-
-    $UIHardware = objc_getClass("UIHardware");
-    Method UIHardware$_playSystemSound$(class_getClassMethod($UIHardware, @selector(_playSystemSound:)));
-    if (UIHardware$_playSystemSound$ != NULL) {
-        _UIHardware$_playSystemSound$ = reinterpret_cast<void (*)(Class, SEL, int)>(method_getImplementation(UIHardware$_playSystemSound$));
-        method_setImplementation(UIHardware$_playSystemSound$, reinterpret_cast<IMP>(&$UIHardware$_playSystemSound$));
-    }
-    /* }}} */
-    /* Set Locale {{{ */
-    Locale_ = CFLocaleCopyCurrent();
-    Languages_ = [NSLocale preferredLanguages];
-    //CFStringRef locale(CFLocaleGetIdentifier(Locale_));
-    //NSLog(@"%@", [Languages_ description]);
-
-    const char *lang;
-    if (Languages_ == nil || [Languages_ count] == 0)
-        // XXX: consider just setting to C and then falling through?
-        lang = NULL;
-    else {
-        lang = [[Languages_ objectAtIndex:0] UTF8String];
-        setenv("LANG", lang, true);
-    }
-
-    //std::setlocale(LC_ALL, lang);
-    NSLog(@"Setting Language: %s", lang);
-    /* }}} */
-
-    apr_app_initialize(&argc, const_cast<const char * const **>(&argv), NULL);
-
-    /* Parse Arguments {{{ */
-    bool substrate(false);
-
-    if (argc != 0) {
-        char **args(argv);
-        int arge(1);
-
-        for (int argi(1); argi != argc; ++argi)
-            if (strcmp(argv[argi], "--") == 0) {
-                arge = argi;
-                argv[argi] = argv[0];
-                argv += argi;
-                argc -= argi;
-                break;
-            }
-
-        for (int argi(1); argi != arge; ++argi)
-            if (strcmp(args[argi], "--substrate") == 0)
-                substrate = true;
-            else
-                fprintf(stderr, "unknown argument: %s\n", args[argi]);
-    }
-    /* }}} */
-
-    App_ = [[NSBundle mainBundle] bundlePath];
-    Home_ = NSHomeDirectory();
-    Advanced_ = YES;
-
-    setuid(0);
-    setgid(0);
-
-    /*Method alloc = class_getClassMethod([NSObject class], @selector(alloc));
-    alloc_ = alloc->method_imp;
-    alloc->method_imp = (IMP) &Alloc_;*/
-
-    /*Method dealloc = class_getClassMethod([NSObject class], @selector(dealloc));
-    dealloc_ = dealloc->method_imp;
-    dealloc->method_imp = (IMP) &Dealloc_;*/
-
-    /* System Information {{{ */
-    size_t size;
-
-    int maxproc;
-    size = sizeof(maxproc);
-    if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1)
-        perror("sysctlbyname(\"kern.maxproc\", ?)");
-    else if (maxproc < 64) {
-        maxproc = 64;
-        if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc, sizeof(maxproc)) == -1)
-            perror("sysctlbyname(\"kern.maxproc\", #)");
-    }
-
-    sysctlbyname("kern.osversion", NULL, &size, NULL, 0);
-    char *osversion = new char[size];
-    if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) == -1)
-        perror("sysctlbyname(\"kern.osversion\", ?)");
-    else
-        System_ = [NSString stringWithUTF8String:osversion];
-
-    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
-    char *machine = new char[size];
-    if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1)
-        perror("sysctlbyname(\"hw.machine\", ?)");
-    else
-        Machine_ = machine;
-
-    if (CFMutableDictionaryRef dict = IOServiceMatching("IOPlatformExpertDevice")) {
-        if (io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, dict)) {
-            if (CFTypeRef serial = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)) {
-                SerialNumber_ = [NSString stringWithString:(NSString *)serial];
-                CFRelease(serial);
-            }
-
-            if (CFTypeRef ecid = IORegistryEntrySearchCFProperty(service, kIODeviceTreePlane, CFSTR("unique-chip-id"), kCFAllocatorDefault, kIORegistryIterateRecursively)) {
-                NSData *data((NSData *) ecid);
-                size_t length([data length]);
-                uint8_t bytes[length];
-                [data getBytes:bytes];
-                char string[length * 2 + 1];
-                for (size_t i(0); i != length; ++i)
-                    sprintf(string + i * 2, "%.2X", bytes[length - i - 1]);
-                ChipID_ = [NSString stringWithUTF8String:string];
-                CFRelease(ecid);
-            }
-
-            IOObjectRelease(service);
-        }
-    }
-
-    UniqueID_ = [[UIDevice currentDevice] uniqueIdentifier];
-
-    if (NSDictionary *system = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"])
-        Build_ = [system objectForKey:@"ProductBuildVersion"];
-    if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:@"/Applications/MobileSafari.app/Info.plist"]) {
-        Product_ = [info objectForKey:@"SafariProductVersion"];
-        Safari_ = [info objectForKey:@"CFBundleVersion"];
-    }
-    /* }}} */
-    /* Load Database {{{ */
-    _trace();
-    Metadata_ = [[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease];
-    _trace();
-    SectionMap_ = [[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Sections" ofType:@"plist"]] autorelease];
-    _trace();
-
-    if (Metadata_ == NULL)
-        Metadata_ = [NSMutableDictionary dictionaryWithCapacity:2];
-    else {
-        Settings_ = [Metadata_ objectForKey:@"Settings"];
-
-        Packages_ = [Metadata_ objectForKey:@"Packages"];
-        Sections_ = [Metadata_ objectForKey:@"Sections"];
-        Sources_ = [Metadata_ objectForKey:@"Sources"];
-
-        Token_ = [Metadata_ objectForKey:@"Token"];
-    }
-
-    if (Settings_ != nil)
-        Role_ = [Settings_ objectForKey:@"Role"];
-
-    if (Packages_ == nil) {
-        Packages_ = [[[NSMutableDictionary alloc] initWithCapacity:128] autorelease];
-        [Metadata_ setObject:Packages_ forKey:@"Packages"];
-    }
-
-    if (Sections_ == nil) {
-        Sections_ = [[[NSMutableDictionary alloc] initWithCapacity:32] autorelease];
-        [Metadata_ setObject:Sections_ forKey:@"Sections"];
-    }
-
-    if (Sources_ == nil) {
-        Sources_ = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
-        [Metadata_ setObject:Sources_ forKey:@"Sources"];
-    }
-    /* }}} */
-
-#if RecycleWebViews
-    Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease];
-#endif
-
-    Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
-
-    if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", F_OK) == 0)
-        dlopen("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", RTLD_LAZY | RTLD_GLOBAL);
-    if (substrate && access("/Applications/WinterBoard.app/WinterBoard.dylib", F_OK) == 0)
-        dlopen("/Applications/WinterBoard.app/WinterBoard.dylib", RTLD_LAZY | RTLD_GLOBAL);
-    /*if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0)
-        dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL);*/
-
-    int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]);
-
-    if (access("/tmp/.cydia.fw", F_OK) == 0) {
-        unlink("/tmp/.cydia.fw");
-        goto firmware;
-    } else if (access("/User", F_OK) != 0 || version < 2) {
-      firmware:
-        _trace();
-        system("/usr/libexec/cydia/firmware.sh");
-        _trace();
-    }
-
-    _assert([[NSFileManager defaultManager]
-        createDirectoryAtPath:@"/var/cache/apt/archives/partial"
-        withIntermediateDirectories:YES
-        attributes:nil
-        error:NULL
-    ]);
-
-    if (access("/tmp/cydia.chk", F_OK) == 0) {
-        if (unlink("/var/cache/apt/pkgcache.bin") == -1)
-            _assert(errno == ENOENT);
-        if (unlink("/var/cache/apt/srcpkgcache.bin") == -1)
-            _assert(errno == ENOENT);
-    }
-
-    /* APT Initialization {{{ */
-    _assert(pkgInitConfig(*_config));
-    _assert(pkgInitSystem(*_config, _system));
-
-    if (lang != NULL)
-        _config->Set("APT::Acquire::Translation", lang);
-    _config->Set("Acquire::http::Timeout", 15);
-    _config->Set("Acquire::http::MaxParallel", 3);
-    /* }}} */
-    /* Color Choices {{{ */
-    space_ = CGColorSpaceCreateDeviceRGB();
-
-    Blue_.Set(space_, 0.2, 0.2, 1.0, 1.0);
-    Blueish_.Set(space_, 0x19/255.f, 0x32/255.f, 0x50/255.f, 1.0);
-    Black_.Set(space_, 0.0, 0.0, 0.0, 1.0);
-    Off_.Set(space_, 0.9, 0.9, 0.9, 1.0);
-    White_.Set(space_, 1.0, 1.0, 1.0, 1.0);
-    Gray_.Set(space_, 0.4, 0.4, 0.4, 1.0);
-    Green_.Set(space_, 0.0, 0.5, 0.0, 1.0);
-    Purple_.Set(space_, 0.0, 0.0, 0.7, 1.0);
-    Purplish_.Set(space_, 0.4, 0.4, 0.8, 1.0);
-
-    InstallingColor_ = [UIColor colorWithRed:0.88f green:1.00f blue:0.88f alpha:1.00f];
-    RemovingColor_ = [UIColor colorWithRed:1.00f green:0.88f blue:0.88f alpha:1.00f];
-    /* }}}*/
-    /* UIKit Configuration {{{ */
-    void (*$GSFontSetUseLegacyFontMetrics)(BOOL)(reinterpret_cast<void (*)(BOOL)>(dlsym(RTLD_DEFAULT, "GSFontSetUseLegacyFontMetrics")));
-    if ($GSFontSetUseLegacyFontMetrics != NULL)
-        $GSFontSetUseLegacyFontMetrics(YES);
-
-    // XXX: I have a feeling this was important
-    //UIKeyboardDisableAutomaticAppearance();
-    /* }}} */
-
-    Colon_ = UCLocalize("COLON_DELIMITED");
-    Error_ = UCLocalize("ERROR");
-    Warning_ = UCLocalize("WARNING");
-
-    _trace();
-    int value(UIApplicationMain(argc, argv, @"Cydia", @"Cydia"));
-
-    CGColorSpaceRelease(space_);
-    CFRelease(Locale_);
-
-    return value;
-}
diff --git a/CydiaAppliance.mm b/CydiaAppliance.mm
new file mode 100644 (file)
index 0000000..8214617
--- /dev/null
@@ -0,0 +1,67 @@
+#import <BackRow/BRAppliance.h>
+#import <BackRow/BRApplianceCategory.h>
+#import <BackRow/BRBaseAppliance.h>
+#import <BackRow/BRTopShelfController.h>
+#import <BackRow/BRTopShelfView.h>
+#import <BackRow/BRViewController.h>
+
+@interface CydiaTopShelfController : NSObject <BRTopShelfController> {
+    BRTopShelfView *view_;
+}
+
+@end
+
+@implementation CydiaTopShelfController
+
+- (void) dealloc {
+    [view_ release];
+
+    [super dealloc];
+}
+
+- (BRTopShelfView *) topShelfView {
+    return view_;
+}
+
+- (void) selectCategoryWithIdentifier:(NSString *)identifier {
+}
+
+@end
+
+
+@interface CydiaManageViewController : BRViewController {
+}
+@end
+
+@implementation CydiaManageViewController
+@end
+
+
+@interface CydiaAppliance : BRBaseAppliance {
+}
+@end
+
+@implementation CydiaAppliance
+
+- (id) applianceCategories {
+    return [NSArray arrayWithObjects:
+        [BRApplianceCategory categoryWithName:@"Install" identifier:@"cydia-install" preferredOrder:0],
+        [BRApplianceCategory categoryWithName:@"Manage" identifier:@"cydia-manage" preferredOrder:0],
+        [BRApplianceCategory categoryWithName:@"Search" identifier:@"cydia-search" preferredOrder:0],
+    nil];
+}
+
+- (id) controllerForIdentifier:(NSString *)identifier args:(NSDictionary *)args {
+    return nil;
+}
+
+- (id) topShelfController {
+    return [[[CydiaTopShelfController alloc] init] autorelease];
+}
+
+- (int) noContentBRError {
+    // XXX: research
+    return 0;
+}
+
+@end
diff --git a/MobileCydia.app/Cydia b/MobileCydia.app/Cydia
new file mode 100755 (executable)
index 0000000..572af7b
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+C=/${0}
+C=${C%/*}
+declare -a flags
+[[ :${DYLD_INSERT_LIBRARIES}: == */MobileSubstrate.dylib: ]] && flags[${#flags[@]}]=--substrate
+exec "${C:-.}"/MobileCydia "${flags[@]}" -- "$@" 2>>/tmp/cydia.log
diff --git a/MobileCydia.app/Default-Portrait.png b/MobileCydia.app/Default-Portrait.png
new file mode 100644 (file)
index 0000000..c24b27e
Binary files /dev/null and b/MobileCydia.app/Default-Portrait.png differ
diff --git a/MobileCydia.app/Default.png b/MobileCydia.app/Default.png
new file mode 100644 (file)
index 0000000..b85286b
Binary files /dev/null and b/MobileCydia.app/Default.png differ
diff --git a/MobileCydia.app/Default@2x.png b/MobileCydia.app/Default@2x.png
new file mode 100644 (file)
index 0000000..abc651b
Binary files /dev/null and b/MobileCydia.app/Default@2x.png differ
diff --git a/MobileCydia.app/English.lproj/Localizable.strings b/MobileCydia.app/English.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..80ff0be
--- /dev/null
@@ -0,0 +1,210 @@
+"ABOUT" = "About";
+"ABOUT_CYDIA" = "About Cydia Installer";
+"ACCEPT_NEW_COPY" = "Accept The New Copy";
+"ADD" = "Add";
+"ADD_ANYWAY" = "Add Anyway";
+"ADD_SOURCE" = "Add Source";
+"ADMINISTRATIVE_INFORMATION" = "Administrative Information";
+"ADVANCED_SEARCH" = "Advanced Search";
+"ALL_PACKAGES" = "All Packages";
+"APPLE" = "Apple";
+"AUTHOR" = "Author";
+"AVAILABLE_UPGRADES" = "Available Upgrades";
+"BROWSER" = "Browser";
+"BY" = "by %@";
+"CANCEL" = "Cancel";
+"CANCEL_CLEAR" = "Cancel and Clear";
+"CANCEL_OPERATION" = "Cancel Operation";
+"CANNOT_COMPLY" = "Cannot Comply";
+"CANNOT_COMPLY_EX" = "The requested modifications cannot be applied due to required dependencies or conflicts that cannot be automatically found or fixed.";
+"CANNOT_LOCATE_PACKAGE" = "Cannot Locate Package";
+"CHANGE_PACKAGE_SETTINGS" = "Change Package Settings";
+"CHANGES" = "Changes";
+"CLEAN_ARCHIVES" = "Clean Archives";
+"CLEAR" = "Clear";
+"CLOSE" = "Close";
+"CLOSE_CYDIA" = "Close Cydia (Restart)";
+"COLON_DELIMITED" = "%@: %@";
+"COMMA_DELIMITED" = "%@, %@";
+"COMING_SOON" = "Coming Soon!";
+"COMPLETE" = "Complete";
+"COMPLETE_UPGRADE" = "Complete Upgrade";
+"CONFIGURATION_UPGRADE" = "Configuration Upgrade";
+"CONFIGURATION_UPGRADE_EX" = "The following file has been changed by both the package maintainer and by you (or for you by a script).";
+"COMMERCIAL_APPLICATIONS" = "Commercial Applications";
+"CONFIRM" = "Confirm";
+"CONSOLE_PACKAGE" = "This is a console package!";
+"CONSOLE_UTILITIES_DAEMONS" = "Console Utilities & Daemons";
+"CONTINUE_QUEUING" = "Continue Queuing";
+"COUNTS_NONZERO_EX" = "So, I just counted some important-looking values, and they didn't sum to zero. This is scary. I don't know why I don't like this anymore, but I think APT was adamant this should not occur.";
+"CREDITS" = "Credits";
+"CYDIA_STORE" = "Cydia Store";
+"DATABASE" = "Database";
+"DETAILS" = "Details";
+"DEVELOPER" = "Developer";
+"DEVELOPER_EX" = "Everything, even scary internal stuff.";
+"DEVELOPERS_ONLY" = "Developers Only";
+"DISK_FREEING" = "Disk Freeing";
+"DISK_USING" = "Disk Using";
+"DONATE_USING" = "Donate using %@";
+"DONE" = "Done";
+"DOUBLE_QUOTED" = "“%@”";
+"DOWNGRADE" = "Downgrade";
+"DOWNLOADING" = "Downloading";
+"DOWNLOADING_" = "Downloading %@";
+"EDIT" = "Edit";
+"ENTER_APT_URL" = "Enter Cydia/APT URL";
+"ENTERED_BY_USER" = "Entered by User";
+"ERROR" = "Error";
+"ESSENTIAL_UPGRADE" = "Essential Upgrade";
+"ESSENTIAL_UPGRADES" = "%d Essential Upgrades";
+"ESSENTIAL_UPGRADE_EX" = "One or more essential packages are currently out of date. If these upgrades are not performed you are likely to encounter errors.";
+"EXCLAMATION" = "%@!";
+"EXPANDED_SIZE" = "Expanded Size";
+"EXPERT" = "Expert";
+"FEATURED_PACKAGES" = "Featured Packages";
+"FAQ" = "FAQ";
+"FILES" = "Files";
+"FILES_INSTALLED_TO" = "files installed to %@";
+"FILESYSTEM_CONTENT" = "Filesystem Content";
+"FOLLOW_ON_TWITTER" = "Follow %@ on Twitter";
+"FORCE_REMOVAL" = "Force Removal";
+"FORCIBLY_CLEAR" = "Forcibly Clear";
+"FREE_APPLICATIONS" = "Free Applications";
+"FREE_EXTENSIONS" = "Free Extensions";
+"FREQUENTLY_ASKED_QUESTIONS" = "Frequently Asked Questions";
+"FROM" = "from %@";
+"FROWNY_PANTS" = "Frowny Pants";
+"FUTURE_FEATURE_ROADMAP" = "Future Feature Roadmap";
+"HACKER" = "Hacker";
+"HACKER_EX" = "Adds Command Line tools.";
+"HALFINSTALLED_PACKAGE" = "Half-Installed Package";
+"HALFINSTALLED_PACKAGES" = "%d Half-Installed Packages";
+"HALFINSTALLED_PACKAGE_EX" = "When the shell scripts associated with packages fail, they are left in a bad state known as either half-configured or half-installed. These errors don't go away and instead continue to cause issues. These scripts can be deleted and the packages forcibly removed.";
+"HOME" = "Home";
+"ID" = "ID";
+"IGNORE_UPGRADES" = "Ignore Upgrades";
+"IGNORED_UPGRADES" = "Ignored Upgrades";
+"ILLEGAL_PACKAGE_IDENTIFIER" = "Illegal Package Identifier";
+"INSTALL" = "Install";
+"INSTALLED" = "Installed";
+"INSTALLED_BY_PACKAGE" = "Installed by Package";
+"INSTALLED_DETAILS" = "Installed Package";
+"INSTALLED_FILES" = "Installed Files";
+"KEEP_OLD_COPY" = "Keep My Old Copy";
+"LOADING" = "Loading";
+"LOADING_DATA" = "Loading Data";
+"LOCAL" = "Local";
+"LOGIN" = "Login";
+"MAILING_LISTS" = "Mailing Lists";
+"MAINTAINER" = "Contact";
+"MANAGE" = "Manage";
+"MODIFICATIONS" = "Modifications";
+"MODIFY" = "Modify";
+"MORE_INFORMATION" = "More Information";
+"MORE_PACKAGE_SOURCES" = "More Package Sources";
+"NAME" = "Name";
+"NETWORK_ERROR" = "Network Error";
+"NEVER_OR_UNKNOWN" = "Never or Unknown";
+"NEW" = "New";
+"NEW_AT" = "New at %@";
+"NEW_INSTALL" = "New Install";
+"NO" = "No";
+"NO_SECTION" = "(No Section)";
+"NOT_RATED" = "Not Rated";
+"NOTE" = "Note";
+"NOT_REPOSITORY" = "Did not Find Repository";
+"NOT_REPOSITORY_EX" = "The indicated repository could not be found. This could be because you are trying to add a legacy Installer repository (these are not supported). Also, this interface is only capable of working with exact repository URLs. If you host a repository and are having issues please contact the author of Cydia with any questions you have.";
+"OK" = "OK";
+"OKAY" = "Okay";
+"PACKAGE_CANNOT_BE_FOUND" = "The package %@ cannot be found in your current sources. I might recommend installing more sources.";
+"PACKAGE_CANNOT_BE_FOUND_EX" = "This issue may also be caused by a number of other factors. The most common one is that your package catalog is out of date. To manually refresh, click the Refresh button on the Changes tab. This package may simply no longer exist. It is also possible you are using an old firmware version: users should attempt to remain reasonably up to date with Apple's firmware releases.";
+"PACKAGE_DAMAGED" = "Package Damaged";
+"PACKAGE_DETAILS" = "Package Details";
+"PACKAGE_QUEUE" = "Package Queue";
+"PACKAGES" = "Packages";
+"PACKAGES_EX" = "View or remove packages you previously installed.";
+"PARENTHETICAL" = "%@ (%@)";
+"PASSWORD" = "password";
+"PERFORM_SELECTIONS" = "Perform Selections";
+"PREPARE_ARCHIVES" = "Prepare Archives";
+"PRODUCTS" = "Products";
+"PURGE" = "Purge";
+"Q_D" = "Q'd";
+"QUEUED_FOR" = "Queued for %@";
+"QUESTION" = "%@?";
+"REBOOT_DEVICE" = "Reboot Device";
+"RECENT_CHANGES_UPDATES" = "Recent Changes/Updates";
+"RECOMMENDED_BOOKS" = "Recommended Books";
+"REFRESH" = "Refresh";
+"REFRESHING_DATA" = "Refreshing Data";
+"REINSTALL" = "Reinstall";
+"RELOAD" = "Reload";
+"RELOAD_SPRINGBOARD" = "Reload SpringBoard";
+"RELOADING_DATA" = "Reloading Data";
+"REMOVE" = "Remove";
+"REMOVING_ESSENTIALS" = "Removing Essentials";
+"REMOVING_ESSENTIALS_EX" = "This operation involves the removal of one or more packages that are required for the continued operation of either Cydia or iPhoneOS. If you continue, you may not be able to use Cydia to repair any damage.";
+"REPAIRING" = "Repairing";
+"REPOSITORY_SIGNATURE" = "View Repository Signature";
+"REQUEST_ADVERTISING_SPACE" = "Request Advertising Space";
+"REQUIREMENTS_FOR_LISTING" = "Requirements for Listing";
+"RESTART_SPRINGBOARD" = "Restart SpringBoard";
+"RESUBMIT_FORM" = "Are you sure you want to submit this form again?";
+"RESUMING_AT" = "Resuming At";
+"RETURN_TO_CYDIA" = "Return to Cydia";
+"ROLE_EX" = "Not all of the packages available via Cydia are designed to be used by all users. Please categorize yourself so that Cydia can apply helpful filters.\n\nThis choice can be changed from \"Settings\" under the \"Manage\" tab (on the iPhone or iPod touch), or the \"Sources\" tab (on the iPad).";
+"RUNNING" = "Running";
+"SAFE" = "Safe";
+"SAMPLE" = "Sample";
+"SCREENSHOT" = "Screenshot";
+"SCREENSHOTS" = "Screenshots";
+"SEARCH" = "Search";
+"SEARCH_EX" = "Package Names & Descriptions";
+"SECTION" = "Section";
+"SECTION_VISIBILITY" = "Section Visibility";
+"SECTIONS" = "Sections";
+"SEE_WHAT_CHANGED" = "See What Changed";
+"SETTINGS" = "Settings";
+"SHOW_ALL_CHANGES" = "Show All Changes";
+"SHOW_ALL_CHANGES_EX" = "Changes only shows upgrades to installed packages so as to minimize spam from packagers. Activate this to see upgrades to this package even when it is not installed.";
+"SIGNED_PACKAGE" = "This package has been signed.";
+"SIMPLE" = "Simple";
+"SINGLE_QUOTED" = "‘%@’";
+"SLASH_DELIMITED" = "%@ / %@";
+"SOURCE_DETAILS" = "Source Information";
+"SOURCE_WARNING" = "Source Warning";
+"SOURCES" = "Sources";
+"SOURCES_EX" = "List current sources and add custom ones you may know.";
+"SPONSOR" = "Sponsor";
+"SPONSORING_PRODUCTS" = "Sponsoring Products";
+"STATISTICS" = "Statistics";
+"STILL_BROKEN_EX" = "Trying to fix the broken selections did not seem to help.";
+"STORAGE" = "Storage";
+"STORAGE_EX" = "See how much room you have left for new packages.";
+"SUBMIT" = "Submit";
+"SUPPORT_KNOWN_ISSUES" = "Support & Known Issues";
+"TEMPORARY_IGNORE" = "Ignore (Temporary)";
+"THANK_YOU" = "Thank You";
+"QUEUE" = "Queue";
+"UNABLE_TO_COMPLY" = "Unable to Comply";
+"UNABLE_TO_COMPLY_EX" = "This operation requires the removal of one or more packages that are required for the continued operation of either Cydia or iPhoneOS. In order to continue and force this operation you will need to be activate the Advanced mode under to continue and force this operation you will need to be activate the Advanced mode under Settings.";
+"UNABLE_TO_LOAD" = "Unable to Load";
+"UNKNOWN" = "Unknown";
+"UNSAFE" = "Unsafe";
+"UPDATING_DATABASE" = "Updating Database";
+"UPDATING_SOURCES" = "Updating Sources";
+"UPGRADE" = "Upgrade";
+"UPGRADE_ESSENTIAL" = "Upgrade Essential";
+"UPGRADING_TO_READ_THIS" = "Upgrading to %@? Read This";
+"USER" = "User";
+"USER_EX" = "Apps, Tweaks, and Themes.";
+"USER_GUIDES" = "User Guides";
+"USERNAME" = "username";
+"VERIFICATION_ERROR" = "Verification Error";
+"VERIFYING_URL" = "Verifying URL";
+"VERSION" = "Version";
+"WARNING" = "Warning";
+"WELCOME_TO_CYDIA" = "Welcome to Cydia™";
+"WHO_ARE_YOU" = "Who Are You?";
+"YES" = "Yes";
diff --git a/MobileCydia.app/English.lproj/Sections_.strings b/MobileCydia.app/English.lproj/Sections_.strings
new file mode 100644 (file)
index 0000000..9cc7ba1
--- /dev/null
@@ -0,0 +1,45 @@
+"Administration" = "";
+"App Addons" = "";
+"Archiving" = "";
+"Battery" = "";
+"Carrier Bundles" = "";
+"Carriers" = "";
+"Complete" = "";
+"Data Storage" = "";
+"Development" = "";
+"Dialer" = "";
+"Dictionaries" = "";
+"Dock" = "";
+"eBooks" = "";
+"Education" = "";
+"Emulation" = "";
+"Entertainment" = "";
+"Games" = "";
+"Icy" = "";
+"Java" = "";
+"Keyboards" = "";
+"Localization" = "";
+"LockScreen" = "";
+"Messaging" = "";
+"Multimedia" = "";
+"Networking" = "";
+"Notifications" = "";
+"Packaging" = "";
+"Productivity" = "";
+"Repositories" = "";
+"Ringtones" = "";
+"Scripting" = "";
+"Security" = "";
+"Sliders" = "";
+"SMS" = "";
+"System" = "";
+"Terminal Support" = "";
+"Text Editors" = "";
+"Themes" = "";
+"Toys" = "";
+"Tweaks" = "";
+"Utilities" = "";
+"Wallpaper" = "";
+"Weather" = "";
+"WebClips" = "";
+"Widgets" = "";
diff --git a/MobileCydia.app/French.lproj/Localizable.strings b/MobileCydia.app/French.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..bdd6988
--- /dev/null
@@ -0,0 +1,210 @@
+"ABOUT" = "À propos";
+"ABOUT_CYDIA" = "À propos de Cydia";
+"ACCEPT_NEW_COPY" = "Accepter la nouvelle version";
+"ADD" = "Ajouter";
+"ADD_ANYWAY" = "Ajouter quand même";
+"ADD_SOURCE" = "Ajouter la source";
+"ADMINISTRATIVE_INFORMATION" = "Information administrative";
+"ADVANCED_SEARCH" = "Recherche avancée";
+"ALL_PACKAGES" = "Tous les paquets";
+"APPLE" = "Apple";
+"AUTHOR" = "Auteur";
+"AVAILABLE_UPGRADES" = "Mises à jour disponibles";
+"BROWSER" = "Navigateur";
+"BY" = "par %@";
+"CANCEL" = "Annuler";
+"CANCEL_CLEAR" = "Annuler et vider la file";
+"CANCEL_OPERATION" = "Annuler l'opération";
+"CANNOT_COMPLY" = "Impossible";
+"CANNOT_COMPLY_EX" = "Les modifications demandées ne peuvent pas être appliquées à cause de dépendances ou de conflits impossibles à identifier automatiquement.";
+"CANNOT_LOCATE_PACKAGE" = "Impossible de trouver le paquet";
+"CHANGE_PACKAGE_SETTINGS" = "Changer les réglages du paquet";
+"CHANGES" = "Nouveautés";
+"CLEAN_ARCHIVES" = "Nettoyer les archives";
+"CLEAR" = "Nettoyer";
+"CLOSE" = "Fermer";
+"CLOSE_CYDIA" = "Quitter Cydia (Redémarrer)";
+"COLON_DELIMITED" = "%@ : %@";
+"COMMA_DELIMITED" = "%@, %@";
+"COMING_SOON" = "À venir!";
+"COMPLETE" = "Effectué";
+"COMPLETE_UPGRADE" = "Mise à Jour effectuée";
+"CONFIGURATION_UPGRADE" = "Configuration de la mise à jour";
+"CONFIGURATION_UPGRADE_EX" = "Le(s) fichier(s) suivant(s) ont été modifiés par le responsable de ce paquet et par vous (ou pour vous par un script).";
+"COMMERCIAL_APPLICATIONS" = "Applications commerciales";
+"CONFIRM" = "Confirmer";
+"CONSOLE_PACKAGE" = "Ceci est un paquet console!";
+"CONSOLE_UTILITIES_DAEMONS" = "Utilitaires de terminal & daemons";
+"CONTINUE_QUEUING" = "Mettre dans la file d'attente";
+"COUNTS_NONZERO_EX" = "Après avoir calculé la somme de valeurs importantes, elle n'est pas égale à zéro. Ceci est épeurant. J'ai aucune idée pourquoi ceci est dangereux, mais je crois que APT ne voulait absolument pas que ceci arrive.";
+"CREDITS" = "Crédits";
+"CYDIA_STORE" = "Cydia Store";
+"DATABASE" = "Base de données";
+"DETAILS" = "Détails";
+"DEVELOPER" = "Développeur";
+"DEVELOPER_EX" = "Aucun filtre";
+"DEVELOPERS_ONLY" = "Développeurs seulement";
+"DISK_FREEING" = "Espace disque libéré";
+"DISK_USING" = "Espace disque utilisé";
+"DONATE_USING" = "Donnez en utilisant %@";
+"DONE" = "OK";
+"DOUBLE_QUOTED" = "« $@ »";
+"DOWNGRADE" = "Rétrograder";
+"DOWNLOADING" = "Télécharger";
+"DOWNLOADING_" = "Téléchargement de %@ en cours";
+"EDIT" = "Modifier";
+"ENTER_APT_URL" = "Entrez une adresse Cydia/APT";
+"ENTERED_BY_USER" = "Entré par l'utilisateur";
+"ERROR" = "Erreur";
+"ESSENTIAL_UPGRADE" = "Mise à jour essentielle";
+"ESSENTIAL_UPGRADES" = "%d mises à jour essentielles";
+"ESSENTIAL_UPGRADE_EX" = "Un ou plusieurs paquets essentiels sont périmés. Si vous ne les mettez pas à jour, vous pourriez rencontrer des erreurs.";
+"EXCLAMATION" = "%@ !";
+"EXPANDED_SIZE" = "Taille décompressée";
+"EXPERT" = "Expert";
+"FEATURED_PACKAGES" = "Paquets conseillés";
+"FAQ" = "FAQ";
+"FILES" = "Fichiers";
+"FILES_INSTALLED_TO" = "fichiers installés dans %@";
+"FILESYSTEM_CONTENT" = "Contenu";
+"FOLLOW_ON_TWITTER" = "Suivez %@ sur Twitter";
+"FORCE_REMOVAL" = "Forcer la suppression";
+"FORCIBLY_CLEAR" = "Forcer le nettoyage";
+"FREE_APPLICATIONS" = "Applications gratuites";
+"FREE_EXTENSIONS" = "Extensions gratuites";
+"FREQUENTLY_ASKED_QUESTIONS" = "Foire aux questions";
+"FROM" = "de %@";
+"FROWNY_PANTS" = "Pantalon fronçant";
+"FUTURE_FEATURE_ROADMAP" = "Feuille de route des mises à jour";
+"HACKER" = "Hacker";
+"HACKER_EX" = "+ CLI";
+"HALFINSTALLED_PACKAGE" = "Paquet à moitié installé";
+"HALFINSTALLED_PACKAGES" = "%d paquets à moitié installés";
+"HALFINSTALLED_PACKAGE_EX" = "Quand les scripts du paquet ne fonctionnent pas, ils laissent le paquet à moitié installé et à moitié configuré. Ces erreurs ne disparaissent pas et vont continuer à causer des problèmes. Ces scripts peuvent être supprimés et les paquets frocément désinstallés.";
+"HOME" = "Accueil";
+"ID" = "ID";
+"IGNORE_UPGRADES" = "Ignorer les mises à jour";
+"IGNORED_UPGRADES" = "Mises à jour ignorées";
+"ILLEGAL_PACKAGE_IDENTIFIER" = "Identifiant du paquet illégal";
+"INSTALL" = "Installer";
+"INSTALLED" = "Installé";
+"INSTALLED_BY_PACKAGE" = "Installer par paquet";
+"INSTALLED_DETAILS" = "Paquet installé";
+"INSTALLED_FILES" = "Fichiers installés";
+"KEEP_OLD_COPY" = "Garder ma vieille copie";
+"LOADING" = "Chargement";
+"LOADING_DATA" = "Chargement des données";
+"LOCAL" = "Local";
+"LOGIN" = "S'identifier";
+"MAILING_LISTS" = "Listes de diffusion";
+"MAINTAINER" = "Contacter";
+"MANAGE" = "Gérer";
+"MODIFY" = "Modifier";
+"MODIFICATIONS" = "Modifications";
+"MORE_INFORMATION" = "Plus d'information";
+"MORE_PACKAGE_SOURCES" = "Plus de sources de paquets";
+"NAME" = "Nom";
+"NETWORK_ERROR" = "Erreur réseau";
+"NEVER_OR_UNKNOWN" = "Jamais ou inconnnu";
+"NEW" = "Nouveau";
+"NEW_AT" = "Nouveau à %@";
+"NEW_INSTALL" = "Nouvelle installation";
+"NO" = "Non";
+"NO_SECTION" = "(Pas de catégorie)";
+"NOT_RATED" = "Pas de cote";
+"NOTE" = "Note";
+"NOT_REPOSITORY" = "Impossible de trouver cette source";
+"NOT_REPOSITORY_EX" = "La source de paquets ne peut pas être trouvée. Ce pourrait être car c'est une source d'Installer (qui ne fonctionne pas avec Cydia). Cydia ne peut fonctionner qu'avec des adresses rigoureusement exactes. Si vous hébergez une source de paquets, contactez l'auteur de Cydia à propos de ces erreurs.";
+"OK" = "OK";
+"OKAY" = "OK";
+"PACKAGE_CANNOT_BE_FOUND" = "Le paquet %@ est introuvable dans vos sources actuelles. Je vous recommande d'ajouter de nouvelles sources.";
+"PACKAGE_CANNOT_BE_FOUND_EX" = "Ce problème peut aussi être causé par plusieurs autres facteurs. Le plus commun est que votre catalogue de paquets est périmé. Pour rafraîchir manuellement, utilisez le bouton Rafraîchir dans l'onglet Nouveautés. Le paquet pour simplement ne plus exister. Il est aussi posible que vous utilisez un vieux firmware; les utilisateurs devraient essayer de rester raisonnablement à date avec les sorties de firmware de Apple.";
+"PACKAGE_DAMAGED" = "Paquet abimé";
+"PACKAGE_DETAILS" = "Détails du paquet";
+"PACKAGE_QUEUE" = "File d'attente de paquets";
+"PACKAGES" = "Paquets";
+"PACKAGES_EX" = "Voir ou supprimer des paquets précédemment installés.";
+"PARENTHETICAL" = "%@ (%@)";
+"PASSWORD" = "mot de passe";
+"PERFORM_SELECTIONS" = "Performer des sélections";
+"PREPARE_ARCHIVES" = "Préparer les archives";
+"PRODUCTS" = "Produits";
+"PURGE" = "Purger";
+"Q_D" = "File";
+"QUEUED_FOR" = "File d'attente pour %@";
+"QUESTION" = "%@ ?";
+"REBOOT_DEVICE" = "Redémarrer l'appareil";
+"RECENT_CHANGES_UPDATES" = "Mises à jour ou changements récents";
+"RECOMMENDED_BOOKS" = "Livres recommandés";
+"REFRESH" = "Rafraîchir";
+"REFRESHING_DATA" = "Rafraîchissement de données";
+"REINSTALL" = "Réinstaller";
+"RELOAD" = "Recharger";
+"RELOAD_SPRINGBOARD" = "Relancer SpringBoard";
+"RELOADING_DATA" = "Rechargement des données";
+"REMOVE" = "Supprimer";
+"REMOVING_ESSENTIALS" = "Suppression d'essentiels";
+"REMOVING_ESSENTIALS_EX" = "Cette opération va supprimer un ou plusieurs paquets indispensables au bon fonctionnement de Cydia ou de votre iPhone. Si vous continuez, vous pourriez bien ne pas pouvoir utiliser Cydia pour réparer les dommages causés.";
+"REPAIRING" = "Réparation";
+"REPOSITORY_SIGNATURE" = "Voir la Signature de la Source";
+"REQUEST_ADVERTISING_SPACE" = "Demander un Espace de Publicité";
+"REQUIREMENTS_FOR_LISTING" = "Prérequis pour le Listage";
+"RESTART_SPRINGBOARD" = "Relancer le SpringBoard";
+"RESUBMIT_FORM" = "Êtes-vous certain(e) de vouloir envoyer ce formulaire à nouveau?";
+"RESUMING_AT" = "Reprise à";
+"RETURN_TO_CYDIA" = "Retour à Cydia";
+"ROLE_EX" = "Certains des paquets disponibles sur Cydia ne sont pas destinés à tous les utilisateurs. Choisissez votre catégorie pour que Cydia ne vous propose que ceux dont vous auriez besoin.\n\nCe choix peut être changé dans les \"Réglages\" du menu \"Gestion\".";
+"RUNNING" = "En Fonction";
+"SAFE" = "Sûr";
+"SAMPLE" = "Échantillon";
+"SCREENSHOT" = "Capture d'écran";
+"SCREENSHOTS" = "Captures d'écran";
+"SEARCH" = "Recherche";
+"SEARCH_EX" = "Noms des paquets & descriptions";
+"SECTION" = "Catégorie";
+"SECTION_VISIBILITY" = "Visibilité des catégories";
+"SECTIONS" = "Catégories";
+"SEE_WHAT_CHANGED" = "Voyez ce qui a changé";
+"SETTINGS" = "Réglages";
+"SHOW_ALL_CHANGES" = "Montrer tous les changements";
+"SHOW_ALL_CHANGES_EX" = "Seuls les mises à jour de paquets installés ne sont affichés ici pour limiter le spam des empaqueteurs. En activant ceci vous serez averti des mises à jour sans que ce paquet soit installé.";
+"SIGNED_PACKAGE" = "Ce paquet est signé.";
+"SIMPLE" = "Simple";
+"SINGLE_QUOTED" = "‹ %@ ›";
+"SLASH_DELIMITED" = "%@ / %@";
+"SOURCE_DETAILS" = "Détails sur la source";
+"SOURCE_WARNING" = "Avertissement de source";
+"SOURCES" = "Sources";
+"SOURCES_EX" = "Voyez vos sources et en ajoutez des nouvelles.";
+"SPONSOR" = "Commanditaire";
+"SPONSORING_PRODUCTS" = "Produits commanditants";
+"STATISTICS" = "Statistiques";
+"STILL_BROKEN_EX" = "Même après avoir essayé de réparé les sélections, le problème n'a pas l'air à être réglé.";
+"STORAGE" = "Stockage";
+"STORAGE_EX" = "Voyez combien d'espace il vous reste pour de nouveaux paquets.";
+"SUBMIT" = "Envoyer";
+"SUPPORT_KNOWN_ISSUES" = "Aide & problèmes connus";
+"TEMPORARY_IGNORE" = "Ignorer (temporairement)";
+"THANK_YOU" = "Remerciements";
+"QUEUE" = "File d'attente";
+"UNABLE_TO_COMPLY" = "Impossible";
+"UNABLE_TO_COMPLY_EX" = "Cette opération va supprimer un ou plusieurs paquets indispensables au bon fonctionnement de Cydia ou de votre iPhone. Pour continuer et forcer cette opération, vous devez activer le mode Utilisateur avancé dans les Réglages.";
+"UNABLE_TO_LOAD" = "Chargement impossible";
+"UNKNOWN" = "Inconnu";
+"UNSAFE" = "Risqué";
+"UPDATING_DATABASE" = "Mise à jour de la base de données";
+"UPDATING_SOURCES" = "Mise à jour des sources";
+"UPGRADE" = "Mise à jour";
+"UPGRADE_ESSENTIAL" = "Mise à jour des essentiels";
+"UPGRADING_TO_READ_THIS" = "À lire: mise à jour à %@";
+"USER" = "Utilisateur";
+"USER_EX" = "GUI seulement";
+"USER_GUIDES" = "Guides utilisateur";
+"USERNAME" = "Nom d'utilisateur";
+"VERIFICATION_ERROR" = "Erreur de vérification";
+"VERIFYING_URL" = "Vérification de l'URL";
+"VERSION" = "Version";
+"WARNING" = "Avertissement";
+"WELCOME_TO_CYDIA" = "Bienvenue dans Cydia™";
+"WHO_ARE_YOU" = "Qui êtes-vous?";
+"YES" = "Oui";
diff --git a/MobileCydia.app/French.lproj/Sections.strings b/MobileCydia.app/French.lproj/Sections.strings
new file mode 100644 (file)
index 0000000..799a82c
--- /dev/null
@@ -0,0 +1,45 @@
+"Administration" = "Administration";
+"App Addons" = "Ajouts aux applications";
+"Archiving" = "Archivage";
+"Battery" = "Batterie";
+"Carrier Bundles" = "Opérateurs";
+"Carriers" = "Opérateurs";
+"Complete" = "Terminé";
+"Data Storage" = "Archivage de données";
+"Development" = "Développement";
+"Dialer" = "Numéroteur";
+"Dictionaries" = "Dictionnaires";
+"Dock" = "Dock";
+"eBooks" = "eLivres";
+"Education" = "Éducation";
+"Emulation" = "Émulation";
+"Entertainment" = "Divertissement";
+"Games" = "Jeux";
+"Icy" = "Icy";
+"Java" = "Java";
+"Keyboards" = "Claviers";
+"Localization" = "Localisation";
+"LockScreen" = "Écran de verrouillage";
+"Messaging" = "Messagerie";
+"Multimedia" = "Multimédia";
+"Networking" = "Réseau";
+"Notifications" = "Notifications";
+"Packaging" = "Enpaquetage";
+"Productivity" = "Productivité";
+"Repositories" = "Sources";
+"Ringtones" = "Sonneries";
+"Scripting" = "Scripts";
+"Security" = "Sécurité";
+"Sliders" = "Sliders";
+"SMS" = "SMS";
+"System" = "Système";
+"Terminal Support" = "Aide au terminal";
+"Text Editors" = "Éditeurs de texte";
+"Themes" = "Thèmes";
+"Toys" = "Jouets";
+"Tweaks" = "Modifications";
+"Utilities" = "Utilitaires";
+"Wallpaper" = "Fonds d'écran";
+"Weather" = "Météo";
+"WebClips" = "WebClips";
+"Widgets" = "Widgets";
diff --git a/MobileCydia.app/German.lproj/Localizable.strings b/MobileCydia.app/German.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..78a818c
--- /dev/null
@@ -0,0 +1,210 @@
+"ABOUT" = "Über";
+"ABOUT_CYDIA" = "Über Cydia Installer";
+"ACCEPT_NEW_COPY" = "Die neue Kopie annehmen";
+"ADD" = "Hinzufügen";
+"ADD_ANYWAY" = "Trotzdem hinzufügen";
+"ADD_SOURCE" = "Quelle hinzufügen";
+"ADMINISTRATIVE_INFORMATION" = "Administrative Information";
+"ADVANCED_SEARCH" = "Erweiterte Suche";
+"ALL_PACKAGES" = "Alle Pakete";
+"APPLE" = "Apple";
+"AUTHOR" = "Autor";
+"AVAILABLE_UPGRADES" = "Vorhandene Aktualisierungen";
+"BROWSER" = "Browser";
+"BY" = "von %@";
+"CANCEL" = "Abbrechen";
+"CANCEL_CLEAR" = "Abbrechen und leeren";
+"CANCEL_OPERATION" = "Vorgang abbrechen";
+"CANNOT_COMPLY" = "Ausführung unmöglich";
+"CANNOT_COMPLY_EX" = "Die gewünschten Änderungen können wegen notwendiger Abhängigkeiten oder Konflikten, die nicht automatisch behoben werden können, nicht durchgeführt werden.";
+"CANNOT_LOCATE_PACKAGE" = "Paket nicht gefunden";
+"CHANGE_PACKAGE_SETTINGS" = "Paket-Einstellungen ändern";
+"CHANGES" = "Änderungen";
+"CLEAN_ARCHIVES" = "Archive aufräumen";
+"CLEAR" = "Leeren";
+"CLOSE" = "Schließen";
+"CLOSE_CYDIA" = "Cydia beenden (neustarten)";
+"COLON_DELIMITED" = "%@: %@";
+"COMMA_DELIMITED" = "%@, %@";
+"COMING_SOON" = "Bald verfügbar!";
+"COMPLETE" = "Fertig";
+"COMPLETE_UPGRADE" = "Vollständige Aktualisierung";
+"CONFIGURATION_UPGRADE" = "Konfiguration wählen";
+"CONFIGURATION_UPGRADE_EX" = "Die folgende Datei wurde sowohl durch den Paket-Inhaber als auch von Ihnen (oder für Sie von einem Skript) geändert.";
+"COMMERCIAL_APPLICATIONS" = "Kommerzielle Programme";
+"CONFIRM" = "Bestätigen";
+"CONSOLE_PACKAGE" = "Dies ist ein Konsolen-Paket!";
+"CONSOLE_UTILITIES_DAEMONS" = "Konsolentools & Hintergrundprozesse";
+"CONTINUE_QUEUING" = "Weiter auswählen";
+"COUNTS_NONZERO_EX" = "So, ich habe gerade ein paar wichtig scheinende Werte gezählt, und ihre Summe war nicht null. Das ist beängstigend. Ich weiß nicht mehr, warum ich das nicht mag, aber ich denke APT bestand darauf, dass das nicht passieren darf.";
+"CREDITS" = "Credits";
+"CYDIA_STORE" = "Cydia Store";
+"DATABASE" = "Datenbank";
+"DETAILS" = "Details";
+"DEVELOPER" = "Entwickler";
+"DEVELOPER_EX" = "Ohne Filter";
+"DEVELOPERS_ONLY" = "Nur für Entwickler";
+"DISK_FREEING" = "Freigegebener Speicher";
+"DISK_USING" = "Speicherverbrauch";
+"DONATE_USING" = "Spenden via %@";
+"DONE" = "Fertig";
+"DOUBLE_QUOTED" = "„%@“";
+"DOWNGRADE" = "Downgrade";
+"DOWNLOADING" = "Lädt";
+"DOWNLOADING_" = "Lädt %@ herunter";
+"EDIT" = "Bearbeiten";
+"ENTER_APT_URL" = "Cydia/APT URL eingeben";
+"ENTERED_BY_USER" = "Vom Benutzer eingegeben";
+"ERROR" = "Fehler";
+"ESSENTIAL_UPGRADE" = "Wichtige Aktualisierung";
+"ESSENTIAL_UPGRADES" = "%d wichtige Aktualisierungen";
+"ESSENTIAL_UPGRADE_EX" = "Ein oder mehr wichtige Pakete sind veraltet. Um Fehler zu vermeiden, wird empfohlen die Aktualisierungen zu installieren.";
+"EXCLAMATION" = "%@!";
+"EXPANDED_SIZE" = "Entpackte Größe";
+"EXPERT" = "Experte";
+"FEATURED_PACKAGES" = "Paketempfehlungen";
+"FAQ" = "FAQ";
+"FILES" = "Dateien";
+"FILES_INSTALLED_TO" = "Dateien installiert nach %@";
+"FILESYSTEM_CONTENT" = "Inhalt des Dateisystems";
+"FOLLOW_ON_TWITTER" = "Folge %@ auf Twitter";
+"FORCE_REMOVAL" = "Löschen erzwingen";
+"FORCIBLY_CLEAR" = "Leeren erzwingen";
+"FREE_APPLICATIONS" = "Kostenlose Programme";
+"FREE_EXTENSIONS" = "Kostenlose Erweiterungen";
+"FREQUENTLY_ASKED_QUESTIONS" = "Häufig gestellte Fragen (FAQ)";
+"FROM" = "von %@";
+"FROWNY_PANTS" = "Stirnrunzelnde Hose";
+"FUTURE_FEATURE_ROADMAP" = "Übersicht geplanter Funktionen";
+"HACKER" = "Hacker";
+"HACKER_EX" = "+ Kommandozeile";
+"HALFINSTALLED_PACKAGE" = "Teilinstalliertes Paket";
+"HALFINSTALLED_PACKAGES" = "%d teilinstallierte Pakete";
+"HALFINSTALLED_PACKAGE_EX" = "Wenn die an Pakete gebundenen Skripte Probleme machen, werden sie in einem schlechten Status (halb eingestellt oder halb installiert) zurückgelassen. Diese Fehler sind dauerhaft und erzeugen weitere Probleme. Diese fehlerhaften Skripte und Pakete können entfernt werden.";
+"HOME" = "Start";
+"ID" = "ID";
+"IGNORE_UPGRADES" = "Aktualisierungen ignorieren";
+"IGNORED_UPGRADES" = "Ignorierte Aktualisierungen";
+"ILLEGAL_PACKAGE_IDENTIFIER" = "Unerlaubte Paket-Kennung";
+"INSTALL" = "Installieren";
+"INSTALLED" = "Installiert";
+"INSTALLED_BY_PACKAGE" = "Installiert nach Paket";
+"INSTALLED_DETAILS" = "Installiertes Paket";
+"INSTALLED_FILES" = "Installierte Dateien";
+"KEEP_OLD_COPY" = "Meine alte Kopie behalten";
+"LOADING" = "Lade";
+"LOADING_DATA" = "Lade Daten";
+"LOCAL" = "Lokal";
+"LOGIN" = "Anmeldung";
+"MAILING_LISTS" = "Mailingliste";
+"MAINTAINER" = "Kontakt";
+"MANAGE" = "Verwalten";
+"MODIFICATIONS" = "Änderungen";
+"MODIFY" = "Verändern";
+"MORE_INFORMATION" = "Mehr Informationen";
+"MORE_PACKAGE_SOURCES" = "Mehr Paketquellen";
+"NAME" = "Name";
+"NETWORK_ERROR" = "Netzwerk-Fehler";
+"NEVER_OR_UNKNOWN" = "Nie oder unbekannt";
+"NEW" = "Neu";
+"NEW_AT" = "Neu am %@";
+"NEW_INSTALL" = "Neuinstallation";
+"NO" = "Nein";
+"NO_SECTION" = "(Keine Kategorie)";
+"NOT_RATED" = "Nicht bewertet";
+"NOTE" = "Hinweis";
+"NOT_REPOSITORY" = "Quelle nicht gefunden";
+"NOT_REPOSITORY_EX" = "Die angegebene Quelle konnte nicht gefunden werden. Dies kann passieren, wenn eine Installer-Quelle hinzugefügt wurde (diese werden nicht unterstützt). Außerdem kann dieses Programm nur mit exakten, vollständigen URLs umgehen. Falls sie eine Quelle hosten und Probleme haben kontaktieren sie mit ihren Fragen bitte den Autor von Cydia.";
+"OK" = "OK";
+"OKAY" = "Okay";
+"PACKAGE_CANNOT_BE_FOUND" = "Das Paket %@ kann in den aktuellen Quellen nicht gefunden werden. Ich schlage vor, mehr Quellen hinzuzufügen.";
+"PACKAGE_CANNOT_BE_FOUND_EX" = "Dieses Problem kann auch durch eine Reihe anderer Faktoren hervorgerufen worden sein. Der häufigste ist, dass dein Paketkatalog nicht mehr aktuell ist. Zum manuellen erneuern, klicke den Aktualisieren-Knopf im Änderungen-Tab. Das Paket könnte auch einfach nicht mehr existieren. Es könnte auch sein, dass du eine alte Firmwareversion nutzt: Nutzer sollten versuchen halbwegs auf dem Laufenden zu bleiben mit Apples neuen Firmwares.";
+"PACKAGE_DAMAGED" = "Paket beschädigt";
+"PACKAGE_DETAILS" = "Paketdetails";
+"PACKAGE_QUEUE" = "Paket-Warteschlange";
+"PACKAGES" = "Pakete";
+"PACKAGES_EX" = "Bereits installierte Pakete ansehen oder löschen.";
+"PARENTHETICAL" = "%@ (%@)";
+"PASSWORD" = "Passwort";
+"PERFORM_SELECTIONS" = "Führe Auswahl durch";
+"PREPARE_ARCHIVES" = "Bereite Archive vor";
+"PRODUCTS" = "Produkte";
+"PURGE" = "Völlig entfernen";
+"Q_D" = "S";
+"QUEUED_FOR" = "In Warteschlange für %@";
+"QUESTION" = "%@?";
+"REBOOT_DEVICE" = "Gerät neustarten";
+"RECENT_CHANGES_UPDATES" = "Neueste Änderungen/Aktualisierungen";
+"RECOMMENDED_BOOKS" = "Empfohlene Bücher";
+"REFRESH" = "Aktualisieren";
+"REFRESHING_DATA" = "Hole neue Daten";
+"REINSTALL" = "Neu installieren";
+"RELOAD" = "Neu laden";
+"RELOAD_SPRINGBOARD" = "SpringBoard neu laden";
+"RELOADING_DATA" = "Lade neue Daten";
+"REMOVE" = "Entfernen";
+"REMOVING_ESSENTIALS" = "Grundlegende Pakete löschen";
+"REMOVING_ESSENTIALS_EX" = "Diese Aktion erfordert das Löschen eines oder mehrerer Pakete die notwendig für die Funktionalität von Cydia oder iPhoneOS sind. Wenn Sie fortsetzen, können Sie ggf. Cydia nicht mehr benutzen um den Schaden zu beheben.";
+"REPAIRING" = "Reparieren";
+"REPOSITORY_SIGNATURE" = "Quellen-Signatur anzeigen";
+"REQUEST_ADVERTISING_SPACE" = "Werbefläche beantragen";
+"REQUIREMENTS_FOR_LISTING" = "Bedingungen für die Aufnahme";
+"RESTART_SPRINGBOARD" = "SpringBoard neu starten";
+"RESUBMIT_FORM" = "Sind Sie sicher, dass Sie das Formular erneut senden möchten?";
+"RESUMING_AT" = "Wiederaufnahme bei";
+"RETURN_TO_CYDIA" = "Zu Cydia zurückkehren";
+"ROLE_EX" = "Nicht alle in Cydia erhältlichen Pakete sind für alle Benutzer gedacht. Bitte stufen Sie sich ein, so dass Cydia hilfreiche Filter anwenden kann.\n\nDiese Einstellung kann in den \"Einstellungen\" unter \"Verwalten\" geändert werden.";
+"RUNNING" = "Aktiv";
+"SAFE" = "Sicher";
+"SAMPLE" = "Beispiel";
+"SCREENSHOT" = "Bildschirmfoto";
+"SCREENSHOTS" = "Bildschirmfotos";
+"SEARCH" = "Suche";
+"SEARCH_EX" = "Paketname & Beschreibung";
+"SECTION" = "Kategorie";
+"SECTION_VISIBILITY" = "Sichtbarkeit der Kategorien";
+"SECTIONS" = "Kategorien";
+"SEE_WHAT_CHANGED" = "Änderungen ansehen";
+"SETTINGS" = "Einstellungen";
+"SHOW_ALL_CHANGES" = "Alle Änderungen zeigen";
+"SHOW_ALL_CHANGES_EX" = "Änderungen zeigt nur Aktualisierungen der installierten Paketen an, um Spam von Paket-Herstellern zu reduzieren. Aktivieren Sie dies, um Aktualisierungen zu diesem Paket zu sehen, obwohl es nicht installiert ist.";
+"SIGNED_PACKAGE" = "Dieses Paket wurde signiert.";
+"SIMPLE" = "Einfach";
+"SINGLE_QUOTED" = "‚%@‘";
+"SLASH_DELIMITED" = "%@ / %@";
+"SOURCE_DETAILS" = "Information zur Quelle";
+"SOURCE_WARNING" = "Quellenwarnung";
+"SOURCES" = "Quellen";
+"SOURCES_EX" = "Quellenliste anzeigen und eigene hinzufügen.";
+"SPONSOR" = "Sponsor";
+"SPONSORING_PRODUCTS" = "Unterstützende Produkte";
+"STATISTICS" = "Statistik";
+"STILL_BROKEN_EX" = "Der Versuch, die kaputten Sektionen zu reparieren hat nichts gebracht.";
+"STORAGE" = "Speicherplatz";
+"STORAGE_EX" = "Nachsehen, wieviel Speicherplatz für neue Pakete vorhanden ist.";
+"SUBMIT" = "Absenden";
+"SUPPORT_KNOWN_ISSUES" = "Support & bekannte Probleme";
+"TEMPORARY_IGNORE" = "Ignorieren (temporär)";
+"THANK_YOU" = "Danke";
+"QUEUE" = "Warteschlange";
+"UNABLE_TO_COMPLY" = "Operation nicht möglich";
+"UNABLE_TO_COMPLY_EX" = "Diese Aktion erfordert das Löschen eines oder mehrerer Pakete die notwendig für die Funktionalität von Cydia oder iPhoneOS sind. Um fortzufahren und diese Aktion zu erzwingen muss der Fortgeschrittenen-Modus in den Einstellungen aktiviert sein.";
+"UNABLE_TO_LOAD" = "Laden nicht möglich";
+"UNKNOWN" = "Unbekannt";
+"UNSAFE" = "Unsicher";
+"UPDATING_DATABASE" = "Datenbank aktualisieren";
+"UPDATING_SOURCES" = "Quellen aktualisieren";
+"UPGRADE" = "Aktualisierung";
+"UPGRADE_ESSENTIAL" = "Wichtige Pakete aktualisieren";
+"UPGRADING_TO_READ_THIS" = "Upgrade auf %@? Hier lesen";
+"USER" = "Benutzer";
+"USER_EX" = "Nur Grafische";
+"USER_GUIDES" = "Benutzer-Handbücher";
+"USERNAME" = "Benutzername";
+"VERIFICATION_ERROR" = "Fehler beim Überprüfen";
+"VERIFYING_URL" = "URL überprüfen";
+"VERSION" = "Version";
+"WARNING" = "Warnung";
+"WELCOME_TO_CYDIA" = "Willkommen bei Cydia™";
+"WHO_ARE_YOU" = "Wer sind Sie?";
+"YES" = "Ja";
diff --git a/MobileCydia.app/German.lproj/Sections.strings b/MobileCydia.app/German.lproj/Sections.strings
new file mode 100644 (file)
index 0000000..6abe4ce
--- /dev/null
@@ -0,0 +1,49 @@
+"Addons" = "Erweiterungen";
+"Administration" = "Verwaltung";
+"Adult" = "Ab 18";
+"App Addons" = "Programm-Erweiterugen";
+"Archiving" = "Archivierung";
+"Battery" = "Batterie";
+"Carrier Bundles" = "Telefongesellschaft-Pakete";
+"Carriers" = "Telefongesellschaften";
+"Complete" = "Vollständig";
+"Data Storage" = "Speicherplatzverwaltung";
+"Development" = "Entwicklung";
+"Dialer" = "Wählhilfen";
+"Dictionaries" = "Wörterbücher";
+"Dock" = "Dock";
+"eBooks" = "eBooks";
+"Education" = "Bildung";
+"Emulation" = "Emulation";
+"Entertainment" = "Unterhaltung";
+"Games" = "Spiele";
+"Icy" = "Icy";
+"Java" = "Java";
+"Keyboards" = "Tastaturen";
+"Localization" = "Lokalisierung";
+"LockScreen" = "Lockscreen";
+"Messaging" = "Nachrichtendienste";
+"Multimedia" = "Multimedia";
+"Networking" = "Netzwerk";
+"Notifications" = "Mitteilugen";
+"Packaging" = "Paketverwaltung";
+"Productivity" = "Produktivität / Kreativität";
+"Repositories" = "Quellen";
+"Ringtones" = "Klingeltöne";
+"Scripting" = "Skriptsprachen";
+"Security" = "Sicherheit";
+"Sliders" = "Slider";
+"SMS" = "SMS";
+"Social" = "Soziale Netze";
+"System" = "System";
+"Terminal Support" = "Konsolen-Support";
+"Text Editors" = "Texteditoren";
+"Themes" = "Themes";
+"Toys" = "Spielereien";
+"Tweaks" = "Tweaks / Tuning";
+"Utilities" = "Dienstprogramme";
+"Videos" = "Videos";
+"Wallpaper" = "Hintergrundbilder";
+"Weather" = "Wetter";
+"WebClips" = "Web-Schnipsel";
+"Widgets" = "Widgets";
diff --git a/MobileCydia.app/Icon-Small-50.png b/MobileCydia.app/Icon-Small-50.png
new file mode 100644 (file)
index 0000000..d7d2849
Binary files /dev/null and b/MobileCydia.app/Icon-Small-50.png differ
diff --git a/MobileCydia.app/Icon-Small.png b/MobileCydia.app/Icon-Small.png
new file mode 100644 (file)
index 0000000..af15d71
Binary files /dev/null and b/MobileCydia.app/Icon-Small.png differ
diff --git a/MobileCydia.app/Icon-Small@2x.png b/MobileCydia.app/Icon-Small@2x.png
new file mode 100644 (file)
index 0000000..1a73ddb
Binary files /dev/null and b/MobileCydia.app/Icon-Small@2x.png differ
diff --git a/MobileCydia.app/Info.plist b/MobileCydia.app/Info.plist
new file mode 100644 (file)
index 0000000..806506b
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>en</string>
+
+    <key>CFBundleExecutable</key>
+    <string>Cydia</string>
+
+    <key>CFBundleIdentifier</key>
+    <string>com.saurik.Cydia</string>
+
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+
+    <key>CFBundleName</key>
+    <string>Cydia</string>
+
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+
+    <key>CFBundleShortVersionString</key>
+    <string>0.9</string>
+
+    <key>CFBundleSignature</key>
+    <string>????</string>
+
+    <key>CFBundleVersion</key>
+    <string>0.9</string>
+
+    <key>SBUsesNetwork</key>
+    <integer>11</integer>
+
+    <key>CFBundleURLTypes</key>
+    <array>
+        <dict>
+            <key>CFBundleURLName</key>
+            <string>Cydia Internal URL</string>
+            <key>CFBundleURLSchemes</key>
+            <array>
+                <string>cydia</string>
+            </array>
+        </dict>
+    </array>
+
+    <key>DTSDKName</key>
+    <string>iphoneos2.0.saurik</string>
+
+    <key>MinimumOSVersion</key>
+    <string>2.0</string>
+
+    <key>UIDeviceFamily</key>
+    <array>
+        <integer>1</integer>
+        <integer>2</integer>
+    </array>
+
+    <key>UISupportedInterfaceOrientations</key>
+    <array>
+        <string>UIInterfaceOrientationPortrait</string>
+        <!--string>UIInterfaceOrientationPortraitUpsideDown</string>
+        <string>UIInterfaceOrientationLandscapeLeft</string>
+        <string>UIInterfaceOrientationLandscapeRight</string-->
+    </array>
+
+    <key>UIBackgroundModes</key>
+    <array>
+        <string>audio</string>
+        <string>continuous</string>
+    </array>
+
+    <key>CFBundleIconFile</key>
+    <string>iconClassic.png</string>
+
+    <key>CFBundleIconFiles</key>
+    <array>
+        <string>icon.png</string>
+        <string>icon-72.png</string>
+        <string>icon@2x.png</string>
+        <string>Icon-Small.png</string>
+        <string>Icon-Small-50.png</string>
+        <string>Icon-Small@2x.png</string>
+    </array>
+</dict>
+
+</plist>
diff --git a/MobileCydia.app/Modes/DOWNGRADE.png b/MobileCydia.app/Modes/DOWNGRADE.png
new file mode 100644 (file)
index 0000000..41c0d70
Binary files /dev/null and b/MobileCydia.app/Modes/DOWNGRADE.png differ
diff --git a/MobileCydia.app/Modes/INSTALL.png b/MobileCydia.app/Modes/INSTALL.png
new file mode 100644 (file)
index 0000000..a83f354
Binary files /dev/null and b/MobileCydia.app/Modes/INSTALL.png differ
diff --git a/MobileCydia.app/Modes/NEW_INSTALL.png b/MobileCydia.app/Modes/NEW_INSTALL.png
new file mode 120000 (symlink)
index 0000000..475bda6
--- /dev/null
@@ -0,0 +1 @@
+INSTALL.png
\ No newline at end of file
diff --git a/MobileCydia.app/Modes/PURGE.png b/MobileCydia.app/Modes/PURGE.png
new file mode 100644 (file)
index 0000000..795fa19
Binary files /dev/null and b/MobileCydia.app/Modes/PURGE.png differ
diff --git a/MobileCydia.app/Modes/REINSTALL.png b/MobileCydia.app/Modes/REINSTALL.png
new file mode 100644 (file)
index 0000000..0b7754c
Binary files /dev/null and b/MobileCydia.app/Modes/REINSTALL.png differ
diff --git a/MobileCydia.app/Modes/REMOVE.png b/MobileCydia.app/Modes/REMOVE.png
new file mode 100644 (file)
index 0000000..1b2e691
Binary files /dev/null and b/MobileCydia.app/Modes/REMOVE.png differ
diff --git a/MobileCydia.app/Modes/UPGRADE.png b/MobileCydia.app/Modes/UPGRADE.png
new file mode 100644 (file)
index 0000000..631b7ef
Binary files /dev/null and b/MobileCydia.app/Modes/UPGRADE.png differ
diff --git a/MobileCydia.app/Purposes/commercial.png b/MobileCydia.app/Purposes/commercial.png
new file mode 100644 (file)
index 0000000..ba66d4b
Binary files /dev/null and b/MobileCydia.app/Purposes/commercial.png differ
diff --git a/MobileCydia.app/Purposes/console.png b/MobileCydia.app/Purposes/console.png
new file mode 100644 (file)
index 0000000..48f7e88
Binary files /dev/null and b/MobileCydia.app/Purposes/console.png differ
diff --git a/MobileCydia.app/Purposes/daemon.png b/MobileCydia.app/Purposes/daemon.png
new file mode 100644 (file)
index 0000000..4593ee8
Binary files /dev/null and b/MobileCydia.app/Purposes/daemon.png differ
diff --git a/MobileCydia.app/Purposes/extension.png b/MobileCydia.app/Purposes/extension.png
new file mode 100644 (file)
index 0000000..e7025b4
Binary files /dev/null and b/MobileCydia.app/Purposes/extension.png differ
diff --git a/MobileCydia.app/Purposes/library.png b/MobileCydia.app/Purposes/library.png
new file mode 100644 (file)
index 0000000..3bcbc04
Binary files /dev/null and b/MobileCydia.app/Purposes/library.png differ
diff --git a/MobileCydia.app/Purposes/uikit.png b/MobileCydia.app/Purposes/uikit.png
new file mode 100644 (file)
index 0000000..2141d72
Binary files /dev/null and b/MobileCydia.app/Purposes/uikit.png differ
diff --git a/MobileCydia.app/Purposes/x.png b/MobileCydia.app/Purposes/x.png
new file mode 100644 (file)
index 0000000..0b24b74
Binary files /dev/null and b/MobileCydia.app/Purposes/x.png differ
diff --git a/MobileCydia.app/Sections.plist b/MobileCydia.app/Sections.plist
new file mode 100644 (file)
index 0000000..a62e6d7
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+
+<dict>
+    <key>Hunspell_Dictionaries</key>
+    <dict>
+        <key>Rename</key>
+        <string>Dictionaries_(Hunspell)</string>
+    </dict>
+
+    <key>Utility</key>
+    <dict>
+        <key>Rename</key>
+        <string>Utilities</string>
+    </dict>
+
+    <key>Themes_(Springboard)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(SpringBoard)</string>
+    </dict>
+
+    <key>Themes_(SummerBoard)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(SpringBoard)</string>
+    </dict>
+    
+    <key>Themes_(Systen)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(System)</string>
+    </dict>
+
+    <key>Intelliborn</key>
+    <dict>
+        <key>Rename</key>
+        <string>Utilities</string>
+    </dict>
+
+    <key>SMS</key>
+    <dict>
+        <key>Rename</key>
+        <string>Messaging</string>
+    </dict>
+
+    <key>CarrierBundle</key>
+    <dict>
+        <key>Rename</key>
+        <string>Carrier_Bundles</string>
+    </dict>
+
+    <key>Messages</key>
+    <dict>
+        <key>Rename</key>
+        <string>Messaging</string>
+    </dict>
+
+    <key>Themes_(Locksceen)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(LockScreen)</string>
+    </dict>
+
+    <key>Themes_(Lockscree)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(LockScreen)</string>
+    </dict>
+
+    <key>Themes_(Losckscreen)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(LockScreen)</string>
+    </dict>
+
+    <key>Themes_(Video)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(Videos)</string>
+    </dict>
+
+    <key>Utilites</key>
+    <dict>
+        <key>Rename</key>
+        <string>Utilities</string>
+    </dict>
+
+    <key>Themes_(Lockscreen)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(LockScreen)</string>
+    </dict>
+
+    <key>Themes_(Complet)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(Complete)</string>
+    </dict>
+    
+    <key>Themes_(Widgets)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Themes_(Addons)</string>
+    </dict>
+
+    <key>Wallpapers</key>
+    <dict>
+        <key>Rename</key>
+        <string>Wallpaper</string>
+    </dict>
+
+    <key>Messageing</key>
+    <dict>
+        <key>Rename</key>
+        <string>Messaging</string>
+    </dict>
+
+    <key>Network</key>
+    <dict>
+        <key>Rename</key>
+        <string>Networking</string>
+    </dict>
+    
+    <key>Ringtone</key>
+    <dict>
+        <key>Rename</key>
+        <string>Ringtones</string>
+    </dict>
+
+    <key>Tweak</key>
+    <dict>
+        <key>Rename</key>
+        <string>Tweaks</string>
+    </dict>
+
+    <key>Tweaks_2.0</key>
+    <dict>
+        <key>Rename</key>
+        <string>Tweaks_(2.0)</string>
+    </dict>
+
+    <key>Tweaks_2.1</key>
+    <dict>
+        <key>Rename</key>
+        <string>Tweaks_(2.1)</string>
+    </dict>
+
+    <key>Tweaks_2.2</key>
+    <dict>
+        <key>Rename</key>
+        <string>Tweaks_(2.2)</string>
+    </dict>
+
+    <key>Tweaks_3.0</key>
+    <dict>
+        <key>Rename</key>
+        <string>Tweaks_(3.0)</string>
+    </dict>
+    
+    <key>SBSettings_Addons</key>
+    <dict>
+        <key>Rename</key>
+        <string>Addons_(SBSettings)</string>
+    </dict>
+    
+    <key>LockInfo_Addons</key>
+    <dict>
+        <key>Rename</key>
+        <string>Addons_(LockInfo)</string>
+    </dict>
+    
+    <key>App_Addons</key>
+    <dict>
+        <key>Rename</key>
+        <string>Addons</string>
+    </dict>
+    
+    <key>App_Addons_(Iconoclasm)</key>
+    <dict>
+        <key>Rename</key>
+        <string>Addons_(Iconoclasm)</string>
+    </dict>
+    
+    <key>BossPaper_Addons</key>
+    <dict>
+        <key>Rename</key>
+        <string>Addons_(BossPaper)</string>
+    </dict>
+</dict>
+
+</plist>
diff --git a/MobileCydia.app/Sections/Administration.png b/MobileCydia.app/Sections/Administration.png
new file mode 100644 (file)
index 0000000..65efd3e
Binary files /dev/null and b/MobileCydia.app/Sections/Administration.png differ
diff --git a/MobileCydia.app/Sections/App Addons.png b/MobileCydia.app/Sections/App Addons.png
new file mode 100644 (file)
index 0000000..424f565
Binary files /dev/null and b/MobileCydia.app/Sections/App Addons.png differ
diff --git a/MobileCydia.app/Sections/Archiving.png b/MobileCydia.app/Sections/Archiving.png
new file mode 100644 (file)
index 0000000..9efce56
Binary files /dev/null and b/MobileCydia.app/Sections/Archiving.png differ
diff --git a/MobileCydia.app/Sections/Blanks.png b/MobileCydia.app/Sections/Blanks.png
new file mode 100644 (file)
index 0000000..7c0c2a0
Binary files /dev/null and b/MobileCydia.app/Sections/Blanks.png differ
diff --git a/MobileCydia.app/Sections/Carrier Bundles.png b/MobileCydia.app/Sections/Carrier Bundles.png
new file mode 100644 (file)
index 0000000..00f36f7
Binary files /dev/null and b/MobileCydia.app/Sections/Carrier Bundles.png differ
diff --git a/MobileCydia.app/Sections/Communication.png b/MobileCydia.app/Sections/Communication.png
new file mode 100644 (file)
index 0000000..00f36f7
Binary files /dev/null and b/MobileCydia.app/Sections/Communication.png differ
diff --git a/MobileCydia.app/Sections/Data Storage.png b/MobileCydia.app/Sections/Data Storage.png
new file mode 100644 (file)
index 0000000..1bb23fe
Binary files /dev/null and b/MobileCydia.app/Sections/Data Storage.png differ
diff --git a/MobileCydia.app/Sections/Development.png b/MobileCydia.app/Sections/Development.png
new file mode 100644 (file)
index 0000000..806b442
Binary files /dev/null and b/MobileCydia.app/Sections/Development.png differ
diff --git a/MobileCydia.app/Sections/Dictionaries.png b/MobileCydia.app/Sections/Dictionaries.png
new file mode 100644 (file)
index 0000000..e386e76
Binary files /dev/null and b/MobileCydia.app/Sections/Dictionaries.png differ
diff --git a/MobileCydia.app/Sections/Education.png b/MobileCydia.app/Sections/Education.png
new file mode 100644 (file)
index 0000000..4a2a03f
Binary files /dev/null and b/MobileCydia.app/Sections/Education.png differ
diff --git a/MobileCydia.app/Sections/Entertainment.png b/MobileCydia.app/Sections/Entertainment.png
new file mode 100644 (file)
index 0000000..69c8214
Binary files /dev/null and b/MobileCydia.app/Sections/Entertainment.png differ
diff --git a/MobileCydia.app/Sections/Games.png b/MobileCydia.app/Sections/Games.png
new file mode 100644 (file)
index 0000000..6e14c50
Binary files /dev/null and b/MobileCydia.app/Sections/Games.png differ
diff --git a/MobileCydia.app/Sections/Health and Fitness.png b/MobileCydia.app/Sections/Health and Fitness.png
new file mode 100644 (file)
index 0000000..e2db013
Binary files /dev/null and b/MobileCydia.app/Sections/Health and Fitness.png differ
diff --git a/MobileCydia.app/Sections/Imaging.png b/MobileCydia.app/Sections/Imaging.png
new file mode 100644 (file)
index 0000000..1e8f7fa
Binary files /dev/null and b/MobileCydia.app/Sections/Imaging.png differ
diff --git a/MobileCydia.app/Sections/Java.png b/MobileCydia.app/Sections/Java.png
new file mode 100644 (file)
index 0000000..e6bbc91
Binary files /dev/null and b/MobileCydia.app/Sections/Java.png differ
diff --git a/MobileCydia.app/Sections/Keyboards.png b/MobileCydia.app/Sections/Keyboards.png
new file mode 100644 (file)
index 0000000..6b3df89
Binary files /dev/null and b/MobileCydia.app/Sections/Keyboards.png differ
diff --git a/MobileCydia.app/Sections/Localization.png b/MobileCydia.app/Sections/Localization.png
new file mode 100644 (file)
index 0000000..80d41d3
Binary files /dev/null and b/MobileCydia.app/Sections/Localization.png differ
diff --git a/MobileCydia.app/Sections/Messaging.png b/MobileCydia.app/Sections/Messaging.png
new file mode 100644 (file)
index 0000000..69d18e0
Binary files /dev/null and b/MobileCydia.app/Sections/Messaging.png differ
diff --git a/MobileCydia.app/Sections/Multimedia.png b/MobileCydia.app/Sections/Multimedia.png
new file mode 100644 (file)
index 0000000..42d0b5e
Binary files /dev/null and b/MobileCydia.app/Sections/Multimedia.png differ
diff --git a/MobileCydia.app/Sections/Navigation.png b/MobileCydia.app/Sections/Navigation.png
new file mode 100644 (file)
index 0000000..4829e62
Binary files /dev/null and b/MobileCydia.app/Sections/Navigation.png differ
diff --git a/MobileCydia.app/Sections/Networking.png b/MobileCydia.app/Sections/Networking.png
new file mode 100644 (file)
index 0000000..a4f04e3
Binary files /dev/null and b/MobileCydia.app/Sections/Networking.png differ
diff --git a/MobileCydia.app/Sections/Packaging.png b/MobileCydia.app/Sections/Packaging.png
new file mode 100644 (file)
index 0000000..d7d914e
Binary files /dev/null and b/MobileCydia.app/Sections/Packaging.png differ
diff --git a/MobileCydia.app/Sections/Planet-iPhones Mods.png b/MobileCydia.app/Sections/Planet-iPhones Mods.png
new file mode 100644 (file)
index 0000000..e641970
Binary files /dev/null and b/MobileCydia.app/Sections/Planet-iPhones Mods.png differ
diff --git a/MobileCydia.app/Sections/Productivity.png b/MobileCydia.app/Sections/Productivity.png
new file mode 100644 (file)
index 0000000..c99c69d
Binary files /dev/null and b/MobileCydia.app/Sections/Productivity.png differ
diff --git a/MobileCydia.app/Sections/Repositories.png b/MobileCydia.app/Sections/Repositories.png
new file mode 100644 (file)
index 0000000..d6fe267
Binary files /dev/null and b/MobileCydia.app/Sections/Repositories.png differ
diff --git a/MobileCydia.app/Sections/Ringtones.png b/MobileCydia.app/Sections/Ringtones.png
new file mode 100644 (file)
index 0000000..57fd660
Binary files /dev/null and b/MobileCydia.app/Sections/Ringtones.png differ
diff --git a/MobileCydia.app/Sections/SBSettings Addons.png b/MobileCydia.app/Sections/SBSettings Addons.png
new file mode 100644 (file)
index 0000000..571555a
Binary files /dev/null and b/MobileCydia.app/Sections/SBSettings Addons.png differ
diff --git a/MobileCydia.app/Sections/Scripting.png b/MobileCydia.app/Sections/Scripting.png
new file mode 100644 (file)
index 0000000..22285d2
Binary files /dev/null and b/MobileCydia.app/Sections/Scripting.png differ
diff --git a/MobileCydia.app/Sections/Security.png b/MobileCydia.app/Sections/Security.png
new file mode 100644 (file)
index 0000000..ae142eb
Binary files /dev/null and b/MobileCydia.app/Sections/Security.png differ
diff --git a/MobileCydia.app/Sections/Social.png b/MobileCydia.app/Sections/Social.png
new file mode 100644 (file)
index 0000000..6c0cfa4
Binary files /dev/null and b/MobileCydia.app/Sections/Social.png differ
diff --git a/MobileCydia.app/Sections/System.png b/MobileCydia.app/Sections/System.png
new file mode 100644 (file)
index 0000000..19d2c22
Binary files /dev/null and b/MobileCydia.app/Sections/System.png differ
diff --git a/MobileCydia.app/Sections/Terminal Support.png b/MobileCydia.app/Sections/Terminal Support.png
new file mode 100644 (file)
index 0000000..d664618
Binary files /dev/null and b/MobileCydia.app/Sections/Terminal Support.png differ
diff --git a/MobileCydia.app/Sections/Text Editors.png b/MobileCydia.app/Sections/Text Editors.png
new file mode 100644 (file)
index 0000000..5e65d46
Binary files /dev/null and b/MobileCydia.app/Sections/Text Editors.png differ
diff --git a/MobileCydia.app/Sections/Themes.png b/MobileCydia.app/Sections/Themes.png
new file mode 100644 (file)
index 0000000..e35b948
Binary files /dev/null and b/MobileCydia.app/Sections/Themes.png differ
diff --git a/MobileCydia.app/Sections/Toys.png b/MobileCydia.app/Sections/Toys.png
new file mode 100644 (file)
index 0000000..368eb4c
Binary files /dev/null and b/MobileCydia.app/Sections/Toys.png differ
diff --git a/MobileCydia.app/Sections/Tweaks.png b/MobileCydia.app/Sections/Tweaks.png
new file mode 100644 (file)
index 0000000..4f588c6
Binary files /dev/null and b/MobileCydia.app/Sections/Tweaks.png differ
diff --git a/MobileCydia.app/Sections/Utilities.png b/MobileCydia.app/Sections/Utilities.png
new file mode 100644 (file)
index 0000000..fab5d32
Binary files /dev/null and b/MobileCydia.app/Sections/Utilities.png differ
diff --git a/MobileCydia.app/Sections/Wallpaper.png b/MobileCydia.app/Sections/Wallpaper.png
new file mode 100644 (file)
index 0000000..1060fa0
Binary files /dev/null and b/MobileCydia.app/Sections/Wallpaper.png differ
diff --git a/MobileCydia.app/Sections/WebClips.png b/MobileCydia.app/Sections/WebClips.png
new file mode 100644 (file)
index 0000000..7ed4053
Binary files /dev/null and b/MobileCydia.app/Sections/WebClips.png differ
diff --git a/MobileCydia.app/Sections/Widgets.png b/MobileCydia.app/Sections/Widgets.png
new file mode 100644 (file)
index 0000000..ca8c1ef
Binary files /dev/null and b/MobileCydia.app/Sections/Widgets.png differ
diff --git a/MobileCydia.app/Sections/X Window.png b/MobileCydia.app/Sections/X Window.png
new file mode 100644 (file)
index 0000000..eac01e9
Binary files /dev/null and b/MobileCydia.app/Sections/X Window.png differ
diff --git a/MobileCydia.app/Sections/eBooks.png b/MobileCydia.app/Sections/eBooks.png
new file mode 100644 (file)
index 0000000..512c68b
Binary files /dev/null and b/MobileCydia.app/Sections/eBooks.png differ
diff --git a/MobileCydia.app/Sources/cy.sosiphone.com.png b/MobileCydia.app/Sources/cy.sosiphone.com.png
new file mode 100644 (file)
index 0000000..b848d95
Binary files /dev/null and b/MobileCydia.app/Sources/cy.sosiphone.com.png differ
diff --git a/MobileCydia.app/Sources/iphone.hackndev.org.png b/MobileCydia.app/Sources/iphone.hackndev.org.png
new file mode 100644 (file)
index 0000000..1f701df
Binary files /dev/null and b/MobileCydia.app/Sources/iphone.hackndev.org.png differ
diff --git a/MobileCydia.app/Sources/iphonehe.com.png b/MobileCydia.app/Sources/iphonehe.com.png
new file mode 100644 (file)
index 0000000..b20263e
Binary files /dev/null and b/MobileCydia.app/Sources/iphonehe.com.png differ
diff --git a/MobileCydia.app/Sources/urbanfanatics.com.png b/MobileCydia.app/Sources/urbanfanatics.com.png
new file mode 100644 (file)
index 0000000..9cf47c4
Binary files /dev/null and b/MobileCydia.app/Sources/urbanfanatics.com.png differ
diff --git a/MobileCydia.app/Sources/www.zodttd.com.png b/MobileCydia.app/Sources/www.zodttd.com.png
new file mode 100644 (file)
index 0000000..83a3b33
Binary files /dev/null and b/MobileCydia.app/Sources/www.zodttd.com.png differ
diff --git a/MobileCydia.app/Test b/MobileCydia.app/Test
new file mode 100755 (executable)
index 0000000..123c7eb
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+killall Cydia_
+set -e
+rsync -SPaz --copy-links saurik@carrier.saurik.com:menes/cydia/cydia_iphoneos-arm.deb .
+dpkg -i cydia_iphoneos-arm.deb
+touch /tmp/cydia.log
+chown mobile.mobile /tmp/cydia.log
+uiopen "${1-cydia://}"
+exec tail /var/log/syslog /tmp/cydia.log -fn0
diff --git a/MobileCydia.app/advanced.png b/MobileCydia.app/advanced.png
new file mode 100644 (file)
index 0000000..419ba52
Binary files /dev/null and b/MobileCydia.app/advanced.png differ
diff --git a/MobileCydia.app/changes.png b/MobileCydia.app/changes.png
new file mode 100644 (file)
index 0000000..654208f
Binary files /dev/null and b/MobileCydia.app/changes.png differ
diff --git a/MobileCydia.app/changes@2x.png b/MobileCydia.app/changes@2x.png
new file mode 100644 (file)
index 0000000..aa6a29a
Binary files /dev/null and b/MobileCydia.app/changes@2x.png differ
diff --git a/MobileCydia.app/chevron@2x.png b/MobileCydia.app/chevron@2x.png
new file mode 100644 (file)
index 0000000..9905c17
Binary files /dev/null and b/MobileCydia.app/chevron@2x.png differ
diff --git a/MobileCydia.app/commercial.png b/MobileCydia.app/commercial.png
new file mode 100644 (file)
index 0000000..8599f48
Binary files /dev/null and b/MobileCydia.app/commercial.png differ
diff --git a/MobileCydia.app/compose.png b/MobileCydia.app/compose.png
new file mode 100644 (file)
index 0000000..1141d5d
Binary files /dev/null and b/MobileCydia.app/compose.png differ
diff --git a/MobileCydia.app/configure.png b/MobileCydia.app/configure.png
new file mode 100644 (file)
index 0000000..c27618d
Binary files /dev/null and b/MobileCydia.app/configure.png differ
diff --git a/MobileCydia.app/confirm.html b/MobileCydia.app/confirm.html
new file mode 100644 (file)
index 0000000..5a4ed55
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="CONFIRM"></title>
+    <meta name="viewport" content="width=320, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="confirm.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+</head><body class="pinstripe">
+<panel id="issues">
+
+<fieldset class="issues">
+    <div><p><span style="color: red; font-weight: bold" localize="NOTE"></span>: <span localize="CANNOT_COMPLY_EX"></span></p></div>
+</fieldset>
+
+<label class="_issues" localize="STATISTICS"></label>
+<fieldset class="_issues">
+    <div class="downloading"><div>
+        <label localize="DOWNLOADING"></label>
+        <label id="downloading"></label>
+    </div></div>
+
+    <div class="resuming"><div>
+        <label localize="RESUMING_AT"></label>
+        <label id="resuming"></label>
+    </div></div>
+</fieldset>
+
+<label localize="MODIFICATIONS"></label>
+<fieldset id="modifications">
+</fieldset>
+
+<fieldset class="queue" style="margin-top: 25px;">
+<a href="javascript:queue();" style="text-align: center; color: #2a3f70; font-size: 15px; background-image: none;">
+    <label localize="CONTINUE_QUEUING"></label>
+</div></a>
+</fieldset>
+
+</panel>
+</body></html>
diff --git a/MobileCydia.app/confirm.js b/MobileCydia.app/confirm.js
new file mode 100644 (file)
index 0000000..efffdc4
--- /dev/null
@@ -0,0 +1,73 @@
+$(function () {
+    if (issues == null) {
+        $(".issues").remove();
+
+        var downloading = sizes[0];
+        if (downloading == "0.0 B")
+            $(".downloading").remove();
+        else
+        $("#downloading").html($.xml(downloading));
+
+        var resuming = sizes[1];
+        if (resuming == "0.0 B")
+            $(".resuming").remove();
+        else
+        $("#resuming").html($.xml(resuming));
+    } else for (var i = 0; i != issues.length; ++i) {
+        document.title = cydia.localize("CANNOT_COMPLY");
+
+        $(".queue").remove();
+
+        $("._issues").remove();
+
+        var issue = issues[i];
+
+        $("#issues").append(
+            "<label style=\"color: #704d4d\">" + $.xml(issue[0]) + "</label>" +
+            "<fieldset style=\"background-color: #dddddd\" class=\"clearfix\" id=\"i" + i + "\"></fieldset>"
+        );
+
+        for (var j = 1; j != issue.length; ++j) {
+            var entry = issue[j];
+            var type = entry[0];
+            if (type == "PreDepends")
+                type = "Depends";
+            var version = entry[1];
+            if (entry.length >= 4)
+                version += " " + entry[3];
+            $("#i" + i).append("<div class=\"clearfix\"><div>" +
+                "<label>" + $.xml(type) + "</label>" +
+                "<label>" + $.xml(version) + "</label>" +
+            "</div></div>");
+        }
+    }
+
+    var keys = [
+        "INSTALL",
+        "REINSTALL",
+        "UPGRADE",
+        "DOWNGRADE",
+        "REMOVE"
+    ];
+
+    for (var i = 0; i != 5; ++i) {
+        var list = changes[i];
+        var length = list.length;
+
+        if (length != 0) {
+            $("#modifications").append("<div class=\"clearfix\"><div>" +
+                "<label>" + cydia.localize($.xml(keys[i])) + "</label>" +
+                "<label id=\"c" + i + "\"></label>" +
+            "</div></div>");
+
+            var value = "";
+            for (var j = 0; j != length; ++j) {
+                if (j != 0)
+                    value += "<br/>";
+                value += $.xml(list[j]);
+            }
+
+            $("#c" + i).html(value);
+        }
+    }
+});
diff --git a/MobileCydia.app/console.png b/MobileCydia.app/console.png
new file mode 100644 (file)
index 0000000..dba3788
Binary files /dev/null and b/MobileCydia.app/console.png differ
diff --git a/MobileCydia.app/email.png b/MobileCydia.app/email.png
new file mode 100644 (file)
index 0000000..1aa20b3
Binary files /dev/null and b/MobileCydia.app/email.png differ
diff --git a/MobileCydia.app/error.html b/MobileCydia.app/error.html
new file mode 100644 (file)
index 0000000..a68ff76
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="NETWORK_ERROR"></title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+
+    <style>
+        body {
+            background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
+            background-size: 7px 1px;
+            display: table;
+            font-family: Helvetica;
+            height: 337px;
+            margin: 0;
+            text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0
+        }
+
+        div.page {
+            display: table-cell;
+            text-align: center;
+            margin: 0 auto;
+            vertical-align: middle;
+            width: 320px;
+        }
+
+        div.title {
+            font-size: 32px;
+        }
+
+        div.error {
+            font-size: 24px;
+        }
+    </style>
+</head><body><div class="page">
+
+<div class="title" localize="UNABLE_TO_LOAD"></div>
+
+<div class="error">(<script>
+    document.write(decodeURI(location.search.substring(1)));
+</script>)</div>
+
+</div></body></html>
diff --git a/MobileCydia.app/expanded.png b/MobileCydia.app/expanded.png
new file mode 100644 (file)
index 0000000..9efce56
Binary files /dev/null and b/MobileCydia.app/expanded.png differ
diff --git a/MobileCydia.app/filesystem.png b/MobileCydia.app/filesystem.png
new file mode 100644 (file)
index 0000000..1bb23fe
Binary files /dev/null and b/MobileCydia.app/filesystem.png differ
diff --git a/MobileCydia.app/folder.png b/MobileCydia.app/folder.png
new file mode 100644 (file)
index 0000000..b628e95
Binary files /dev/null and b/MobileCydia.app/folder.png differ
diff --git a/MobileCydia.app/folder@2x.png b/MobileCydia.app/folder@2x.png
new file mode 100644 (file)
index 0000000..af3009c
Binary files /dev/null and b/MobileCydia.app/folder@2x.png differ
diff --git a/MobileCydia.app/green-dn.png b/MobileCydia.app/green-dn.png
new file mode 100644 (file)
index 0000000..c311acd
Binary files /dev/null and b/MobileCydia.app/green-dn.png differ
diff --git a/MobileCydia.app/green-up.png b/MobileCydia.app/green-up.png
new file mode 100644 (file)
index 0000000..c335b24
Binary files /dev/null and b/MobileCydia.app/green-up.png differ
diff --git a/MobileCydia.app/home-Selected.png b/MobileCydia.app/home-Selected.png
new file mode 100644 (file)
index 0000000..c02c120
Binary files /dev/null and b/MobileCydia.app/home-Selected.png differ
diff --git a/MobileCydia.app/home-Selected@2x.png b/MobileCydia.app/home-Selected@2x.png
new file mode 100644 (file)
index 0000000..748be33
Binary files /dev/null and b/MobileCydia.app/home-Selected@2x.png differ
diff --git a/MobileCydia.app/home.png b/MobileCydia.app/home.png
new file mode 100644 (file)
index 0000000..0611697
Binary files /dev/null and b/MobileCydia.app/home.png differ
diff --git a/MobileCydia.app/home@2x.png b/MobileCydia.app/home@2x.png
new file mode 100644 (file)
index 0000000..72b7297
Binary files /dev/null and b/MobileCydia.app/home@2x.png differ
diff --git a/MobileCydia.app/icon-72.png b/MobileCydia.app/icon-72.png
new file mode 100644 (file)
index 0000000..1dbce13
Binary files /dev/null and b/MobileCydia.app/icon-72.png differ
diff --git a/MobileCydia.app/icon.png b/MobileCydia.app/icon.png
new file mode 100644 (file)
index 0000000..61d51dd
Binary files /dev/null and b/MobileCydia.app/icon.png differ
diff --git a/MobileCydia.app/icon@2x.png b/MobileCydia.app/icon@2x.png
new file mode 100644 (file)
index 0000000..1ec010c
Binary files /dev/null and b/MobileCydia.app/icon@2x.png differ
diff --git a/MobileCydia.app/iconClassic.png b/MobileCydia.app/iconClassic.png
new file mode 100644 (file)
index 0000000..384c582
Binary files /dev/null and b/MobileCydia.app/iconClassic.png differ
diff --git a/MobileCydia.app/id.png b/MobileCydia.app/id.png
new file mode 100644 (file)
index 0000000..f168812
Binary files /dev/null and b/MobileCydia.app/id.png differ
diff --git a/MobileCydia.app/install.png b/MobileCydia.app/install.png
new file mode 100644 (file)
index 0000000..9e30898
Binary files /dev/null and b/MobileCydia.app/install.png differ
diff --git a/MobileCydia.app/install@2x.png b/MobileCydia.app/install@2x.png
new file mode 100644 (file)
index 0000000..dfb8212
Binary files /dev/null and b/MobileCydia.app/install@2x.png differ
diff --git a/MobileCydia.app/installed.png b/MobileCydia.app/installed.png
new file mode 100644 (file)
index 0000000..2f86f0a
Binary files /dev/null and b/MobileCydia.app/installed.png differ
diff --git a/MobileCydia.app/installed@2x.png b/MobileCydia.app/installed@2x.png
new file mode 100644 (file)
index 0000000..ab86df2
Binary files /dev/null and b/MobileCydia.app/installed@2x.png differ
diff --git a/MobileCydia.app/installing.png b/MobileCydia.app/installing.png
new file mode 100644 (file)
index 0000000..6332fef
Binary files /dev/null and b/MobileCydia.app/installing.png differ
diff --git a/MobileCydia.app/loading.html b/MobileCydia.app/loading.html
new file mode 100644 (file)
index 0000000..33b2637
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title>Loading</title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <base target="_blank"/>
+</head><body>
+    <div style="padding: 5px 7px">
+        <span style="color: #4d4d70; font-weight: normal; font-size: 16px">
+            <div style="display: inline-block; background-image: url(menes/indicator-c7ced5-4d4d70.gif); width: 16px; height: 16px; margin: 2px 0 -2px 0"></div>
+            <span style="margin: 0 4px">Loading...</span>
+        </span>
+    </div>
+</body></html>
diff --git a/MobileCydia.app/localize.js b/MobileCydia.app/localize.js
new file mode 100644 (file)
index 0000000..9be82d0
--- /dev/null
@@ -0,0 +1,15 @@
+document.addEventListener("DOMContentLoaded", function () {
+    var results = document.evaluate("//*[@localize]", document, null, XPathResult.ANY_TYPE, null);
+    var result, nodes = [];
+    while (result = results.iterateNext())
+        nodes.push(result);
+    for (var index in nodes) {
+        var node = nodes[index];
+        var key = node.getAttribute('localize');
+        var value = cydia.localize(key, node.innerHTML);
+        if (node.nodeName == 'TITLE')
+            document.title = value;
+        else
+            node.innerHTML = value;
+    }
+});
diff --git a/MobileCydia.app/manage.html b/MobileCydia.app/manage.html
new file mode 100644 (file)
index 0000000..bba3762
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="MANAGE"></title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+
+    <style>
+        body {
+            background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
+            background-size: 7px 1px;
+            display: table;
+            font-family: Helvetica;
+            height: 337px;
+            margin: 0;
+            padding: 0;
+            -webkit-text-size-adjust: none;
+            -webkit-user-select: none;
+        }
+
+        div.page {
+            display: table-cell;
+            text-align: center;
+            margin: 0 auto;
+            vertical-align: middle;
+            width: 320px;
+        }
+
+        a.giant-button {
+            background-color: rgba(0, 0, 0, .15);
+            -webkit-border-radius: 10px;
+            color: #193250;
+            display: block;
+            margin: 10px;
+            text-decoration: none;
+        }
+
+        a.giant-button > img {
+            display: inline-block;
+            float: left;
+            height: 80px;
+            margin: 10px -10px 0 10px;
+            width: 80px;
+            vertical-align: middle;
+        }
+
+        a.giant-button > div.contents {
+            display: inline-block;
+            width: 190px;
+            margin: 5px 10px 17px 10px;
+        }
+
+        a.giant-button > div.contents > label {
+            display: block;
+            font-size: 28px;
+            margin: 8px 0 8px 0;
+            text-align: center;
+            text-shadow: rgba(200, 200, 200, 0.75) 1px 1px 0;
+        }
+
+        a.giant-button > div.contents > div {
+            display: block;
+            font-size: 14px;
+            margin-left: 4px;
+            text-align: center;
+        }
+    </style>
+</head><body><div class="page">
+<div class="dialog">
+    <div class="panel">
+
+<a href="cydia://packages" class="giant-button">
+    <img src="packages.png"/>
+    <div class="contents">
+        <label localize="PACKAGES"></label>
+        <div localize="PACKAGES_EX"></div>
+    </div>
+</a>
+
+<a href="cydia://sources" class="giant-button">
+    <img src="sources.png"/>
+    <div class="contents">
+        <label localize="SOURCES"></label>
+        <div localize="SOURCES_EX"></div>
+    </div>
+</a>
+
+<a href="cydia://storage" class="giant-button">
+    <img src="storage.png"/>
+    <div class="contents">
+        <label localize="STORAGE"></label>
+        <div localize="STORAGE_EX"></div>
+    </div>
+</a>
+
+    </div>
+</div>
+</div></body></html>
diff --git a/MobileCydia.app/manage.png b/MobileCydia.app/manage.png
new file mode 100644 (file)
index 0000000..9513a7c
Binary files /dev/null and b/MobileCydia.app/manage.png differ
diff --git a/MobileCydia.app/manage@2x.png b/MobileCydia.app/manage@2x.png
new file mode 100644 (file)
index 0000000..cfb8c13
Binary files /dev/null and b/MobileCydia.app/manage@2x.png differ
diff --git a/MobileCydia.app/menes/chevron.png b/MobileCydia.app/menes/chevron.png
new file mode 100644 (file)
index 0000000..6ff8205
Binary files /dev/null and b/MobileCydia.app/menes/chevron.png differ
diff --git a/MobileCydia.app/menes/chevron@2x.png b/MobileCydia.app/menes/chevron@2x.png
new file mode 100644 (file)
index 0000000..9905c17
Binary files /dev/null and b/MobileCydia.app/menes/chevron@2x.png differ
diff --git a/MobileCydia.app/menes/indicator-c7ced5-4d4d70.gif b/MobileCydia.app/menes/indicator-c7ced5-4d4d70.gif
new file mode 100644 (file)
index 0000000..e41bb96
Binary files /dev/null and b/MobileCydia.app/menes/indicator-c7ced5-4d4d70.gif differ
diff --git a/MobileCydia.app/menes/menes.js b/MobileCydia.app/menes/menes.js
new file mode 100644 (file)
index 0000000..dc210bb
--- /dev/null
@@ -0,0 +1,575 @@
+/* XXX: this message is ultra-lame */
+var _assert = function (expr, value) {
+    if (!expr) {
+        var message = "_assert(" + value + ")";
+        console.log(message);
+        throw message;
+    }
+}
+
+// Compatibility {{{
+if (typeof Array.prototype.push != "function")
+    Array.prototype.push = function (value) {
+        this[this.length] = value;
+    };
+// }}}
+
+var $ = function (arg, doc) {
+    if (this.magic_ != $.prototype.magic_)
+        return new $(arg);
+
+    if (arg == null)
+        arg = [];
+
+    var type = $.type(arg);
+
+    if (type == "function")
+        $.ready(arg);
+    else if (type == "string") {
+        if (typeof doc == 'undefined')
+            doc = document;
+        if (arg.charAt(0) == '#') {
+            /* XXX: this is somewhat incorrect-a-porter */
+            var element = doc.getElementById(arg.substring(1));
+            return $(element == null ? [] : [element]);
+        } else if (arg.charAt(0) == '.')
+            return $(doc.getElementsByClassName(arg.substring(1)));
+        else
+            return $([doc]).descendants(arg);
+    } else if (typeof arg.length != 'undefined') {
+        _assert(typeof doc == 'undefined', "non-query with document to $");
+        this.set(arg);
+        return this;
+    } else _assert(false, "unknown argument to $: " + typeof arg);
+};
+
+$.xml = function (value) {
+    return value
+        .replace(/&/, "&amp;")
+        .replace(/</, "&lt;")
+        .replace(/>/, "&gt;")
+        .replace(/"/, "&quot;")
+        .replace(/'/, "&apos;")
+    ;
+}
+
+$.type = function (value) {
+    var type = typeof value;
+
+    if ((type == "function" || type == "object") && value.toString != null) {
+        var string = value.toString();
+        if (string.substring(0, 8) == "[object ")
+            return string.substring(8, string.length - 1);
+    }
+
+    return type;
+};
+
+(function () {
+    var ready_ = null;
+
+    $.ready = function (_function) {
+        if (ready_ == null) {
+            ready_ = [];
+
+            document.addEventListener("DOMContentLoaded", function () {
+                for (var i = 0; i != ready_.length; ++i)
+                    ready_[i]();
+            }, false);
+        }
+
+        ready_.push(_function);
+    };
+})();
+
+/* XXX: verify arg3 overflow */
+$.each = function (values, _function, arg0, arg1, arg2) {
+    for (var i = 0, e = values.length; i != e; ++i)
+        _function(values[i], arg0, arg1, arg2);
+};
+
+/* XXX: verify arg3 overflow */
+$.map = function (values, _function, arg0, arg1, arg2) {
+    var mapped = [];
+    for (var i = 0, e = values.length; i != e; ++i)
+        mapped.push(_function(values[i], arg0, arg1, arg2));
+    return mapped;
+};
+
+$.array = function (values) {
+    if (values.constructor == Array)
+        return values;
+    _assert(typeof values.length != 'undefined', "$.array on underlying non-array");
+    var array = [];
+    for (var i = 0; i != values.length; ++i)
+        array.push(values[i]);
+    return array;
+};
+
+$.document = function (node) {
+    for (;;) {
+        var parent = node.parentNode;
+        if (parent == null)
+            return node;
+        node = parent;
+    }
+};
+
+$.reclass = function (_class) {
+    return new RegExp('(\\s|^)' + _class + '(\\s|$)');
+};
+
+$.prototype = {
+    magic_: 2041085062,
+
+    add: function (nodes) {
+        Array.prototype.push.apply(this, $.array(nodes));
+    },
+
+    at: function (name, value) {
+        if (typeof value == 'undefined')
+            return $.map(this, function (node) {
+                return node.getAttribute(name);
+            });
+        else if (value == null)
+            $.each(this, function (node) {
+                node.removeAttribute();
+            });
+        else
+            $.each(this, function (node) {
+                node.setAttribute(name, value);
+            });
+    },
+
+    set: function (nodes) {
+        this.length = 0;
+        this.add(nodes);
+    },
+
+    /* XXX: verify arg3 overflow */
+    each: function (_function, arg0, arg1, arg2) {
+        $.each(this, function (node) {
+            _function($([node]), arg0, arg1, arg2);
+        });
+    },
+
+    css: function (name, value) {
+        $.each(this, function (node) {
+            node.style[name] = value;
+        });
+    },
+
+    addClass: function (_class) {
+        $.each(this, function (node) {
+            if (!$([node]).hasClass(_class)[0])
+                node.className += " " + _class;
+        });
+    },
+
+    blur: function () {
+        $.each(this, function (node) {
+            node.blur();
+        });
+    },
+
+    focus: function () {
+        $.each(this, function (node) {
+            node.focus();
+        });
+    },
+
+    removeClass: function (_class) {
+        $.each(this, function (node) {
+            node.className = node.className.replace($.reclass(_class), ' ');
+        });
+    },
+
+    hasClass: function (_class) {
+        return $.map(this, function (node) {
+            return node.className.match($.reclass(_class));
+        });
+    },
+
+    append: function (children) {
+        if ($.type(children) == "string")
+            $.each(this, function (node) {
+                var doc = $.document(node);
+
+                // XXX: implement wrapper system
+                var div = doc.createElement("div");
+                div.innerHTML = children;
+
+                while (div.childNodes.length != 0) {
+                    var child = div.childNodes[0];
+                    node.appendChild(child);
+                }
+            });
+        else
+            $.each(this, function (node) {
+                $.each(children, function (child) {
+                    node.appendChild(child);
+                });
+            });
+    },
+
+    xpath: function (expression) {
+        var value = $([]);
+
+        $.each(this, function (node) {
+            var doc = $.document(node);
+            var results = doc.evaluate(expression, node, null, XPathResult.ANY_TYPE, null);
+            var result;
+            while (result = results.iterateNext())
+                value.add([result]);
+        });
+
+        return value;
+    },
+
+    clone: function (deep) {
+        return $($.map(this, function (node) {
+            return node.cloneNode(deep);
+        }));
+    },
+
+    descendants: function (expression) {
+        var descendants = $([]);
+
+        $.each(this, function (node) {
+            var nodes = node.getElementsByTagName(expression);
+            descendants.add(nodes);
+        });
+
+        return descendants;
+    },
+
+    remove: function () {
+        $.each(this, function (node) {
+            node.parentNode.removeChild(node);
+        });
+    }
+};
+
+$.scroll = function (x, y) {
+    window.scrollTo(x, y);
+};
+
+// XXX: document.all?
+$.all = function (doc) {
+    if (typeof doc == 'undefined')
+        doc = document;
+    return $(doc.getElementsByTagName("*"));
+};
+
+$.inject = function (a, b) {
+    if ($.type(a) == "string") {
+        $.prototype[a] = function (value) {
+            if (typeof value == 'undefined')
+                return $.map(this, function (node) {
+                    return b.get(node);
+                });
+            else
+                $.each(this, function (node, value) {
+                    b.set(node, value);
+                }, value);
+        };
+    } else for (var name in a)
+        $.inject(name, a[name]);
+};
+
+$.inject({
+    _default: {
+        get: function (node) {
+            return node.style.defaultValue;
+        },
+        set: function (node, value) {
+            node.style.defaultValue = value;
+        }
+    },
+
+    height: {
+        get: function (node) {
+            return node.height;
+        },
+        set: function (node, value) {
+            node.height = value;
+        }
+    },
+
+    html: {
+        get: function (node) {
+            return node.innerHTML;
+        },
+        set: function (node, value) {
+            node.innerHTML = value;
+        }
+    },
+
+    href: {
+        get: function (node) {
+            return node.href;
+        },
+        set: function (node, value) {
+            node.href = value;
+        }
+    },
+
+    name: {
+        get: function (node) {
+            return node.name;
+        },
+        set: function (node, value) {
+            node.name = value;
+        }
+    },
+
+    parent: {
+        get: function (node) {
+            return node.parentNode;
+        }
+    },
+
+    src: {
+        get: function (node) {
+            return node.src;
+        },
+        set: function (node, value) {
+            node.src = value;
+        }
+    },
+
+    type: {
+        get: function (node) {
+            return node.localName;
+        }
+    },
+
+    value: {
+        get: function (node) {
+            return node.value;
+        },
+        set: function (node, value) {
+            // XXX: do I really need this?
+            if (true || node.localName != "select")
+                node.value = value;
+            else {
+                var options = node.options;
+                for (var i = 0, e = options.length; i != e; ++i)
+                    if (options[i].value == value) {
+                        if (node.selectedIndex != i)
+                            node.selectedIndex = i;
+                        break;
+                    }
+            }
+        }
+    },
+
+    width: {
+        get: function (node) {
+            return node.offsetWidth;
+        }
+    }
+});
+
+// Query String Parsing {{{
+$.query = function () {
+    var args = {};
+
+    var search = location.search;
+    if (search != null) {
+        _assert(search[0] == "?", "query string without ?");
+
+        var values = search.substring(1).split("&");
+        for (var index in values) {
+            var value = values[index]
+            var equal = value.indexOf("=");
+            var name;
+
+            if (equal == -1) {
+                name = value;
+                value = null;
+            } else {
+                name = value.substring(0, equal);
+                value = value.substring(equal + 1);
+                value = decodeURIComponent(value);
+            }
+
+            name = decodeURIComponent(name);
+            if (typeof args[name] == "undefined")
+                args[name] = [];
+            if (value != null)
+                args[name].push(value);
+        }
+    }
+
+    return args;
+};
+// }}}
+// Event Registration {{{
+// XXX: unable to remove registration
+$.prototype.event = function (event, _function) {
+    $.each(this, function (node) {
+        // XXX: smooth over this pointer ugliness
+        if (node.addEventListener)
+            node.addEventListener(event, _function, false);
+        else if (node.attachEvent)
+            node.attachEvent("on" + event, _function);
+        else
+            // XXX: multiple registration SNAFU
+            node["on" + event] = _function;
+    });
+};
+
+$.each([
+    "click", "load", "submit"
+], function (event) {
+    $.prototype[event] = function (_function) {
+        if (typeof _function == 'undefined')
+            _assert(false, "undefined function to $.[event]");
+        else
+            this.event(event, _function);
+    };
+});
+// }}}
+// Timed Animation {{{
+$.interpolate = function (duration, event) {
+    var start = new Date();
+
+    var next = function () {
+        setTimeout(update, 0);
+    };
+
+    var update = function () {
+        var time = new Date() - start;
+
+        if (time >= duration)
+            event(1);
+        else {
+            event(time / duration);
+            next();
+        }
+    };
+
+    next();
+};
+// }}}
+// AJAX Requests {{{
+// XXX: abstract and implement other cases
+$.xhr = function (url, method, headers, data, events) {
+    var xhr = new XMLHttpRequest();
+    xhr.open(method, url, true);
+
+    for (var name in headers)
+        xhr.setRequestHeader(name.replace(/_/, "-"), headers[name]);
+
+    if (events == null)
+        events = {};
+
+    xhr.onreadystatechange = function () {
+        if (xhr.readyState == 4) {
+            var status = xhr.status;
+            var text = xhr.responseText;
+            if (events.response != null)
+                events.response(status, text);
+            if (status == 200) {
+                if (events.success != null)
+                    events.success(text);
+            } else {
+                if (events.failure != null)
+                    events.failure(status);
+            }
+        }
+    };
+
+    xhr.send(data);
+};
+
+$.call = function (url, post, onsuccess) {
+    var events = {};
+
+    if (onsuccess != null)
+        events.complete = function (text) {
+            onsuccess(eval(text));
+        };
+
+    if (post == null)
+        $.xhr(url, "POST", null, null, events);
+    else
+        $.xhr(url, "POST", {
+            Content_Type: "application/json"
+        }, $.json(post), events);
+};
+// }}}
+// WWW Form URL Encoder {{{
+$.form = function (parameters) {
+    var data = "";
+
+    var ampersand = false;
+    for (var name in parameters) {
+        if (!ampersand)
+            ampersand = true;
+        else
+            data += "&";
+
+        var value = parameters[name];
+
+        data += escape(name);
+        data += "=";
+        data += escape(value);
+    }
+
+    return data;
+};
+// }}}
+// JSON Serializer {{{
+$.json = function (value) {
+    if (value == null)
+        return "null";
+
+    var type = $.type(value);
+
+    if (type == "number")
+        return value;
+    else if (type == "string")
+        return "\"" + value
+            .replace(/\\/, "\\\\")
+            .replace(/\t/, "\\t")
+            .replace(/\r/, "\\r")
+            .replace(/\n/, "\\n")
+            .replace(/"/, "\\\"")
+        + "\"";
+    else if (value.constructor == Array) {
+        var json = "[";
+        var comma = false;
+
+        for (var i = 0; i != value.length; ++i) {
+            if (!comma)
+                comma = true;
+            else
+                json += ",";
+
+            json += $.json(value[i]);
+        }
+
+        return json + "]";
+    } else if (
+        value.constructor == Object &&
+        value.toString() == "[object Object]"
+    ) {
+        var json = "{";
+        var comma = false;
+
+        for (var name in value) {
+            if (!comma)
+                comma = true;
+            else
+                json += ",";
+
+            json += name + ":" + $.json(value[name]);
+        }
+        return json + "}";
+    } else {
+        return value;
+    }
+};
+// }}}
diff --git a/MobileCydia.app/menes/style.css b/MobileCydia.app/menes/style.css
new file mode 100644 (file)
index 0000000..677a2fc
--- /dev/null
@@ -0,0 +1,885 @@
+/* iPhone.css - iPhone Interface Cascading Style Sheet
+ * Copyright (C) 2007-2008  Jay Freeman (saurik)
+*/
+
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* .clearfix {{{ */
+.clearfix:after {
+    content: ".";
+    display: block;
+    clear: both;
+    visibility: hidden;
+    line-height: 0;
+    height: 0;
+}
+
+.clearfix {
+    display: block;
+}
+/* }}} */
+
+* {
+    border: 0;
+    -moz-border-radius: 0;
+    -webkit-border-radius: 0;
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    /*font-family: inherit;*/
+    font-size: 100%;
+    font-style: inherit;
+    font-weight: inherit;
+    margin: 0;
+    outline: 0;
+    padding: 0;
+    text-decoration: none;
+    vertical-align: baseline;
+}
+
+a {
+    color: inherit;
+}
+
+sup {
+    font-size: smaller;
+    margin-top: -6px;
+    position: relative;
+    top: -6px;
+}
+
+select {
+    border: 1px solid #999999;
+}
+
+panel {
+    display: block;
+    width: 320px;
+}
+
+body {
+    font-family: Helvetica, Arial;
+    -webkit-text-size-adjust: none;
+    -webkit-user-select: none;
+    margin: 0 auto;
+    width: 320px;
+}
+
+body.white {
+    background-color: #ffffff;
+}
+
+body.pinstripe {
+    background: #c7ced5 url(cydia://uikit-image/UIPinstripe.png);
+    background-size: 7px 1px;
+}
+
+dialog {
+    display: block;
+    position: absolute;
+    width: 100%;
+}
+
+dialog > panel {
+    display: block;
+}
+
+a {
+    color: blue;
+    text-underline-style: dotted;
+}
+
+strong {
+    font-weight: bold
+}
+
+pre, tt {
+    font-family: monospace;
+}
+
+pre {
+    letter-spacing: -2px;
+}
+
+em {
+    font-style: italic;
+}
+
+.default {
+    color: #aaaabb;
+}
+
+.deleted {
+    display: none;
+}
+
+/* #toolbar {{{ */
+dialog > toolbar {
+    background: url(toolbar.png) #6d84a2 repeat-x;
+    border-bottom: 1px solid #2d3642;
+    height: 45px;
+    padding: 10px;
+}
+
+dialog > toolbar > h1 {
+    color: #ffffff;
+    font-size: 20px;
+    font-weight: bold;
+    height: 100%;
+    margin: 1px auto 0 auto;
+    text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
+    text-align: center;
+    white-space: nowrap;
+}
+/* }}} */
+/* (back|forward)-button {{{ */
+dialog > toolbar > a.back-button,
+dialog > toolbar > a.forward-button {
+    color: #ffffff;
+    font-size: 12px;
+    font-weight: bold;
+    height: 30px;
+    line-height: 30px;
+    margin-top: -28px;
+    padding: 0 3px;
+    text-decoration: none;
+    text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
+    white-space: nowrap;
+}
+
+dialog > toolbar > a.back-button {
+    -webkit-border-image: url(backButton.png) 0 8 0 14;
+    border-width: 0 8px 0 14px;
+    float: left;
+}
+
+dialog > toolbar > a.forward-button {
+    -webkit-border-image: url(toolButton.png) 0 5 0 5;
+    border-width: 0 5px;
+    float: right;
+}
+/* }}} */
+
+panel > block {
+    /*background-color: #ccd1d5;*/
+    /*background-color: white;*/
+    /*background-color: #c7ced5;*/
+    background-color: transparent;
+    //background-color: #ffffff;
+    border-bottom: 1px solid #999999;
+    border-top: 1px solid #999999;
+    border-left: 1px dotted #999999;
+    border-right: 1px dotted #999999;
+    -moz-border-radius: 9px;
+    -webkit-border-radius: 9px;
+    //border: 1px solid #999999;
+    display: block;
+    font-size: 16px;
+    margin: 9px;
+    padding: 0 10px;
+}
+
+panel > fieldset > div > hr,
+panel > block > hr {
+    border-top: 1px dashed #999999;
+}
+
+panel > fieldset {
+    background-color: #ffffff;
+    border: 1px solid #999999;
+    -moz-border-radius: 9px;
+    -webkit-border-radius: 9px;
+    font-size: 16px;
+    margin: 9px;
+}
+
+panel > input[type="submit"] {
+    /*-webkit-border-image: url(whiteButton.png) 0 12 0 12;
+    -moz-border-radius: 0;
+    -webkit-border-radius: 0;
+    border-width: 0px 12px;*/
+    border: none;
+    color: #000000;
+    display: block;
+    font-size: 20px;
+    font-weight: bold;
+    margin: 9px;
+    height: 44px;
+    padding: 10px;
+    text-align: center;
+    width: 302px;
+}
+
+list > label {
+    background: #a7b3bc url(cydia://uikit-image/UISectionListHeaderBackground.png);
+    background-repeat: repeat-x no-repeat-y;
+    margin-bottom: 0px;
+    padding: 4px 15px 1px 15px;
+    display: block;
+    color: white;
+    font-size: inherit;
+    font-weight: bold;
+    text-shadow: rgba(0, 0, 0, 0.5) 0px 1px 0;
+}
+
+panel > label {
+    display: block;
+    margin: 13px 0 -4px 24px;
+    line-height: 24px;
+    font-size: inherit;
+    font-weight: bold;
+    color: #4d4d70;
+    text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0;
+}
+
+panel > fieldset > a,
+panel > fieldset > div,
+panel > fieldset > textarea {
+    border-top: 1px solid #999999;
+}
+
+/* XXX: should be a.left:nth-last-child(2) */
+panel > fieldset > a.left,
+panel > fieldset > a.middle,
+panel > fieldset > a:first-child,
+panel > fieldset > div:first-child,
+panel > fieldset > textarea:first-child {
+    border-top: 0;
+}
+
+list > fieldset > a,
+list > fieldset > div,
+list > fieldset > textarea {
+    border-bottom: 1px solid #e0e0e0;
+}
+
+fieldset > a:not([type="ad"]),
+fieldset > div,
+fieldset > textarea {
+    /* XXX: small differences due to font bugs */
+    padding: 12px 14px 10px 14px;
+}
+
+/*fieldset > a:not([type="ad"]):last-child,
+fieldset > div:last-child {
+    padding-bottom: 10px;
+}*/
+
+fieldset > a[type="ad"] {
+    /* XXX: small differences due to font bugs */
+    padding: 4px 4px 2px 5px;
+}
+
+panel > fieldset > a[type="ad"]:first-child > div:first-child,
+panel > fieldset > a[type="comment"]:first-child > div:first-child,
+panel > fieldset > a[type="profile"]:first-child > div:first-child,
+panel > fieldset > a[type="thumb"]:first-child > div:first-child {
+    -moz-border-radius-topleft: 9px;
+    -webkit-border-top-left-radius: 9px;
+}
+
+panel > fieldset > a[type="ad"]:last-child > div:first-child,
+panel > fieldset > a[type="comment"]:last-child > div:first-child,
+panel > fieldset > a[type="profile"]:last-child > div:first-child,
+panel > fieldset > a[type="thumb"]:last-child > div:first-child {
+    -moz-border-radius-bottomleft: 9px;
+    -webkit-border-bottom-left-radius: 9px;
+}
+
+fieldset > a[type="ad"] > div:first-child {
+    border: 1px solid #999999;
+}
+
+list > fieldset > a[type="comment"] > div:first-child,
+list > fieldset > a[type="profile"] > div:first-child,
+list > fieldset > a[type="thumb"] > div:first-child {
+    border: 1px solid #e0e0e0;
+}
+
+panel > fieldset > a[type="comment"] > div:first-child {
+    border: 1px solid #999999;
+    border-bottom-style: dashed;
+}
+
+panel > fieldset > a[type="profile"] > div:first-child,
+panel > fieldset:not(.header) > a[type="thumb"] > div:first-child {
+    border: 1px solid #999999;
+}
+
+div[tile] {
+    float: right;
+    height: 30px;
+    width: 30px;
+}
+
+div[tile="app"]   { background-image: url(http://cache.saurik.com/cydia/tile/app.png);   }
+div[tile="call"]  { background-image: url(http://cache.saurik.com/cydia/tile/call.png);  }
+div[tile="map"]   { background-image: url(http://cache.saurik.com/cydia/tile/map.png);   }
+div[tile="media"] { background-image: url(http://cache.saurik.com/cydia/tile/media.png); }
+div[tile="music"] { background-image: url(http://cache.saurik.com/cydia/tile/video.png); }
+div[tile="site"]  { background-image: url(http://cache.saurik.com/cydia/tile/site.png);  }
+
+fieldset > a[type="ad"] > div:first-child {
+    background-repeat: no-repeat;
+    background-position: center center;
+    border-right: none;
+    display: inline-block;
+    height: 40px;
+    line-height: 38px;
+    /* XXX: small differences due to font bugs */
+    /* XXX: 1px difference due to border stupidity */
+    margin: -5px 5px -3px -6px;
+    width: 40px;
+}
+
+panel > fieldset > a[type="comment"] {
+    border-bottom-style: dashed;
+}
+
+fieldset > a[type="comment"] > div:first-child {
+    -webkit-background-size: 44px;
+    height: 44px;
+    width: 44px;
+}
+
+fieldset > a[type="header"] > div:first-child {
+    height: 64px;
+    width: 64px;
+}
+
+fieldset > a[type="profile"] > div:first-child {
+    -webkit-background-size: 50px;
+    height: 50px;
+    width: 50px;
+}
+
+fieldset > a[type="thumb"] > div:first-child  {
+    height: 64px;
+    width: 64px;
+}
+
+fieldset > a[type="comment"] > div:first-child,
+fieldset > a[type="header"] > div:first-child,
+fieldset > a[type="profile"] > div:first-child,
+fieldset > a[type="thumb"] > div:first-child {
+    background-repeat: no-repeat;
+    background-position: center center;
+    display: inline-block;
+    /* XXX: small differences due to font bugs */
+    /* XXX: 1px difference due to border stupidity */
+    margin: -13px 7px -11px -15px;
+}
+
+fieldset > a > img.icon,
+fieldset > div > img.icon {
+    height: auto;
+    /* XXX: small differences due to font bugs */
+    margin: -7px 6px -9px -8px;
+    max-height: 30px;
+    min-width: 30px;
+    width: 30px;
+}
+
+fieldset > a.sixth > img.icon {
+    position: relative;
+    left: 7px;
+}
+
+panel > block > p,
+fieldset > div > p,
+panel > block > ul,
+fieldset > div > ul {
+    margin: 10px 0;
+}
+
+panel > block > ul,
+fieldset > div > ul {
+    margin-left: 13px;
+}
+
+panel > block > p,
+fieldset > div > p {
+    text-align: center;
+}
+
+fieldset > div > p:first-child,
+fieldset > div > ul:first-child {
+    margin-top: 0;
+}
+
+fieldset > div > p:last-child,
+fieldset > div > ul:last-child {
+    margin-bottom: 0;
+}
+
+fieldset > a {
+    color: inherit;
+    display: block;
+}
+
+fieldset > textarea,
+fieldset > div > input:not([type="checkbox"]),
+fieldset > div > select,
+fieldset > div > div > select {
+    background: none;
+    -webkit-box-shadow: none;
+    -webkit-appearance: none;
+}
+
+/* Chevrons {{{ */
+
+fieldset > a[href]:not([type="ad"]),
+fieldset > div > select,
+fieldset > div > div > select {
+    background-repeat: no-repeat;
+    background-image: url(chevron.png);
+}
+
+@media screen and (-webkit-min-device-pixel-ratio: 2) {
+fieldset > a[href]:not([type="ad"]),
+fieldset > div > select,
+fieldset > div > div > select {
+    background-image: url(chevron@2x.png);
+    background-size: 10px 13px;
+} }
+
+/* Horizontal */
+
+list > fieldset > a[href] {
+    background-position: 295px center;
+}
+
+panel > fieldset > a[href] {
+    background-position: 275px center;
+}
+
+panel > fieldset > a[href].half {
+    background-position: 125px center;
+}
+
+panel > fieldset > a[href].third {
+    background-position: 75px center;
+}
+
+panel > fieldset > a[href].sixth {
+    background: none;
+}
+
+list > fieldset > a:not([href]) > select,
+list > fieldset > div > select,
+list > fieldset > div > div > select {
+    background-position: 183px center;
+}
+
+panel > fieldset > a:not([href]) > select,
+panel > fieldset > div > select,
+panel > fieldset > div > div > select {
+    background-position: 163px center;
+}
+
+/* }}} */
+
+fieldset > textarea,
+fieldset > div > input,
+fieldset > div > select,
+fieldset > div > div > select,
+fieldset > a > div > label + label,
+fieldset > div > div > label + label {
+    color: #193250;
+}
+
+fieldset > textarea,
+fieldset > div > input,
+fieldset > div > select,
+fieldset > div > div > select {
+    font-size: 16px;
+}
+
+fieldset > div > input {
+    padding-left: 7px;
+    padding-right: 14px;
+}
+
+fieldset > div > input[type="checkbox"] {
+    border: 1px solid #999999;
+    -moz-border-radius: 7px;
+    -webkit-border-radius: 7px;
+    float: right;
+    margin: -7px -8px;
+    height: 30px;
+    width: 30px;
+}
+
+fieldset > div > select,
+fieldset > div > div > select,
+fieldset > div > input:not([type="checkbox"]) {
+    border: none;
+    float: right;
+    height: 40px;
+    margin: -11px -13px -11px -14px;
+}
+
+panel > fieldset > div > select,
+panel > fieldset > div > div > select,
+panel > fieldset > div > input:not([type="checkbox"]) {
+    width: 187px;
+}
+
+list > fieldset > div > select,
+list > fieldset > div > div > select,
+list > fieldset > div > input:not([type="checkbox"]) {
+    width: 207px;
+}
+
+fieldset > textarea {
+    padding: 10px;
+    width: 320px;
+}
+
+fieldset > div > div,
+fieldset > a > div {
+    display: inline-block;
+}
+
+fieldset > div > div {
+    width: 273px;
+}
+
+fieldset > a[type="ad"] > div:nth-child(2) {
+    width: 218px;
+}
+
+fieldset > a:not([type]) > div {
+    width: 250px;
+}
+
+fieldset > a:not([href]) > img.icon + div,
+fieldset > div > img.icon + div {
+    width: 244px;
+}
+
+fieldset > a[href] > img.icon + div {
+    width: 221px;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2) > label:nth-child(1).unknown {
+    color: #aaaabb;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2) > label:only-child {
+    left: 4px;
+    position: relative;
+    top: 3px;
+}
+
+fieldset > a[type="thumb"] > div:nth-child(2) > label:only-child {
+    position: relative;
+    top: 10px;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2) > label + label {
+    display: block;
+    font-size: 13px;
+    margin-top: 2px;
+}
+
+fieldset > a[type="thumb"] > div:nth-child(2) > label + label {
+    display: block;
+    margin-top: 2px;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2) {
+    width: 207px;
+}
+
+fieldset > a[type="thumb"] > div:nth-child(2) {
+    width: 193px;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2) {
+    margin: -5px 0;
+}
+
+fieldset > a[type="profile"] > div:nth-child(2),
+fieldset > a[type="thumb"] > div:nth-child(2) {
+    vertical-align: top;
+}
+
+fieldset > a > label:first-child,
+fieldset > a > div > label:first-child,
+fieldset > div > label:first-child,
+fieldset > div > div > label:first-child {
+    font-weight: bold;
+}
+
+/* XXX: this doesn't handle icon offsets */
+list > fieldset > a:not([type]) > div > label + label,
+list > fieldset > div > div > label + label {
+    margin-left: 94px;
+}
+
+panel > fieldset > a:not([type]) > div > label + label,
+panel > fieldset > div > div > label + label {
+    float: right;
+    text-align: right;
+}
+
+panel > img {
+    display: block;
+    margin: 9px auto 4px auto;
+    height: auto;
+    width: 300px;
+}
+
+fieldset > a[type="ad"] {
+}
+
+fieldset > a[type="ad"] > div:nth-child(2) {
+    position: relative;
+    vertical-align: top;
+}
+
+fieldset > a[type="ad"] > div > label:first-child {
+    color: #2d2d50;
+    font-size: 13px;
+    font-weight: bold;
+    line-height: 15px;
+}
+
+fieldset > a[type="ad"] > div > label + label {
+    position: absolute;
+    top: 17px;
+    left: 156px;
+    font-size: 9.5px;
+    font-weight: normal;
+}
+
+panel > fieldset > a.middle,
+panel > fieldset > a.right {
+    border-left: 1px solid #999999;
+}
+
+panel > fieldset > a.half {
+    display: inline-block;
+    width: 150px;
+}
+
+panel > fieldset > a.third {
+    display: inline-block;
+    width: 100px;
+}
+
+panel > fieldset > a.sixth {
+    display: inline-block;
+    width: 50px;
+}
+
+fieldset.half > a {
+    background: none;
+    background-position: 120px center;
+}
+
+fieldset.half > a > img.icon + div {
+    width: 65px;
+}
+
+fieldset.right {
+    float: right;
+    margin-left: 10px;
+}
+
+block + fieldset.right,
+fieldset + fieldset.right {
+    margin-top: 0;
+}
+
+fieldset.half {
+    width: 146px;
+}
+
+panel > fieldset.dashed > a,
+panel > fieldset.dashed > div,
+panel > fieldset.dashed > textarea,
+list > fieldset.dashed > a,
+list > fieldset.dashed > div,
+list > fieldset.dashed > textarea {
+    border-style: dashed;
+}
+
+fieldset > a[type="thumb"]:first-child > back {
+    -moz-border-radius-topright: 9px;
+    -webkit-border-top-right-radius: 9px;
+}
+
+fieldset > a[type="thumb"]:last-child > back {
+    -moz-border-radius-bottomright: 9px;
+    -webkit-border-bottom-right-radius: 9px;
+}
+
+fieldset > a[type="thumb"] > back {
+    background-repeat: no-repeat;
+    border: 1px solid #999999;
+    display: block;
+    height: 64px;
+    left: 62px;
+    position: absolute;
+    opacity: 0.2;
+    top: -1px;
+    width: 237px;
+}
+
+.mm {
+    border: 1px solid #999999;
+    -moz-border-radius: 9px;
+    -webkit-border-radius: 9px;
+}
+
+a.mm {
+    display: block;
+    margin: 9px;
+}
+
+div.mm img {
+    height: auto;
+    width: 300px;
+}
+
+fieldset > a.small {
+    font-size: 12px;
+    padding-top: 9px;
+}
+
+fieldset > a.small label {
+    display: inline-block;
+    position: relative;
+    top: 1px;
+}
+
+fieldset > a.small > img.icon {
+    max-height: 22px;
+    min-width: 22px;
+    width: 22px;
+}
+
+fieldset > a.small.half > img.icon + div {
+    width: 79px;
+}
+
+fieldset > a.small.third > img.icon + div {
+    width: 50px;
+}
+
+fieldset > a.small.sixth > img.icon + div {
+    width: 0px;
+}
+
+panel.centered > label {
+    margin-left: 0px;
+    margin-right: 0px;
+    text-align: center;
+}
+
+panel > iframe {
+    margin: -9px 0;
+}
+
+panel > iframe:first-child,
+panel > iframe + iframe {
+    margin-top: 0;
+}
+
+/* Rating Stars {{{ */
+.ratings {
+    margin: -2px 0;
+    text-align: center;
+}
+
+.rated {
+    display: inline-block;
+}
+
+.rated.left {
+    margin-right: 9px;
+}
+
+.rated label {
+    font-weight: bold;
+    margin-right: 3px;
+    position: relative;
+    top: -3px;
+}
+
+.rating {
+    display: inline-block;
+    width: 80px;
+}
+
+.rating .back,
+.rating .fore,
+.rating .star {
+    background: url(http://cache.saurik.com/crystal/16x16/actions/knewstuff.png);
+    height: 16px;
+}
+
+.rating .back,
+.rating .fore {
+    width: 80px;
+}
+
+.rating .star {
+    display: inline-block;
+    width: 16px;
+}
+
+.rating .back {
+    opacity: 0.2;
+}
+
+.rating .fore {
+    /*border-right: 1px solid #999999;*/
+    position: absolute;
+}
+/* }}} */
+
+panel > fieldset.header {
+    background-color: transparent;
+    border: none;
+    margin: -5px 9px -11px 9px;
+}
+
+panel > fieldset.header > a > div > label {
+    color: #4d4d70;
+    text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0;
+}
diff --git a/MobileCydia.app/package.html b/MobileCydia.app/package.html
new file mode 100644 (file)
index 0000000..c91b52c
--- /dev/null
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="DETAILS"></title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="package.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+
+    <!--script type="text/javascript">
+        var count = -1;
+        var loaded = function() {
+            if (count++ != 0)
+                return;
+            $("#depiction-load").remove();
+            $("#depiction-src").css("display", "block");
+        }
+
+        var remove = function() {
+            $(".description").css("display", "block");
+            $(".depiction").remove();
+        }
+    </script-->
+
+    <style>
+        .flip-180 {
+            -webkit-backface-visibility: hidden;
+            -webkit-transform: rotateY(180deg);
+        }
+
+        #icon.flip-180 {
+            -webkit-transition-duration: 2s;
+            -webkit-transition-property: transform;
+        }
+
+        .flip-360 {
+            -webkit-backface-visibility: hidden;
+            -webkit-transform: rotateY(360deg);
+            -webkit-transition-duration: 2s;
+            -webkit-transition-property: transform;
+        }
+
+        .fade-out {
+            opacity: 0;
+            -webkit-transition-property: opacity;
+            -webkit-transition-duration: 2s;
+        }
+
+        .fade-in {
+            opacity: 1;
+            -webkit-transition-property: opacity;
+            -webkit-transition-duration: 2s;
+        }
+
+        #remove {
+            margin-top: 7px;
+            text-align: center;
+        }
+
+        #indicator {
+            left: 20px;
+            position: relative;
+            top: -5px;
+        }
+
+        #remove > a {
+            color: #335588;
+            text-decoration: none;
+        }
+
+        #upper-bar {
+            margin-bottom: 0;
+            margin-top: 10px;
+        }
+
+        #lower-bar {
+            margin-bottom: 10px;
+            margin-top: 0;
+        }
+
+        #warnings {
+            background-color: #ffdddd;
+        }
+
+        #warnings > div > label {
+            color: red;
+        }
+
+        #boundary {
+            float: left;
+            height: 64;
+            width: 64px;
+        }
+
+        #thumb,
+        #icon {
+            background-position: center center;
+            background-repeat: no-repeat;
+            height: 64px;
+            position: absolute;
+            width: 64px;
+        }
+
+        #thumb {
+            -webkit-border-radius: 9px;
+        }
+
+        /* XXX: this style is out of date */
+        #reflection {
+            height: 59px;
+            max-width: 60px;
+            opacity: 0.4;
+            position: absolute;
+            -webkit-transform: matrix(1, 0, 0, -1, 0, 0);
+            width: auto;
+        }
+
+        #id, #author, #maintainer, #sponsor {
+            white-space: nowrap;
+        }
+
+        #header {
+            background: transparent;
+            border: none;
+            position: relative;
+        }
+
+        #header > div {
+            padding: 0;
+        }
+
+        #content {
+            padding: 5px;
+            position: absolute;
+            left: 77px;
+            width: 232px;
+        }
+
+        #lower {
+            margin: 0px 5px;
+        }
+
+        #name {
+            margin-bottom: 13px;
+            font-weight: bold;
+            font-size: 17px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+
+        #latest {
+            color: #335588;
+            float: left;
+        }
+
+        a[href].rating {
+            background: 107px 7px no-repeat url(menes/chevron.png);
+        }
+
+        .rating {
+            /*border: 1px solid #999999;*/
+            -webkit-border-radius: 6px;
+            padding: 7px 7px;
+            margin: -7px 0px;
+            float: right;
+            width: 126px;
+        }
+
+        .rating .back,
+        .rating .fore,
+        .rating .star {
+            background: url(star.png);
+        }
+
+        .rating .text {
+            display: inline-block;
+            color: #4d4d70;
+            margin: 0 6px;
+            vertical-align: top;
+        }
+
+        #rating-done {
+            padding-left: 12px;
+        }
+
+        #rating-none,
+        #rating-done {
+            display: none;
+        }
+
+        #depiction-src,
+        #notice-src {
+            height: 1px;
+            width: 320px;
+        }
+    </style>
+</head><body class="pinstripe">
+<panel>
+
+<fieldset id="header">
+    <div>
+        <div id="boundary">
+            <div class="flip-0" id="icon"></div>
+            <div class="flip-180" id="thumb"></div>
+            <!--img id="reflection"/-->
+        </div>
+
+        <div id="content">
+            <div id="name"></div>
+            <div id="latest"></div>
+
+            <a class="rating" id="rating-href">
+                <div id="rating-none">
+                    <div class="star"></div><div class="text" localize="NOT_RATED"></div>
+                </div><div id="rating-done">
+                    <div class="fore" id="rating-value"></div>
+                    <div class="back"></div>
+                </div>
+            </a>
+        </div>
+    </div>
+</fieldset>
+
+<fieldset class="mode">
+    <a>
+        <img class="icon" id="mode-src"/><div>
+        <label localize="PACKAGE_QUEUE"></label>
+        <label id="mode"></label>
+    </div></a>
+</fieldset>
+
+<fieldset id="actions">
+    <a id="settings">
+        <img class="icon" src="settings.png"/><div>
+        <label localize="CHANGE_PACKAGE_SETTINGS"></label>
+    </div></a>
+
+    <a id="author-href" class="author" target="_popup">
+        <img id="author-icon" class="icon" src="email.png"/><div>
+        <label localize="AUTHOR"></label>
+        <label id="author"></label>
+    </div></a>
+
+    <!--div class="commercial">
+        <img class="icon" src="commercial.png"/><div>
+        <label>This is a commercial package!</label>
+    </div></div-->
+
+    <a class="console" href="http://cydia.saurik.com/purpose/console/">
+        <img class="icon" src="console.png"/><div>
+        <label localize="CONSOLE_PACKAGE"></label>
+    </div></a>
+
+    <a id="application">
+        <img class="icon"/><div>
+        <label class="application"></label>
+    </div></a>
+</fieldset>
+
+<fieldset class="warnings" id="warnings">
+    <div id="warning">
+        <img class="icon" src="warning.png"/><div>
+        <label class="warning"></label>
+    </div></div>
+</fieldset>
+
+<iframe
+    class="notice"
+    id="notice-src"
+    frameborder="0"
+    width="320"
+    height="0"
+    target="_top"
+></iframe>
+
+<!--iframe
+    class="activation"
+    id="activation-src"
+    frameborder="0"
+    width="320"
+    height="0"
+    target="_top"
+></iframe-->
+
+<!--div id="remove" class="depiction">
+    <a href="javascript:remove()">Remove Custom Depiction</a>
+</div>
+
+<hr id="upper-bar" class="depiction"/-->
+
+<iframe
+    class="depiction"
+    id="depiction-src"
+    frameborder="0"
+    width="320"
+    height="0"
+    target="_top"
+    onload_="loaded()"
+></iframe>
+
+<!--hr id="lower-bar" class="depiction"/-->
+
+<block class="description"><p id="description"></p></block>
+
+<fieldset class="description homepage">
+    <a class="homepage" id="homepage-href">
+        <img class="icon" src="web.png"/><div>
+        <label localize="MORE_INFORMATION"></label>
+    </div></a>
+</fieldset>
+
+<label class="installed" localize="INSTALLED_DETAILS"></label>
+<fieldset class="installed">
+    <div>
+        <img class="icon" src="version.png"/><div>
+        <label localize="VERSION"></label>
+        <label id="installed"></label>
+    </div></div>
+
+    <a id="files-href">
+        <img class="icon" src="filesystem.png"/><div>
+        <label localize="FILESYSTEM_CONTENT"></label>
+    </div></a>
+</fieldset>
+
+<label localize="PACKAGE_DETAILS"></label>
+<fieldset>
+    <div>
+        <img class="icon" src="id.png"/><div>
+        <label localize="ID"></label>
+        <label id="id"></label>
+    </div></div>
+
+    <div class="section">
+        <img id="section-src" class="icon"/><div>
+        <label localize="SECTION"></label>
+        <label id="section"></label>
+    </div></div>
+
+    <div class="size">
+        <img class="icon" src="expanded.png"/><div>
+        <label localize="EXPANDED_SIZE"></label>
+        <label id="size"></label>
+    </div></div>
+
+    <a id="maintainer-href" class="maintainer" target="_popup">
+        <img id="maintainer-icon" class="icon" src="email.png"/><div>
+        <label localize="MAINTAINER"></label>
+        <label id="maintainer"></label>
+    </div></a>
+
+    <a id="sponsor-href" class="sponsor">
+        <img class="icon" src="web.png"/><div>
+        <label localize="SPONSOR"></label>
+        <label id="sponsor"></label>
+    </div></a>
+
+    <!--a class="trusted" id="trusted">
+        <img class="icon" src="trusted.png"><div>
+        <label localize="REPOSITORY_SIGNATURE"></label>
+    </div></a-->
+
+    <div class="trusted">
+        <img class="icon" src="trusted.png"><div>
+        <label>&nbsp;</label>
+        <label localize="SIGNED_PACKAGE"></label>
+    </div></div>
+</fieldset>
+
+<label class="source" localize="SOURCE_DETAILS"></label>
+<fieldset class="source">
+    <div>
+        <img class="icon" id="source-src"/><div>
+        <label id="source-name"></label>
+    </div></div>
+
+    <div class="source-description" id="source-description"></div>
+</fieldset>
+
+</panel>
+</body></html>
diff --git a/MobileCydia.app/package.js b/MobileCydia.app/package.js
new file mode 100644 (file)
index 0000000..b9f85ff
--- /dev/null
@@ -0,0 +1,330 @@
+/*var package = {
+    "name": "MobileTerminal",
+    "latest": "286u-5",
+    "author": {
+        "name": "Allen Porter",
+        "address": "allen.porter@gmail.com"
+    },
+    //"depiction": "http://planet-iphones.com/repository/info/chromium1.3.php",
+    "depiction": "http://cydia.saurik.com/terminal.html",
+    "longDescription": "this is a sample description",
+    "homepage": "http://cydia.saurik.com/terminal.html",
+    "installed": "286u-4",
+    "id": "mobileterminal",
+    "section": "Terminal Support",
+    "size": 552*1024,
+    "maintainer": {
+        "name": "Jay Freeman",
+        "address": "saurik@saurik.com"
+    },
+    "source": {
+        "name": "Telesphoreo Tangelo",
+        "description": "Distribution of Unix Software for the iPhone"
+    }
+};*/
+
+function space(selector, html, max) {
+    var node = $(selector);
+    node.html(html);
+    var width = node.width();
+    if (width > max) {
+        var spacing = (max - node.width()) / (html.length - 1) + "px";
+        node.css("letter-spacing", spacing);
+    }
+}
+
+var swap_, swap = function (on, off, time) {
+    setTimeout(swap_(on, off, time), time);
+};
+
+swap_ = function (on, off, time) {
+    return function () {
+        on.className = 'fade-out';
+        off.className = 'fade-in';
+        swap(off, on, time);
+    };
+};
+
+var special_ = function () {
+    if (package == null)
+        return;
+
+    var id = package.id;
+    var idc = encodeURIComponent(id);
+    var name = package.name;
+    var icon = 'cydia://package-icon/' + idc;
+
+    var api = 'http://cydia.saurik.com/api/';
+    var capi = 'http://cache.cydia.saurik.com/api/';
+
+    var support = package.support;
+
+    var regarding = function (type) {
+        return encodeURIComponent("Cydia/APT(" + type + "): " + name);
+    };
+
+    $("#icon").css("background-image", 'url("' + icon + '")');
+    //$("#reflection").src("cydia://package-icon/" + idc);
+
+    $("#name").html(name);
+    space("#latest", package.latest, 96);
+
+    $.xhr(capi + 'package/' + idc, 'GET', {}, null, {
+        success: function (value) {
+            value = eval(value);
+
+            if (typeof value.notice == "undefined")
+                $(".notice").addClass("deleted");
+            else
+                $("#notice-src").src(value.notice);
+
+            if (typeof value.rating == "undefined")
+                $(".rating").addClass("deleted");
+            else {
+                $("#rating-load").addClass("deleted");
+                $("#rating-href").href(value.reviews);
+
+                var none = $("#rating-none");
+                var done = $("#rating-done");
+
+                if (value.rating == null) {
+                    none.css("display", "block");
+                } else {
+                    done.css("display", "block");
+
+                    $("#rating-value").css('width', 16 * value.rating);
+                }
+            }
+
+            if (typeof value.icon != "undefined" && value.icon != null) {
+                var icon = $("#icon");
+                var thumb = $("#thumb");
+
+                icon[0].className = 'flip-180';
+                thumb[0].className = 'flip-360';
+
+                thumb.css("background-image", 'url("' + value.icon + '")');
+
+                setTimeout(function () {
+                    icon.addClass("deleted");
+                    thumb[0].className = 'flip-0';
+                }, 2000);
+            }
+        },
+
+        failure: function (status) {
+            $(".rating").addClass("deleted");
+        }
+    });
+
+    $("#settings").href("cydia://package-settings/" + idc);
+
+    var mode = package.mode;
+    if (mode == null)
+        $(".mode").addClass("deleted");
+    else {
+        $("#mode").html(cydia.localize(mode));
+        $("#mode-src").src("Modes/" + mode + ".png");
+    }
+
+    var warnings = package.warnings;
+    var length = warnings == null ? 0 : warnings.length;
+    if (length == 0)
+        $(".warnings").addClass("deleted");
+    else {
+        var parent = $("#warnings");
+        var child = $("#warning");
+
+        for (var i = 0; i != length; ++i) {
+            var clone = child.clone(true);
+            clone.addClass("inserted");
+            parent.append(clone);
+            clone.xpath("./div/label").html($.xml(warnings[i]));
+        }
+
+        child.addClass("deleted");
+    }
+
+    var applications = package.applications;
+    var length = applications == null ? 0 : applications.length;
+
+    var child = $("#application");
+
+    /*if (length != 0) {
+        var parent = $("#actions");
+
+        for (var i = 0; i != length; ++i) {
+            var application = applications[i];
+            var clone = child.clone(true);
+            parent.append(clone);
+            clone.href("cydia://launch/" + application[0]);
+            clone.xpath("label").html("Run " + $.xml(application[1]));
+            clone.xpath("img").src(application[2]);
+        }
+    }*/
+
+    child.addClass("deleted");
+
+    var commercial = package.hasTag('cydia::commercial');
+    if (!commercial)
+        $(".commercial").addClass("deleted");
+
+    var _console = package.hasTag('purpose::console');
+    if (!_console)
+        $(".console").addClass("deleted");
+
+    var author = package.author;
+    if (author == null)
+        $(".author").addClass("deleted");
+    else {
+        space("#author", author.name, 160);
+        if (author.address == null)
+            $("#author-icon").addClass("deleted");
+        else if (support == null)
+            $("#author-href").href("mailto:" + author.address + "?subject=" + regarding("A"));
+        else
+            $("#author-href").href(support);
+    }
+
+    /*var store = commercial;
+    if (!store)
+        $(".activation").addClass("deleted");
+    else {
+        var activation = api + 'activation/' + idc;
+        $("#activation-src").src(activation);
+    }*/
+
+    var depiction = package.depiction;
+    if (depiction != null) {
+        $(".description").addClass("deleted");
+        $("#depiction-src").src(depiction);
+    } else {
+        $(".depiction").addClass("deleted");
+
+        var description = package.longDescription;
+        if (description == null)
+            description = package.shortDescription;
+
+        if (description == null)
+            $(".description").addClass("deleted");
+        else {
+            description = $.xml(description).replace(/\n/g, "<br/>");
+            $("#description").html(description);
+        }
+    }
+
+    var homepage = package.homepage;
+    if (homepage == null)
+        $(".homepage").addClass("deleted");
+    else
+        $("#homepage-href").href(homepage);
+
+    var installed = package.installed;
+    if (installed == null)
+        $(".installed").addClass("deleted");
+    else {
+        $("#installed").html(installed);
+        $("#files-href").href("cydia://files/" + idc);
+    }
+
+    space("#id", id, 220);
+
+    var section = package.longSection;
+    if (section == null)
+        $(".section").addClass("deleted");
+    else {
+        $("#section-src").src("cydia://section-icon/" + encodeURIComponent(section));
+        $("#section").html(section);
+    }
+
+    var size = package.size;
+    if (size == 0)
+        $(".size").addClass("deleted");
+    else
+        $("#size").html(size / 1024 + " kB");
+
+    var maintainer = package.maintainer;
+    if (maintainer == null)
+        $(".maintainer").addClass("deleted");
+    else {
+        space("#maintainer", maintainer.name, 153);
+        if (maintainer.address == null)
+            $("#maintainer-icon").addClass("deleted");
+        else if (support == null)
+            $("#maintainer-href").href("mailto:" + maintainer.address + "?subject=" + regarding("M"));
+        else
+            $("#maintainer-href").href(support);
+    }
+
+    var sponsor = package.sponsor;
+    if (sponsor == null)
+        $(".sponsor").addClass("deleted");
+    else {
+        space("#sponsor", sponsor.name, 152);
+        $("#sponsor-href").href(sponsor.address);
+    }
+
+    var source = package.source;
+    if (source == null) {
+        $(".source").addClass("deleted");
+        $(".trusted").addClass("deleted");
+    } else {
+        var host = source.host;
+
+        $("#source-src").src("cydia://source-icon/" + encodeURIComponent(host));
+        $("#source-name").html(source.name);
+
+        if (source.trusted)
+            $("#trusted").href("cydia://package-signature/" + idc);
+        else
+            $(".trusted").addClass("deleted");
+
+        var description = source.description;
+        if (description == null)
+            $(".source-description").addClass("deleted");
+        else
+            $("#source-description").html($.xml(description));
+    }
+};
+
+$(special_);
+
+var special = function () {
+    $(".deleted").removeClass("deleted");
+    $(".inserted").remove();
+
+    $("#icon")[0].className = 'flip-0';
+    $("#thumb")[0].className = 'flip-180';
+
+    /* XXX: this could be better */
+    $("#rating-href").href(null);
+    $("#rating-none").css("display", "none");
+    $("#rating-done").css("display", "none");
+
+    var notice = $("#notice-src");
+
+    notice[0].outerHTML = '<iframe' +
+        ' class="notice"' +
+        ' id="notice-src"' +
+        ' frameborder="0"' +
+        ' width="320"' +
+        ' height="0"' +
+        ' target="_top"' +
+    '></iframe>';
+
+    var depiction = $("#depiction-src");
+
+    depiction[0].outerHTML = '<iframe' +
+        ' class="depiction"' +
+        ' id="depiction-src"' +
+        ' frameborder="0"' +
+        ' width="320"' +
+        ' height="0"' +
+        ' target="_top"' +
+        ' onload_="loaded()"' +
+    '></iframe>';
+
+    special_();
+};
+
+cydia.setSpecial(special);
diff --git a/MobileCydia.app/packages.png b/MobileCydia.app/packages.png
new file mode 100644 (file)
index 0000000..404fe0c
Binary files /dev/null and b/MobileCydia.app/packages.png differ
diff --git a/MobileCydia.app/reload.png b/MobileCydia.app/reload.png
new file mode 100644 (file)
index 0000000..8d06eb4
Binary files /dev/null and b/MobileCydia.app/reload.png differ
diff --git a/MobileCydia.app/removing.png b/MobileCydia.app/removing.png
new file mode 100644 (file)
index 0000000..935d4c7
Binary files /dev/null and b/MobileCydia.app/removing.png differ
diff --git a/MobileCydia.app/search.png b/MobileCydia.app/search.png
new file mode 100644 (file)
index 0000000..4083f1b
Binary files /dev/null and b/MobileCydia.app/search.png differ
diff --git a/MobileCydia.app/search@2x.png b/MobileCydia.app/search@2x.png
new file mode 100644 (file)
index 0000000..74d6381
Binary files /dev/null and b/MobileCydia.app/search@2x.png differ
diff --git a/MobileCydia.app/settings.png b/MobileCydia.app/settings.png
new file mode 100644 (file)
index 0000000..86f4e78
Binary files /dev/null and b/MobileCydia.app/settings.png differ
diff --git a/MobileCydia.app/signature.html b/MobileCydia.app/signature.html
new file mode 100644 (file)
index 0000000..aa113b8
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title>Signature</title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="signature.js"></script>
+    <base target="_blank"/>
+</head><body><div class="page">
+<div class="dialog">
+    <div class="panel">
+
+    </div>
+</div>
+</div></body></html>
diff --git a/MobileCydia.app/source.png b/MobileCydia.app/source.png
new file mode 100755 (executable)
index 0000000..2dcfdbc
Binary files /dev/null and b/MobileCydia.app/source.png differ
diff --git a/MobileCydia.app/source@2x.png b/MobileCydia.app/source@2x.png
new file mode 100755 (executable)
index 0000000..65d70c3
Binary files /dev/null and b/MobileCydia.app/source@2x.png differ
diff --git a/MobileCydia.app/sources.png b/MobileCydia.app/sources.png
new file mode 100755 (executable)
index 0000000..e8422e4
Binary files /dev/null and b/MobileCydia.app/sources.png differ
diff --git a/MobileCydia.app/star.png b/MobileCydia.app/star.png
new file mode 100644 (file)
index 0000000..f762a24
Binary files /dev/null and b/MobileCydia.app/star.png differ
diff --git a/MobileCydia.app/storage.html b/MobileCydia.app/storage.html
new file mode 100644 (file)
index 0000000..55ac5ab
--- /dev/null
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="STORAGE"></title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="storage.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+
+    <style>
+        body {
+            display: table;
+            font-family: Helvetica;
+            height: 337px;
+            margin: 0;
+            padding: 0;
+            -webkit-text-size-adjust: none;
+            -webkit-user-select: none;
+        }
+
+        div.page {
+            display: table-cell;
+            text-align: center;
+            margin: 0 auto;
+            vertical-align: middle;
+            width: 320px;
+        }
+
+        a.giant-button {
+            background-color: rgba(0, 0, 0, 0.15);
+            -webkit-border-radius: 10px;
+            color: #193250;
+            display: block;
+            margin: 8px 10px;
+            position: relative;
+            text-decoration: none;
+            width: 300px;
+        }
+
+        a.giant-button > piechart {
+            float: left;
+            margin: 10px;
+            vertical-align: middle;
+        }
+
+        a.giant-button > label {
+            display: block;
+            float: left;
+            font-size: 25px;
+            margin: 10px 0 4px 4px;
+            text-align: center;
+            text-shadow: rgba(200, 200, 200, 0.75) 1px 1px 0;
+            width: 155px;
+        }
+
+        a.giant-button > div.text {
+            display: block;
+            float: left;
+            font-size: 14px;
+            margin-left: 4px;
+            text-align: center;
+            width: 155px;
+        }
+
+        div.key {
+            display: inline-block;
+            width: 50%;
+        }
+
+        a.giant-button > div.legend {
+            float: left;
+            font-size: 14px;
+            left: 15px;
+            position: absolute;
+            top: 120px;
+            width: 290px;
+        }
+
+        div.key {
+            margin-bottom: 4px;
+        }
+
+        piechart {
+            /*-webkit-transform: rotate(-5deg);*/
+            /*-webkit-transform: rotateY(15deg) rotateX(-45deg);*/
+        }
+
+        piechart > div {
+            -webkit-border-radius: 50px;
+            height: 100px;
+            overflow: hidden;
+            position: relative;
+            width: 100px;
+        }
+
+        piechart > div > div:first-child {
+            height: 100px;
+            overflow: hidden;
+            position: absolute;
+            z-index: 102;
+            width: 51px;
+        }
+
+        piechart > div > div:last-child {
+            height: 100px;
+            overflow: hidden;
+            position: absolute;
+            width: 100px;
+            z-index: 0;
+        }
+
+        piechart > div div.lslice,
+        piechart > div div.rslice,
+        piechart > div div.tslice,
+        piechart > div div.bslice {
+            background-color: #4d4d70;
+        }
+
+        piechart > div div.lslice,
+        piechart > div div.rslice,
+        piechart > div div.tslice,
+        piechart > div div.bslice,
+        piechart > div div.xslice {
+            /* XXX: technically, these aren't needed */
+            -webkit-border-bottom-left-radius: 50px;
+            -webkit-border-top-left-radius: 50px;
+            height: 100px;
+            position: absolute;
+            -webkit-transform-origin: 100% 50%;
+            width: 50px;
+        }
+
+        piechart > div div.lslice {
+            z-index: 100;
+        }
+
+        piechart > div div.rslice,
+        piechart > div div.tslice,
+        piechart > div div.bslice {
+            z-index: 0;
+        }
+
+        piechart > div div.rslice {
+            -webkit-transform: rotate(180deg);
+        }
+
+        piechart > div div.tslice {
+            -webkit-transform: rotate(90deg);
+        }
+
+        piechart > div div.bslice {
+            -webkit-transform: rotate(270deg);
+        }
+
+        piechart > div > div.nslice {
+            position: absolute;
+            text-align: center;
+            top: 42px;
+            width: 100px;
+            z-index: 103;
+        }
+
+        piechart > div > div.nslice > div {
+            background-color: rgba(255, 255, 255, 0.7);
+            -webkit-border-radius: 7px;
+            display: inline;
+            color: black;
+            font-size: 15px;
+            font-weight: bold;
+            margin: 0 auto;
+            padding: 2px 4px;
+            text-align: center;
+        }
+
+        div.color {
+            background-color: black;
+            border: 1px solid #4d4d70;
+            display: inline-block;
+            vertical-align: middle;
+        }
+
+        div.color > div {
+            border: 1px solid white;
+            display: inline-block;
+            height: 12px;
+            width: 12px;
+        }
+
+        div.name {
+            display: inline-block;
+            font-size: 14px;
+            margin-left: 5px;
+            vertical-align: middle;
+        }
+    </style>
+</head><body class="pinstripe">
+<panel>
+
+<a class="giant-button" style="height: 149px">
+    <piechart><div>
+        <div id="system-left"></div>
+        <div id="system-right">
+            <div class="lslice"></div>
+            <div class="rslice"></div>
+            <div class="tslice"></div>
+            <div class="bslice"></div>
+        </div>
+        <div class="nslice"><div id="system-size"></div></div>
+    </div></piechart>
+
+    <label>System</label>
+    <div class="text">A small partition used to store iPhone OS. Cydia adds a few important programs and libraries.</div>
+
+    <div class="legend" id="system-legend"></div>
+</a>
+
+<a class="giant-button" style="height: 189px">
+    <piechart><div>
+        <div id="private-left"></div>
+        <div id="private-right">
+            <div class="lslice"></div>
+            <div class="rslice"></div>
+            <div class="tslice"></div>
+            <div class="bslice"></div>
+        </div>
+        <div class="nslice"><div id="private-size"></div></div>
+    </div></piechart>
+
+    <label>Private</label>
+    <div class="text">Most content is stored on this partition: from applications (Cydia and Apple) to multimedia.</div>
+
+    <div class="legend" id="private-legend"></div>
+</a>
+
+</panel>
+</body></html>
diff --git a/MobileCydia.app/storage.js b/MobileCydia.app/storage.js
new file mode 100644 (file)
index 0000000..ae8cb85
--- /dev/null
@@ -0,0 +1,88 @@
+var colors = ["#9090e0", "#4d4d70", "#7d7da0", "#7da0e0", "#d0d0f0", "#7070e0"];
+
+var list = function (legend, color, name, value) {
+    legend.append('<div class="key">' +
+        '<div class="color" style="background-color: ' + color + '"><div></div></div>' +
+        '<div class="name">' + name + ' (' + Math.round(value * 1000) / 10 + '%)</div>' +
+    '</div>');
+};
+
+console.log(cydia.statfs("/"));
+
+var cut = function (parent, color, fraction, z) {
+    var deg = Math.round(360 * fraction);
+    if (deg < 2)
+        deg = 2;
+    parent.append('<div class="xslice" style="' +
+        'background-color: ' + color + ';' +
+        '-webkit-transform: rotate(' + deg + 'deg);' +
+        'z-index: ' + z + ';' +
+    '"></div>');
+};
+
+var chart = function (right, left, slices) {
+    var total = 0;
+    for (var i = 0; i != slices.length; ++i) {
+        var slice = slices[i];
+        var z = slices.length - i;
+        if (slice[1] > 0.5)
+            cut(right, slice[0], total + 0.5, z);
+        total += slice[1];
+        cut(total > 0.5 ? left : right, slice[0], total, z);
+    }
+};
+
+var setup = function (name, root, folders) {
+    var size = $("#" + name + "-size");
+    var statfs = cydia.statfs(root);
+    var kb = statfs[0] * statfs[1] / 1024;
+    var total = kb / 1024;
+
+    var unit;
+    if (total < 1000)
+        unit = 'M';
+    else {
+        total = total / 1024;
+        unit = 'G'
+    }
+
+    size.html(Math.round(total * 10) / 10 + " " + unit);
+
+    var legend = $("#" + name + "-legend");
+    var used = 0;
+
+    var slices = [];
+
+    if (folders != null)
+        for (var i = 0; i != folders.length; ++i) {
+            var folder = folders[i];
+            var usage = cydia.du(folder[1]);
+            if (usage == null)
+                usage = 0;
+            var color = colors[i + 2];
+            var percent = usage / kb;
+            list(legend, color, folder[0], percent);
+            slices.push([color, percent]);
+            used += usage;
+        }
+
+    var free = statfs[0] * statfs[2] / 1024;
+    var other = (kb - free - used) / kb;
+
+    slices.push([colors[0], other]);
+    chart($("#" + name + "-right"), $("#" + name + "-left"), slices);
+
+    list(legend, colors[0], folders == null ? "Used" : "Other", other);
+    list(legend, colors[1], "Free", statfs[2] / statfs[1]);
+};
+
+$(function () {
+    setup("system", "/", null);
+
+    setup("private", "/private/var", [
+        ["Themes", "/Library/Themes/"],
+        ["iTunes", "/var/mobile/Media/iTunes_Control/"],
+        ["App Store", "/var/mobile/Applications/"],
+        ["Camera", "/var/mobile/Media/DCIM/"]
+    ]);
+});
diff --git a/MobileCydia.app/storage.png b/MobileCydia.app/storage.png
new file mode 100644 (file)
index 0000000..3cefef0
Binary files /dev/null and b/MobileCydia.app/storage.png differ
diff --git a/MobileCydia.app/trusted.png b/MobileCydia.app/trusted.png
new file mode 100644 (file)
index 0000000..de249eb
Binary files /dev/null and b/MobileCydia.app/trusted.png differ
diff --git a/MobileCydia.app/unknown.html b/MobileCydia.app/unknown.html
new file mode 100644 (file)
index 0000000..900a86f
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<html><head>
+    <title localize="UNKNOWN"></title>
+    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <link rel="stylesheet" type="text/css" href="menes/style.css"/>
+    <script type="text/javascript" src="menes/menes.js"></script>
+    <script type="text/javascript" src="localize.js"></script>
+    <base target="_blank"/>
+    <script type="text/javascript">
+    $(function () {
+        $("#body").html($.xml(cydia.format(cydia.localize("PACKAGE_CANNOT_BE_FOUND"), [location.search.substring(1)])));
+    });
+    </script>
+</head><body class="pinstripe">
+<panel>
+
+<fieldset>
+    <div><p style="font-weight: bold"><span style="color: red" localize="NOTE"></span>: <span localize="CANNOT_LOCATE_PACKAGE"></span></p></div>
+</fieldset>
+
+<block>
+    <p id="body"></p>
+    <p localize="PACKAGE_CANNOT_BE_FOUND_EX"></p>
+</block>
+
+</panel>
+</body></html>
diff --git a/MobileCydia.app/unknown.png b/MobileCydia.app/unknown.png
new file mode 100644 (file)
index 0000000..92d7338
Binary files /dev/null and b/MobileCydia.app/unknown.png differ
diff --git a/MobileCydia.app/version.png b/MobileCydia.app/version.png
new file mode 100644 (file)
index 0000000..fd1eec1
Binary files /dev/null and b/MobileCydia.app/version.png differ
diff --git a/MobileCydia.app/warning.png b/MobileCydia.app/warning.png
new file mode 100644 (file)
index 0000000..8d3e5df
Binary files /dev/null and b/MobileCydia.app/warning.png differ
diff --git a/MobileCydia.app/web.png b/MobileCydia.app/web.png
new file mode 100644 (file)
index 0000000..a4f04e3
Binary files /dev/null and b/MobileCydia.app/web.png differ
diff --git a/MobileCydia.mm b/MobileCydia.mm
new file mode 100644 (file)
index 0000000..a9c4ada
--- /dev/null
@@ -0,0 +1,9018 @@
+/* Cydia - iPhone UIKit Front-End for Debian APT
+ * Copyright (C) 2008-2010  Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+// XXX: wtf/FastMalloc.h... wtf?
+#define USE_SYSTEM_MALLOC 1
+
+/* #include Directives {{{ */
+#include "UICaboodle/UCPlatform.h"
+#include "UICaboodle/UCLocalize.h"
+
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+#include <CoreGraphics/CoreGraphics.h>
+#include <Foundation/Foundation.h>
+
+#if 0
+#define DEPLOYMENT_TARGET_MACOSX 1
+#define CF_BUILDING_CF 1
+#include <CoreFoundation/CFInternal.h>
+#endif
+
+#include <CoreFoundation/CFPriv.h>
+#include <CoreFoundation/CFUniChar.h>
+
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#include <UIKit/UIKit.h>
+#include "iPhonePrivate.h"
+
+#include <IOKit/IOKitLib.h>
+
+#include <WebCore/WebCoreThread.h>
+
+#include <algorithm>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <ext/stdio_filebuf.h>
+
+#undef ABS
+
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/clean.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/debindexfile.h>
+#include <apt-pkg/debmetaindex.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/mmap.h>
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/sha1.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/tagfile.h>
+
+#include <apr-1/apr_pools.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <fcntl.h>
+#include <notify.h>
+#include <dlfcn.h>
+
+extern "C" {
+#include <mach-o/nlist.h>
+}
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <errno.h>
+#include <pcre.h>
+
+#include <ext/hash_map>
+
+#include "UICaboodle/BrowserView.h"
+
+#include "substrate.h"
+/* }}} */
+
+/* Profiler {{{ */
+struct timeval _ltv;
+bool _itv;
+
+#define _timestamp ({ \
+    struct timeval tv; \
+    gettimeofday(&tv, NULL); \
+    tv.tv_sec * 1000000 + tv.tv_usec; \
+})
+
+typedef std::vector<class ProfileTime *> TimeList;
+TimeList times_;
+
+class ProfileTime {
+  private:
+    const char *name_;
+    uint64_t total_;
+    uint64_t count_;
+
+  public:
+    ProfileTime(const char *name) :
+        name_(name),
+        total_(0)
+    {
+        times_.push_back(this);
+    }
+
+    void AddTime(uint64_t time) {
+        total_ += time;
+        ++count_;
+    }
+
+    void Print() {
+        if (total_ != 0)
+            std::cerr << std::setw(5) << count_ << ", " << std::setw(7) << total_ << " : " << name_ << std::endl;
+        total_ = 0;
+        count_ = 0;
+    }
+};
+
+class ProfileTimer {
+  private:
+    ProfileTime &time_;
+    uint64_t start_;
+
+  public:
+    ProfileTimer(ProfileTime &time) :
+        time_(time),
+        start_(_timestamp)
+    {
+    }
+
+    ~ProfileTimer() {
+        time_.AddTime(_timestamp - start_);
+    }
+};
+
+void PrintTimes() {
+    for (TimeList::const_iterator i(times_.begin()); i != times_.end(); ++i)
+        (*i)->Print();
+    std::cerr << "========" << std::endl;
+}
+
+#define _profile(name) { \
+    static ProfileTime name(#name); \
+    ProfileTimer _ ## name(name);
+
+#define _end }
+/* }}} */
+
+#define _pooled _H<NSAutoreleasePool> _pool([[NSAutoreleasePool alloc] init], true);
+
+static const NSUInteger UIViewAutoresizingFlexibleBoth(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
+
+void NSLogPoint(const char *fix, const CGPoint &point) {
+    NSLog(@"%s(%g,%g)", fix, point.x, point.y);
+}
+
+void NSLogRect(const char *fix, const CGRect &rect) {
+    NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+}
+
+static _finline NSString *CydiaURL(NSString *path) {
+    char page[25];
+    page[0] = 'h'; page[1] = 't'; page[2] = 't'; page[3] = 'p'; page[4] = ':';
+    page[5] = '/'; page[6] = '/'; page[7] = 'c'; page[8] = 'y'; page[9] = 'd';
+    page[10] = 'i'; page[11] = 'a'; page[12] = '.'; page[13] = 's'; page[14] = 'a';
+    page[15] = 'u'; page[16] = 'r'; page[17] = 'i'; page[18] = 'k'; page[19] = '.';
+    page[20] = 'c'; page[21] = 'o'; page[22] = 'm'; page[23] = '/'; page[24] = '\0';
+    return [[NSString stringWithUTF8String:page] stringByAppendingString:path];
+}
+
+static _finline void UpdateExternalStatus(uint64_t newStatus) {
+    int notify_token;
+    if (notify_register_check("com.saurik.Cydia.status", &notify_token) == NOTIFY_STATUS_OK) {
+        notify_set_state(notify_token, newStatus);
+        notify_cancel(notify_token);
+    }
+    notify_post("com.saurik.Cydia.status");
+}
+
+/* [NSObject yieldToSelector:(withObject:)] {{{*/
+@interface NSObject (Cydia)
+- (id) yieldToSelector:(SEL)selector withObject:(id)object;
+- (id) yieldToSelector:(SEL)selector;
+@end
+
+@implementation NSObject (Cydia)
+
+- (void) doNothing {
+}
+
+- (void) _yieldToContext:(NSMutableArray *)context { _pooled
+    SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
+    id object([[context objectAtIndex:1] nonretainedObjectValue]);
+    volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
+
+    /* XXX: deal with exceptions */
+    id value([self performSelector:selector withObject:object]);
+
+    NSMethodSignature *signature([self methodSignatureForSelector:selector]);
+    [context removeAllObjects];
+    if ([signature methodReturnLength] != 0 && value != nil)
+        [context addObject:value];
+
+    stopped = true;
+
+    [self
+        performSelectorOnMainThread:@selector(doNothing)
+        withObject:nil
+        waitUntilDone:NO
+    ];
+}
+
+- (id) yieldToSelector:(SEL)selector withObject:(id)object {
+    /*return [self performSelector:selector withObject:object];*/
+
+    volatile bool stopped(false);
+
+    NSMutableArray *context([NSMutableArray arrayWithObjects:
+        [NSValue valueWithPointer:selector],
+        [NSValue valueWithNonretainedObject:object],
+        [NSValue valueWithPointer:const_cast<bool *>(&stopped)],
+    nil]);
+
+    NSThread *thread([[[NSThread alloc]
+        initWithTarget:self
+        selector:@selector(_yieldToContext:)
+        object:context
+    ] autorelease]);
+
+    [thread start];
+
+    NSRunLoop *loop([NSRunLoop currentRunLoop]);
+    NSDate *future([NSDate distantFuture]);
+
+    while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
+
+    return [context count] == 0 ? nil : [context objectAtIndex:0];
+}
+
+- (id) yieldToSelector:(SEL)selector {
+    return [self yieldToSelector:selector withObject:nil];
+}
+
+@end
+/* }}} */
+
+@interface CYActionSheet : UIAlertView {
+    unsigned button_;
+}
+
+- (int) yieldToPopupAlertAnimated:(BOOL)animated;
+@end
+
+@implementation CYActionSheet
+
+- (id) initWithTitle:(NSString *)title buttons:(NSArray *)buttons defaultButtonIndex:(int)index {
+    if ((self = [super init])) {
+        [self setTitle:title];
+        [self setDelegate:self];
+        for (NSString *button in buttons) [self addButtonWithTitle:button];
+        [self setCancelButtonIndex:index];
+    } return self;
+}
+
+- (void) _updateFrameForDisplay {
+    [super _updateFrameForDisplay];
+    if ([self cancelButtonIndex] == -1) {
+        NSArray *buttons = [self buttons];
+        if ([buttons count]) {
+            UIImage *background = [[buttons objectAtIndex:0] backgroundForState:0];
+            for (UIThreePartButton *button in buttons)
+                [button setBackground:background forState:0];
+        }
+    }
+}
+
+- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
+    button_ = buttonIndex + 1;
+}
+
+- (void) dismiss {
+    [self dismissWithClickedButtonIndex:-1 animated:YES];
+}
+
+- (int) yieldToPopupAlertAnimated:(BOOL)animated {
+    [self setRunsModal:YES];
+    button_ = 0;
+    [self show];
+    return button_;
+}
+
+@end
+
+/* NSForcedOrderingSearch doesn't work on the iPhone */
+static const NSStringCompareOptions MatchCompareOptions_ = NSLiteralSearch | NSCaseInsensitiveSearch;
+static const NSStringCompareOptions LaxCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSCaseInsensitiveSearch;
+static const CFStringCompareFlags LaxCompareFlags_ = kCFCompareCaseInsensitive | kCFCompareNonliteral | kCFCompareLocalized | kCFCompareNumerically | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
+
+/* Information Dictionaries {{{ */
+@interface NSMutableArray (Cydia)
+- (void) addInfoDictionary:(NSDictionary *)info;
+@end
+
+@implementation NSMutableArray (Cydia)
+
+- (void) addInfoDictionary:(NSDictionary *)info {
+    [self addObject:info];
+}
+
+@end
+
+@interface NSMutableDictionary (Cydia)
+- (void) addInfoDictionary:(NSDictionary *)info;
+@end
+
+@implementation NSMutableDictionary (Cydia)
+
+- (void) addInfoDictionary:(NSDictionary *)info {
+    [self setObject:info forKey:[info objectForKey:@"CFBundleIdentifier"]];
+}
+
+@end
+/* }}} */
+
+#define lprintf(args...) fprintf(stderr, args)
+
+#define ForRelease 1
+#define TraceLogging (1 && !ForRelease)
+#define HistogramInsertionSort (0 && !ForRelease)
+#define ProfileTimes (0 && !ForRelease)
+#define ForSaurik (0 && !ForRelease)
+#define LogBrowser (0 && !ForRelease)
+#define TrackResize (0 && !ForRelease)
+#define ManualRefresh (0 && !ForRelease)
+#define ShowInternals (0 && !ForRelease)
+#define IgnoreInstall (0 && !ForRelease)
+#define RecycleWebViews 0
+#define RecyclePackageViews (0 && ForRelease)
+#define AlwaysReload (1 && !ForRelease)
+
+#if !TraceLogging
+#undef _trace
+#define _trace(args...)
+#endif
+
+#if !ProfileTimes
+#undef _profile
+#define _profile(name) {
+#undef _end
+#define _end }
+#define PrintTimes() do {} while (false)
+#endif
+
+/* Radix Sort {{{ */
+typedef uint32_t (*SKRadixFunction)(id, void *);
+
+@interface NSMutableArray (Radix)
+- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object;
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument;
+@end
+
+struct RadixItem_ {
+    size_t index;
+    uint32_t key;
+};
+
+static void RadixSort_(NSMutableArray *self, size_t count, struct RadixItem_ *swap) {
+    struct RadixItem_ *lhs(swap), *rhs(swap + count);
+
+    static const size_t width = 32;
+    static const size_t bits = 11;
+    static const size_t slots = 1 << bits;
+    static const size_t passes = (width + (bits - 1)) / bits;
+
+    size_t *hist(new size_t[slots]);
+
+    for (size_t pass(0); pass != passes; ++pass) {
+        memset(hist, 0, sizeof(size_t) * slots);
+
+        for (size_t i(0); i != count; ++i) {
+            uint32_t key(lhs[i].key);
+            key >>= pass * bits;
+            key &= _not(uint32_t) >> width - bits;
+            ++hist[key];
+        }
+
+        size_t offset(0);
+        for (size_t i(0); i != slots; ++i) {
+            size_t local(offset);
+            offset += hist[i];
+            hist[i] = local;
+        }
+
+        for (size_t i(0); i != count; ++i) {
+            uint32_t key(lhs[i].key);
+            key >>= pass * bits;
+            key &= _not(uint32_t) >> width - bits;
+            rhs[hist[key]++] = lhs[i];
+        }
+
+        RadixItem_ *tmp(lhs);
+        lhs = rhs;
+        rhs = tmp;
+    }
+
+    delete [] hist;
+
+    NSMutableArray *values([NSMutableArray arrayWithCapacity:count]);
+    for (size_t i(0); i != count; ++i)
+        [values addObject:[self objectAtIndex:lhs[i].index]];
+    [self setArray:values];
+
+    delete [] swap;
+}
+
+@implementation NSMutableArray (Radix)
+
+- (void) radixSortUsingSelector:(SEL)selector withObject:(id)object {
+    size_t count([self count]);
+    if (count == 0)
+        return;
+
+#if 0
+    NSInvocation *invocation([NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"L12@0:4@8"]]);
+    [invocation setSelector:selector];
+    [invocation setArgument:&object atIndex:2];
+#else
+    /* XXX: this is an unsafe optimization of doomy hell */
+    Method method(class_getInstanceMethod([[self objectAtIndex:0] class], selector));
+    _assert(method != NULL);
+    uint32_t (*imp)(id, SEL, id) = reinterpret_cast<uint32_t (*)(id, SEL, id)>(method_getImplementation(method));
+    _assert(imp != NULL);
+#endif
+
+    struct RadixItem_ *swap(new RadixItem_[count * 2]);
+
+    for (size_t i(0); i != count; ++i) {
+        RadixItem_ &item(swap[i]);
+        item.index = i;
+
+        id object([self objectAtIndex:i]);
+
+#if 0
+        [invocation setTarget:object];
+        [invocation invoke];
+        [invocation getReturnValue:&item.key];
+#else
+        item.key = imp(object, selector, object);
+#endif
+    }
+
+    RadixSort_(self, count, swap);
+}
+
+- (void) radixSortUsingFunction:(SKRadixFunction)function withContext:(void *)argument {
+    size_t count([self count]);
+    struct RadixItem_ *swap(new RadixItem_[count * 2]);
+
+    for (size_t i(0); i != count; ++i) {
+        RadixItem_ &item(swap[i]);
+        item.index = i;
+
+        id object([self objectAtIndex:i]);
+        item.key = function(object, argument);
+    }
+
+    RadixSort_(self, count, swap);
+}
+
+@end
+/* }}} */
+/* Insertion Sort {{{ */
+
+CFIndex SKBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
+    const char *ptr = (const char *)list;
+    while (0 < count) {
+        CFIndex half = count / 2;
+        const char *probe = ptr + elementSize * half;
+        CFComparisonResult cr = comparator(element, probe, context);
+    if (0 == cr) return (probe - (const char *)list) / elementSize;
+        ptr = (cr < 0) ? ptr : probe + elementSize;
+        count = (cr < 0) ? half : (half + (count & 1) - 1);
+    }
+    return (ptr - (const char *)list) / elementSize;
+}
+
+CFIndex CFBSearch_(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
+    const char *ptr = (const char *)list;
+    while (0 < count) {
+        CFIndex half = count / 2;
+        const char *probe = ptr + elementSize * half;
+        CFComparisonResult cr = comparator(element, probe, context);
+    if (0 == cr) return (probe - (const char *)list) / elementSize;
+        ptr = (cr < 0) ? ptr : probe + elementSize;
+        count = (cr < 0) ? half : (half + (count & 1) - 1);
+    }
+    return (ptr - (const char *)list) / elementSize;
+}
+
+void CFArrayInsertionSortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) {
+    if (range.length == 0)
+        return;
+    const void **values(new const void *[range.length]);
+    CFArrayGetValues(array, range, values);
+
+#if HistogramInsertionSort
+    uint32_t total(0), *offsets(new uint32_t[range.length]);
+#endif
+
+    for (CFIndex index(1); index != range.length; ++index) {
+        const void *value(values[index]);
+        //CFIndex correct(SKBSearch_(&value, sizeof(const void *), values, index, comparator, context));
+        CFIndex correct(index);
+        while (comparator(value, values[correct - 1], context) == kCFCompareLessThan)
+            if (--correct == 0)
+                break;
+        if (correct != index) {
+            size_t offset(index - correct);
+#if HistogramInsertionSort
+            total += offset;
+            ++offsets[offset];
+            if (offset > 10)
+                NSLog(@"Heavy Insertion Displacement: %u = %@", offset, value);
+#endif
+            memmove(values + correct + 1, values + correct, sizeof(const void *) * offset);
+            values[correct] = value;
+        }
+    }
+
+    CFArrayReplaceValues(array, range, values, range.length);
+    delete [] values;
+
+#if HistogramInsertionSort
+    for (CFIndex index(0); index != range.length; ++index)
+        if (offsets[index] != 0)
+            NSLog(@"Insertion Displacement [%u]: %u", index, offsets[index]);
+    NSLog(@"Average Insertion Displacement: %f", double(total) / range.length);
+    delete [] offsets;
+#endif
+}
+
+/* }}} */
+
+/* Apple Bug Fixes {{{ */
+@implementation UIWebDocumentView (Cydia)
+
+- (void) _setScrollerOffset:(CGPoint)offset {
+    UIScroller *scroller([self _scroller]);
+
+    CGSize size([scroller contentSize]);
+    CGSize bounds([scroller bounds].size);
+
+    CGPoint max;
+    max.x = size.width - bounds.width;
+    max.y = size.height - bounds.height;
+
+    // wtf Apple?!
+    if (max.x < 0)
+        max.x = 0;
+    if (max.y < 0)
+        max.y = 0;
+
+    offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x;
+    offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y;
+
+    [scroller setOffset:offset];
+}
+
+@end
+/* }}} */
+
+@implementation WebScriptObject (NSFastEnumeration)
+
+- (NSUInteger) countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count {
+    size_t length([self count] - state->state);
+    if (length <= 0)
+        return 0;
+    else if (length > count)
+        length = count;
+    for (size_t i(0); i != length; ++i)
+        objects[i] = [self objectAtIndex:state->state++];
+    state->itemsPtr = objects;
+    state->mutationsPtr = (unsigned long *) self;
+    return length;
+}
+
+@end
+
+NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
+    size_t length([self length] - state->state);
+    if (length <= 0)
+        return 0;
+    else if (length > count)
+        length = count;
+    for (size_t i(0); i != length; ++i)
+        objects[i] = [self item:state->state++];
+    state->itemsPtr = objects;
+    state->mutationsPtr = (unsigned long *) self;
+    return length;
+}
+
+/* Cydia NSString Additions {{{ */
+@interface NSString (Cydia)
++ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length;
++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length withZone:(NSZone *)zone inPool:(apr_pool_t *)pool;
++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length;
+- (NSComparisonResult) compareByPath:(NSString *)other;
+- (NSString *) stringByCachingURLWithCurrentCDN;
+- (NSString *) stringByAddingPercentEscapesIncludingReserved;
+@end
+
+@implementation NSString (Cydia)
+
++ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length {
+    return [[[NSString alloc] initWithBytesNoCopy:const_cast<char *>(bytes) length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
+}
+
++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length withZone:(NSZone *)zone inPool:(apr_pool_t *)pool {
+    char *data(reinterpret_cast<char *>(apr_palloc(pool, length)));
+    memcpy(data, bytes, length);
+    return [[[NSString allocWithZone:zone] initWithBytesNoCopy:data length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
+}
+
++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length {
+    return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease];
+}
+
+- (NSComparisonResult) compareByPath:(NSString *)other {
+    NSString *prefix = [self commonPrefixWithString:other options:0];
+    size_t length = [prefix length];
+
+    NSRange lrange = NSMakeRange(length, [self length] - length);
+    NSRange rrange = NSMakeRange(length, [other length] - length);
+
+    lrange = [self rangeOfString:@"/" options:0 range:lrange];
+    rrange = [other rangeOfString:@"/" options:0 range:rrange];
+
+    NSComparisonResult value;
+
+    if (lrange.location == NSNotFound && rrange.location == NSNotFound)
+        value = NSOrderedSame;
+    else if (lrange.location == NSNotFound)
+        value = NSOrderedAscending;
+    else if (rrange.location == NSNotFound)
+        value = NSOrderedDescending;
+    else
+        value = NSOrderedSame;
+
+    NSString *lpath = lrange.location == NSNotFound ? [self substringFromIndex:length] :
+        [self substringWithRange:NSMakeRange(length, lrange.location - length)];
+    NSString *rpath = rrange.location == NSNotFound ? [other substringFromIndex:length] :
+        [other substringWithRange:NSMakeRange(length, rrange.location - length)];
+
+    NSComparisonResult result = [lpath compare:rpath];
+    return result == NSOrderedSame ? value : result;
+}
+
+- (NSString *) stringByCachingURLWithCurrentCDN {
+    return [self
+        stringByReplacingOccurrencesOfString:@"://cydia.saurik.com/"
+        withString:@"://cache.cydia.saurik.com/"
+    ];
+}
+
+- (NSString *) stringByAddingPercentEscapesIncludingReserved {
+    return [(id)CFURLCreateStringByAddingPercentEscapes(
+        kCFAllocatorDefault,
+        (CFStringRef) self,
+        NULL,
+        CFSTR(";/?:@&=+$,"),
+        kCFStringEncodingUTF8
+    ) autorelease];
+}
+
+@end
+/* }}} */
+
+/* C++ NSString Wrapper Cache {{{ */
+class CYString {
+  private:
+    char *data_;
+    size_t size_;
+    CFStringRef cache_;
+
+    _finline void clear_() {
+        if (cache_ != NULL) {
+            CFRelease(cache_);
+            cache_ = NULL;
+        }
+    }
+
+  public:
+    _finline bool empty() const {
+        return size_ == 0;
+    }
+
+    _finline size_t size() const {
+        return size_;
+    }
+
+    _finline char *data() const {
+        return data_;
+    }
+
+    _finline void clear() {
+        size_ = 0;
+        clear_();
+    }
+
+    _finline CYString() :
+        data_(0),
+        size_(0),
+        cache_(NULL)
+    {
+    }
+
+    _finline ~CYString() {
+        clear_();
+    }
+
+    void operator =(const CYString &rhs) {
+        data_ = rhs.data_;
+        size_ = rhs.size_;
+
+        if (rhs.cache_ == nil)
+            cache_ = NULL;
+        else
+            cache_ = reinterpret_cast<CFStringRef>(CFRetain(rhs.cache_));
+    }
+
+    void set(apr_pool_t *pool, const char *data, size_t size) {
+        if (size == 0)
+            clear();
+        else {
+            clear_();
+
+            char *temp(reinterpret_cast<char *>(apr_palloc(pool, size + 1)));
+            memcpy(temp, data, size);
+            temp[size] = '\0';
+            data_ = temp;
+            size_ = size;
+        }
+    }
+
+    _finline void set(apr_pool_t *pool, const char *data) {
+        set(pool, data, data == NULL ? 0 : strlen(data));
+    }
+
+    _finline void set(apr_pool_t *pool, const std::string &rhs) {
+        set(pool, rhs.data(), rhs.size());
+    }
+
+    bool operator ==(const CYString &rhs) const {
+        return size_ == rhs.size_ && memcmp(data_, rhs.data_, size_) == 0;
+    }
+
+    operator CFStringRef() {
+        if (cache_ == NULL) {
+            if (size_ == 0)
+                return nil;
+            cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+            if (cache_ == NULL)
+                cache_ = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<uint8_t *>(data_), size_, kCFStringEncodingISOLatin1, NO, kCFAllocatorNull);
+        } return cache_;
+    }
+
+    _finline operator id() {
+        return (NSString *) static_cast<CFStringRef>(*this);
+    }
+};
+/* }}} */
+/* C++ NSString Algorithm Adapters {{{ */
+extern "C" {
+    CF_EXPORT CFHashCode CFStringHashNSString(CFStringRef str);
+}
+
+struct NSStringMapHash :
+    std::unary_function<NSString *, size_t>
+{
+    _finline size_t operator ()(NSString *value) const {
+        return CFStringHashNSString((CFStringRef) value);
+    }
+};
+
+struct NSStringMapLess :
+    std::binary_function<NSString *, NSString *, bool>
+{
+    _finline bool operator ()(NSString *lhs, NSString *rhs) const {
+        return [lhs compare:rhs] == NSOrderedAscending;
+    }
+};
+
+struct NSStringMapEqual :
+    std::binary_function<NSString *, NSString *, bool>
+{
+    _finline bool operator ()(NSString *lhs, NSString *rhs) const {
+        return CFStringCompare((CFStringRef) lhs, (CFStringRef) rhs, 0) == kCFCompareEqualTo;
+        //CFEqual((CFTypeRef) lhs, (CFTypeRef) rhs);
+        //[lhs isEqualToString:rhs];
+    }
+};
+/* }}} */
+
+/* Perl-Compatible RegEx {{{ */
+class Pcre {
+  private:
+    pcre *code_;
+    pcre_extra *study_;
+    int capture_;
+    int *matches_;
+    const char *data_;
+
+  public:
+    Pcre(const char *regex) :
+        study_(NULL)
+    {
+        const char *error;
+        int offset;
+        code_ = pcre_compile(regex, 0, &error, &offset, NULL);
+
+        if (code_ == NULL) {
+            lprintf("%d:%s\n", offset, error);
+            _assert(false);
+        }
+
+        pcre_fullinfo(code_, study_, PCRE_INFO_CAPTURECOUNT, &capture_);
+        matches_ = new int[(capture_ + 1) * 3];
+    }
+
+    ~Pcre() {
+        pcre_free(code_);
+        delete matches_;
+    }
+
+    NSString *operator [](size_t match) {
+        return [NSString stringWithUTF8Bytes:(data_ + matches_[match * 2]) length:(matches_[match * 2 + 1] - matches_[match * 2])];
+    }
+
+    bool operator ()(NSString *data) {
+        // XXX: length is for characters, not for bytes
+        return operator ()([data UTF8String], [data length]);
+    }
+
+    bool operator ()(const char *data, size_t size) {
+        data_ = data;
+        return pcre_exec(code_, study_, data, size, 0, 0, matches_, (capture_ + 1) * 3) >= 0;
+    }
+};
+/* }}} */
+/* Mime Addresses {{{ */
+@interface Address : NSObject {
+    NSString *name_;
+    NSString *address_;
+}
+
+- (NSString *) name;
+- (NSString *) address;
+
+- (void) setAddress:(NSString *)address;
+
++ (Address *) addressWithString:(NSString *)string;
+- (Address *) initWithString:(NSString *)string;
+@end
+
+@implementation Address
+
+- (void) dealloc {
+    [name_ release];
+    if (address_ != nil)
+        [address_ release];
+    [super dealloc];
+}
+
+- (NSString *) name {
+    return name_;
+}
+
+- (NSString *) address {
+    return address_;
+}
+
+- (void) setAddress:(NSString *)address {
+    if (address_ != nil)
+        [address_ autorelease];
+    if (address == nil)
+        address_ = nil;
+    else
+        address_ = [address retain];
+}
+
++ (Address *) addressWithString:(NSString *)string {
+    return [[[Address alloc] initWithString:string] autorelease];
+}
+
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:@"address", @"name", nil];
+}
+
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (Address *) initWithString:(NSString *)string {
+    if ((self = [super init]) != nil) {
+        const char *data = [string UTF8String];
+        size_t size = [string length];
+
+        static Pcre address_r("^\"?(.*)\"? <([^>]*)>$");
+
+        if (address_r(data, size)) {
+            name_ = [address_r[1] retain];
+            address_ = [address_r[2] retain];
+        } else {
+            name_ = [string retain];
+            address_ = nil;
+        }
+    } return self;
+}
+
+@end
+/* }}} */
+/* CoreGraphics Primitives {{{ */
+class CYColor {
+  private:
+    CGColorRef color_;
+
+  public:
+    CYColor() :
+        color_(NULL)
+    {
+    }
+
+    CYColor(CGColorSpaceRef space, float red, float green, float blue, float alpha) :
+        color_(NULL)
+    {
+        Set(space, red, green, blue, alpha);
+    }
+
+    void Clear() {
+        if (color_ != NULL)
+            CGColorRelease(color_);
+    }
+
+    ~CYColor() {
+        Clear();
+    }
+
+    void Set(CGColorSpaceRef space, float red, float green, float blue, float alpha) {
+        Clear();
+        float color[] = {red, green, blue, alpha};
+        color_ = CGColorCreate(space, (CGFloat *) color);
+    }
+
+    operator CGColorRef() {
+        return color_;
+    }
+};
+/* }}} */
+
+/* Random Global Variables {{{ */
+static const int PulseInterval_ = 50000;
+static const int ButtonBarWidth_ = 60;
+static const int ButtonBarHeight_ = 48;
+static const float KeyboardTime_ = 0.3f;
+
+static int Finish_;
+static NSArray *Finishes_;
+
+#define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
+#define NotifyConfig_ "/etc/notify.conf"
+
+static bool Queuing_;
+
+static CYColor Blue_;
+static CYColor Blueish_;
+static CYColor Black_;
+static CYColor Off_;
+static CYColor White_;
+static CYColor Gray_;
+static CYColor Green_;
+static CYColor Purple_;
+static CYColor Purplish_;
+
+static UIColor *InstallingColor_;
+static UIColor *RemovingColor_;
+
+static NSString *App_;
+static NSString *Home_;
+
+static BOOL Advanced_;
+static BOOL Ignored_;
+
+static UIFont *Font12_;
+static UIFont *Font12Bold_;
+static UIFont *Font14_;
+static UIFont *Font18Bold_;
+static UIFont *Font22Bold_;
+
+static const char *Machine_ = NULL;
+static NSString *System_ = nil;
+static NSString *SerialNumber_ = nil;
+static NSString *ChipID_ = nil;
+static NSString *Token_ = nil;
+static NSString *UniqueID_ = nil;
+static NSString *Build_ = nil;
+static NSString *Product_ = nil;
+static NSString *Safari_ = nil;
+
+static CFLocaleRef Locale_;
+static NSArray *Languages_;
+static CGColorSpaceRef space_;
+
+static NSDictionary *SectionMap_;
+static NSMutableDictionary *Metadata_;
+static _transient NSMutableDictionary *Settings_;
+static _transient NSString *Role_;
+static _transient NSMutableDictionary *Packages_;
+static _transient NSMutableDictionary *Sections_;
+static _transient NSMutableDictionary *Sources_;
+static bool Changed_;
+static NSDate *now_;
+
+static bool IsWildcat_;
+
+#if RecycleWebViews
+static NSMutableArray *Documents_;
+#endif
+/* }}} */
+
+/* Display Helpers {{{ */
+inline float Interpolate(float begin, float end, float fraction) {
+    return (end - begin) * fraction + begin;
+}
+
+/* XXX: localize this! */
+NSString *SizeString(double size) {
+    bool negative = size < 0;
+    if (negative)
+        size = -size;
+
+    unsigned power = 0;
+    while (size > 1024) {
+        size /= 1024;
+        ++power;
+    }
+
+    static const char *powers_[] = {"B", "kB", "MB", "GB"};
+
+    return [NSString stringWithFormat:@"%s%.1f %s", (negative ? "-" : ""), size, powers_[power]];
+}
+
+static _finline CFStringRef CFCString(const char *value) {
+    return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
+}
+
+const char *StripVersion_(const char *version) {
+    const char *colon(strchr(version, ':'));
+    if (colon != NULL)
+        version = colon + 1;
+    return version;
+}
+
+CFStringRef StripVersion(const char *version) {
+    const char *colon(strchr(version, ':'));
+    if (colon != NULL)
+        version = colon + 1;
+    return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(version), strlen(version), kCFStringEncodingUTF8, NO);
+    // XXX: performance
+    return CFCString(version);
+}
+
+NSString *LocalizeSection(NSString *section) {
+    static Pcre title_r("^(.*?) \\((.*)\\)$");
+    if (title_r(section)) {
+        NSString *parent(title_r[1]);
+        NSString *child(title_r[2]);
+
+        return [NSString stringWithFormat:UCLocalize("PARENTHETICAL"),
+            LocalizeSection(parent),
+            LocalizeSection(child)
+        ];
+    }
+
+    return [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"];
+}
+
+NSString *Simplify(NSString *title) {
+    const char *data = [title UTF8String];
+    size_t size = [title length];
+
+    static Pcre square_r("^\\[(.*)\\]$");
+    if (square_r(data, size))
+        return Simplify(square_r[1]);
+
+    static Pcre paren_r("^\\((.*)\\)$");
+    if (paren_r(data, size))
+        return Simplify(paren_r[1]);
+
+    static Pcre title_r("^(.*?) \\((.*)\\)$");
+    if (title_r(data, size))
+        return Simplify(title_r[1]);
+
+    return title;
+}
+/* }}} */
+
+NSString *GetLastUpdate() {
+    NSDate *update = [Metadata_ objectForKey:@"LastUpdate"];
+
+    if (update == nil)
+        return UCLocalize("NEVER_OR_UNKNOWN");
+
+    CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle);
+    CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) update);
+
+    CFRelease(formatter);
+
+    return [(NSString *) formatted autorelease];
+}
+
+bool isSectionVisible(NSString *section) {
+    NSDictionary *metadata([Sections_ objectForKey:section]);
+    NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]);
+    return hidden == nil || ![hidden boolValue];
+}
+
+@class Cydia;
+
+/* Delegate Prototypes {{{ */
+@class Package;
+@class Source;
+
+@interface NSObject (ProgressDelegate)
+@end
+
+@protocol ProgressDelegate
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)id;
+- (void) setProgressTitle:(NSString *)title;
+- (void) setProgressPercent:(float)percent;
+- (void) startProgress;
+- (void) addProgressOutput:(NSString *)output;
+- (bool) isCancelling:(size_t)received;
+@end
+
+@protocol ConfigurationDelegate
+- (void) repairWithSelector:(SEL)selector;
+- (void) setConfigurationData:(NSString *)data;
+@end
+
+@class PackageController;
+
+@protocol CydiaDelegate
+- (void) setPackageController:(PackageController *)view;
+- (void) clearPackage:(Package *)package;
+- (void) installPackage:(Package *)package;
+- (void) installPackages:(NSArray *)packages;
+- (void) removePackage:(Package *)package;
+- (void) beginUpdate;
+- (BOOL) updating;
+- (void) distUpgrade;
+- (void) loadData;
+- (void) updateData;
+- (void) syncData;
+- (void) showSettings;
+- (UIProgressHUD *) addProgressHUD;
+- (void) removeProgressHUD:(UIProgressHUD *)hud;
+- (CYViewController *) pageForPackage:(NSString *)name;
+- (PackageController *) packageController;
+- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item;
+@end
+/* }}} */
+
+/* Status Delegation {{{ */
+class Status :
+    public pkgAcquireStatus
+{
+  private:
+    _transient NSObject<ProgressDelegate> *delegate_;
+
+  public:
+    Status() :
+        delegate_(nil)
+    {
+    }
+
+    void setDelegate(id delegate) {
+        delegate_ = delegate;
+    }
+
+    NSObject<ProgressDelegate> *getDelegate() const {
+        return delegate_;
+    }
+
+    virtual bool MediaChange(std::string media, std::string drive) {
+        return false;
+    }
+
+    virtual void IMSHit(pkgAcquire::ItemDesc &item) {
+    }
+
+    virtual void Fetch(pkgAcquire::ItemDesc &item) {
+        //NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]);
+        [delegate_ setProgressTitle:[NSString stringWithFormat:UCLocalize("DOWNLOADING_"), [NSString stringWithUTF8String:item.ShortDesc.c_str()]]];
+    }
+
+    virtual void Done(pkgAcquire::ItemDesc &item) {
+    }
+
+    virtual void Fail(pkgAcquire::ItemDesc &item) {
+        if (
+            item.Owner->Status == pkgAcquire::Item::StatIdle ||
+            item.Owner->Status == pkgAcquire::Item::StatDone
+        )
+            return;
+
+        std::string &error(item.Owner->ErrorText);
+        if (error.empty())
+            return;
+
+        NSString *description([NSString stringWithUTF8String:item.Description.c_str()]);
+        NSArray *fields([description componentsSeparatedByString:@" "]);
+        NSString *source([fields count] == 0 ? nil : [fields objectAtIndex:0]);
+
+        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
+            withObject:[NSArray arrayWithObjects:
+                [NSString stringWithUTF8String:error.c_str()],
+                source,
+            nil]
+            waitUntilDone:YES
+        ];
+    }
+
+    virtual bool Pulse(pkgAcquire *Owner) {
+        bool value = pkgAcquireStatus::Pulse(Owner);
+
+        float percent(
+            double(CurrentBytes + CurrentItems) /
+            double(TotalBytes + TotalItems)
+        );
+
+        [delegate_ setProgressPercent:percent];
+        return [delegate_ isCancelling:CurrentBytes] ? false : value;
+    }
+
+    virtual void Start() {
+        [delegate_ startProgress];
+    }
+
+    virtual void Stop() {
+    }
+};
+/* }}} */
+/* Progress Delegation {{{ */
+class Progress :
+    public OpProgress
+{
+  private:
+    _transient id<ProgressDelegate> delegate_;
+    float percent_;
+
+  protected:
+    virtual void Update() {
+        /*if (abs(Percent - percent_) > 2)
+            //NSLog(@"%s:%s:%f", Op.c_str(), SubOp.c_str(), Percent);
+            percent_ = Percent;
+        }*/
+
+        /*[delegate_ setProgressTitle:[NSString stringWithUTF8String:Op.c_str()]];
+        [delegate_ setProgressPercent:(Percent / 100)];*/
+    }
+
+  public:
+    Progress() :
+        delegate_(nil),
+        percent_(0)
+    {
+    }
+
+    void setDelegate(id delegate) {
+        delegate_ = delegate;
+    }
+
+    id getDelegate() const {
+        return delegate_;
+    }
+
+    virtual void Done() {
+        //NSLog(@"DONE");
+        //[delegate_ setProgressPercent:1];
+    }
+};
+/* }}} */
+
+/* Database Interface {{{ */
+typedef std::map< unsigned long, _H<Source> > SourceMap;
+
+@interface Database : NSObject {
+    NSZone *zone_;
+    apr_pool_t *pool_;
+
+    unsigned era_;
+
+    pkgCacheFile cache_;
+    pkgDepCache::Policy *policy_;
+    pkgRecords *records_;
+    pkgProblemResolver *resolver_;
+    pkgAcquire *fetcher_;
+    FileFd *lock_;
+    SPtr<pkgPackageManager> manager_;
+    pkgSourceList *list_;
+
+    SourceMap sources_;
+    NSMutableArray *packages_;
+
+    _transient NSObject<ConfigurationDelegate, ProgressDelegate> *delegate_;
+    Status status_;
+    Progress progress_;
+
+    int cydiafd_;
+    int statusfd_;
+    FILE *input_;
+}
+
++ (Database *) sharedInstance;
+- (unsigned) era;
+
+- (void) _readCydia:(NSNumber *)fd;
+- (void) _readStatus:(NSNumber *)fd;
+- (void) _readOutput:(NSNumber *)fd;
+
+- (FILE *) input;
+
+- (Package *) packageWithName:(NSString *)name;
+
+- (pkgCacheFile &) cache;
+- (pkgDepCache::Policy *) policy;
+- (pkgRecords *) records;
+- (pkgProblemResolver *) resolver;
+- (pkgAcquire &) fetcher;
+- (pkgSourceList &) list;
+- (NSArray *) packages;
+- (NSArray *) sources;
+- (void) reloadData;
+
+- (void) configure;
+- (bool) prepare;
+- (void) perform;
+- (bool) upgrade;
+- (void) update;
+
+- (void) setVisible;
+
+- (void) updateWithStatus:(Status &)status;
+
+- (void) setDelegate:(id)delegate;
+- (Source *) getSource:(pkgCache::PkgFileIterator)file;
+@end
+/* }}} */
+/* Delegate Helpers {{{ */
+@implementation NSObject (ProgressDelegate)
+
+- (void) _setProgressErrorPackage:(NSArray *)args {
+    [self performSelector:@selector(setProgressError:forPackage:)
+        withObject:[args objectAtIndex:0]
+        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
+    ];
+}
+
+- (void) _setProgressErrorTitle:(NSArray *)args {
+    [self performSelector:@selector(setProgressError:withTitle:)
+        withObject:[args objectAtIndex:0]
+        withObject:([args count] == 1 ? nil : [args objectAtIndex:1])
+    ];
+}
+
+- (void) _setProgressError:(NSString *)error withTitle:(NSString *)title {
+    [self performSelectorOnMainThread:@selector(_setProgressErrorTitle:)
+        withObject:[NSArray arrayWithObjects:error, title, nil]
+        waitUntilDone:YES
+    ];
+}
+
+- (void) setProgressError:(NSString *)error forPackage:(NSString *)id {
+    Package *package = id == nil ? nil : [[Database sharedInstance] packageWithName:id];
+
+    [self performSelector:@selector(setProgressError:withTitle:)
+        withObject:error
+        withObject:(package == nil ? id : [package name])
+    ];
+}
+
+@end
+/* }}} */
+
+/* Source Class {{{ */
+@interface Source : NSObject {
+    CYString depiction_;
+    CYString description_;
+    CYString label_;
+    CYString origin_;
+    CYString support_;
+
+    CYString uri_;
+    CYString distribution_;
+    CYString type_;
+    CYString version_;
+
+    NSString *host_;
+    NSString *authority_;
+
+    CYString defaultIcon_;
+
+    NSDictionary *record_;
+    BOOL trusted_;
+}
+
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool;
+
+- (NSComparisonResult) compareByNameAndType:(Source *)source;
+
+- (NSString *) depictionForPackage:(NSString *)package;
+- (NSString *) supportForPackage:(NSString *)package;
+
+- (NSDictionary *) record;
+- (BOOL) trusted;
+
+- (NSString *) uri;
+- (NSString *) distribution;
+- (NSString *) type;
+- (NSString *) key;
+- (NSString *) host;
+
+- (NSString *) name;
+- (NSString *) description;
+- (NSString *) label;
+- (NSString *) origin;
+- (NSString *) version;
+
+- (NSString *) defaultIcon;
+
+@end
+
+@implementation Source
+
+- (void) _clear {
+    uri_.clear();
+    distribution_.clear();
+    type_.clear();
+
+    description_.clear();
+    label_.clear();
+    origin_.clear();
+    depiction_.clear();
+    support_.clear();
+    version_.clear();
+    defaultIcon_.clear();
+
+    if (record_ != nil) {
+        [record_ release];
+        record_ = nil;
+    }
+
+    if (host_ != nil) {
+        [host_ release];
+        host_ = nil;
+    }
+
+    if (authority_ != nil) {
+        [authority_ release];
+        authority_ = nil;
+    }
+}
+
+- (void) dealloc {
+    [self _clear];
+    [super dealloc];
+}
+
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:@"description", @"distribution", @"host", @"key", @"label", @"name", @"origin", @"trusted", @"type", @"uri", @"version", nil];
+}
+
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (void) setMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
+    [self _clear];
+
+    trusted_ = index->IsTrusted();
+
+    uri_.set(pool, index->GetURI());
+    distribution_.set(pool, index->GetDist());
+    type_.set(pool, index->GetType());
+
+    debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
+    if (dindex != NULL) {
+        FileFd fd;
+        if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            pkgTagFile tags(&fd);
+
+            pkgTagSection section;
+            tags.Step(section);
+
+            struct {
+                const char *name_;
+                CYString *value_;
+            } names[] = {
+                {"default-icon", &defaultIcon_},
+                {"depiction", &depiction_},
+                {"description", &description_},
+                {"label", &label_},
+                {"origin", &origin_},
+                {"support", &support_},
+                {"version", &version_},
+            };
+
+            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+                const char *start, *end;
+
+                if (section.Find(names[i].name_, start, end)) {
+                    CYString &value(*names[i].value_);
+                    value.set(pool, start, end - start);
+                }
+            }
+        }
+    }
+
+    record_ = [Sources_ objectForKey:[self key]];
+    if (record_ != nil)
+        record_ = [record_ retain];
+
+    NSURL *url([NSURL URLWithString:uri_]);
+
+    host_ = [url host];
+    if (host_ != nil)
+        host_ = [[host_ lowercaseString] retain];
+
+    if (host_ != nil)
+        authority_ = host_;
+    else
+        authority_ = [url path];
+
+    if (authority_ != nil)
+        authority_ = [authority_ retain];
+}
+
+- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool {
+    if ((self = [super init]) != nil) {
+        [self setMetaIndex:index inPool:pool];
+    } return self;
+}
+
+- (NSComparisonResult) compareByNameAndType:(Source *)source {
+    NSDictionary *lhr = [self record];
+    NSDictionary *rhr = [source record];
+
+    if (lhr != rhr)
+        return lhr == nil ? NSOrderedDescending : NSOrderedAscending;
+
+    NSString *lhs = [self name];
+    NSString *rhs = [source name];
+
+    if ([lhs length] != 0 && [rhs length] != 0) {
+        unichar lhc = [lhs characterAtIndex:0];
+        unichar rhc = [rhs characterAtIndex:0];
+
+        if (isalpha(lhc) && !isalpha(rhc))
+            return NSOrderedAscending;
+        else if (!isalpha(lhc) && isalpha(rhc))
+            return NSOrderedDescending;
+    }
+
+    return [lhs compare:rhs options:LaxCompareOptions_];
+}
+
+- (NSString *) depictionForPackage:(NSString *)package {
+    return depiction_.empty() ? nil : [static_cast<id>(depiction_) stringByReplacingOccurrencesOfString:@"*" withString:package];
+}
+
+- (NSString *) supportForPackage:(NSString *)package {
+    return support_.empty() ? nil : [static_cast<id>(support_) stringByReplacingOccurrencesOfString:@"*" withString:package];
+}
+
+- (NSDictionary *) record {
+    return record_;
+}
+
+- (BOOL) trusted {
+    return trusted_;
+}
+
+- (NSString *) uri {
+    return uri_;
+}
+
+- (NSString *) distribution {
+    return distribution_;
+}
+
+- (NSString *) type {
+    return type_;
+}
+
+- (NSString *) key {
+    return [NSString stringWithFormat:@"%@:%@:%@", (NSString *) type_, (NSString *) uri_, (NSString *) distribution_];
+}
+
+- (NSString *) host {
+    return host_;
+}
+
+- (NSString *) name {
+    return origin_.empty() ? authority_ : origin_;
+}
+
+- (NSString *) description {
+    return description_;
+}
+
+- (NSString *) label {
+    return label_.empty() ? authority_ : label_;
+}
+
+- (NSString *) origin {
+    return origin_;
+}
+
+- (NSString *) version {
+    return version_;
+}
+
+- (NSString *) defaultIcon {
+    return defaultIcon_;
+}
+
+@end
+/* }}} */
+/* Relationship Class {{{ */
+@interface Relationship : NSObject {
+    NSString *type_;
+    NSString *id_;
+}
+
+- (NSString *) type;
+- (NSString *) id;
+- (NSString *) name;
+
+@end
+
+@implementation Relationship
+
+- (void) dealloc {
+    [type_ release];
+    [id_ release];
+    [super dealloc];
+}
+
+- (NSString *) type {
+    return type_;
+}
+
+- (NSString *) id {
+    return id_;
+}
+
+- (NSString *) name {
+    _assert(false);
+    return nil;
+}
+
+@end
+/* }}} */
+/* Package Class {{{ */
+@interface Package : NSObject {
+    unsigned era_;
+    apr_pool_t *pool_;
+
+    pkgCache::VerIterator version_;
+    pkgCache::PkgIterator iterator_;
+    _transient Database *database_;
+    pkgCache::VerFileIterator file_;
+
+    Source *source_;
+    bool cached_;
+    bool parsed_;
+
+    CYString section_;
+    NSString *section$_;
+    bool essential_;
+    bool required_;
+    bool visible_;
+    bool obsolete_;
+
+    NSString *latest_;
+    CYString installed_;
+
+    CYString id_;
+    CYString name_;
+    CYString tagline_;
+    CYString icon_;
+    CYString depiction_;
+    CYString homepage_;
+
+    CYString sponsor_;
+    Address *sponsor$_;
+
+    CYString author_;
+    Address *author$_;
+
+    CYString bugs_;
+    CYString support_;
+    NSMutableArray *tags_;
+    NSString *role_;
+
+    NSArray *relationships_;
+
+    NSMutableDictionary *metadata_;
+    _transient NSDate *firstSeen_;
+    _transient NSDate *lastSeen_;
+    bool subscribed_;
+}
+
+- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
++ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database;
+
+- (pkgCache::PkgIterator) iterator;
+- (void) parse;
+
+- (NSString *) section;
+- (NSString *) simpleSection;
+
+- (NSString *) longSection;
+- (NSString *) shortSection;
+
+- (NSString *) uri;
+
+- (Address *) maintainer;
+- (size_t) size;
+- (NSString *) longDescription;
+- (NSString *) shortDescription;
+- (unichar) index;
+
+- (NSMutableDictionary *) metadata;
+- (NSDate *) seen;
+- (BOOL) subscribed;
+- (BOOL) ignored;
+
+- (NSString *) latest;
+- (NSString *) installed;
+- (BOOL) uninstalled;
+
+- (BOOL) valid;
+- (BOOL) upgradableAndEssential:(BOOL)essential;
+- (BOOL) essential;
+- (BOOL) broken;
+- (BOOL) unfiltered;
+- (BOOL) visible;
+
+- (BOOL) half;
+- (BOOL) halfConfigured;
+- (BOOL) halfInstalled;
+- (BOOL) hasMode;
+- (NSString *) mode;
+
+- (void) setVisible;
+
+- (NSString *) id;
+- (NSString *) name;
+- (UIImage *) icon;
+- (NSString *) homepage;
+- (NSString *) depiction;
+- (Address *) author;
+
+- (NSString *) support;
+
+- (NSArray *) files;
+- (NSArray *) relationships;
+- (NSArray *) warnings;
+- (NSArray *) applications;
+
+- (Source *) source;
+- (NSString *) role;
+
+- (BOOL) matches:(NSString *)text;
+
+- (bool) hasSupportingRole;
+- (BOOL) hasTag:(NSString *)tag;
+- (NSString *) primaryPurpose;
+- (NSArray *) purposes;
+- (bool) isCommercial;
+
+- (CYString &) cyname;
+
+- (uint32_t) compareBySection:(NSArray *)sections;
+
+- (uint32_t) compareForChanges;
+
+- (void) install;
+- (void) remove;
+
+- (bool) isUnfilteredAndSearchedForBy:(NSString *)search;
+- (bool) isUnfilteredAndSelectedForBy:(NSString *)search;
+- (bool) isInstalledAndVisible:(NSNumber *)number;
+- (bool) isVisibleInSection:(NSString *)section;
+- (bool) isVisibleInSource:(Source *)source;
+
+@end
+
+uint32_t PackageChangesRadix(Package *self, void *) {
+    union {
+        uint32_t key;
+
+        struct {
+            uint32_t timestamp : 30;
+            uint32_t ignored : 1;
+            uint32_t upgradable : 1;
+        } bits;
+    } value;
+
+    bool upgradable([self upgradableAndEssential:YES]);
+    value.bits.upgradable = upgradable ? 1 : 0;
+
+    if (upgradable) {
+        value.bits.timestamp = 0;
+        value.bits.ignored = [self ignored] ? 0 : 1;
+        value.bits.upgradable = 1;
+    } else {
+        value.bits.timestamp = static_cast<uint32_t>([[self seen] timeIntervalSince1970]) >> 2;
+        value.bits.ignored = 0;
+        value.bits.upgradable = 0;
+    }
+
+    return _not(uint32_t) - value.key;
+}
+
+_finline static void Stifle(uint8_t &value) {
+}
+
+uint32_t PackagePrefixRadix(Package *self, void *context) {
+    size_t offset(reinterpret_cast<size_t>(context));
+    CYString &name([self cyname]);
+
+    size_t size(name.size());
+    if (size == 0)
+        return 0;
+    char *text(name.data());
+
+    size_t zeros;
+    if (!isdigit(text[0]))
+        zeros = 0;
+    else {
+        size_t digits(1);
+        while (size != digits && isdigit(text[digits]))
+            if (++digits == 4)
+                break;
+        zeros = 4 - digits;
+    }
+
+    uint8_t data[4];
+
+    // 0.607997
+
+    if (offset == 0 && zeros != 0) {
+        memset(data, '0', zeros);
+        memcpy(data + zeros, text, 4 - zeros);
+    } else {
+        /* XXX: there's some danger here if you request a non-zero offset < 4 and it gets zero padded */
+        if (size <= offset - zeros)
+            return 0;
+
+        text += offset - zeros;
+        size -= offset - zeros;
+
+        if (size >= 4)
+            memcpy(data, text, 4);
+        else {
+            memcpy(data, text, size);
+            memset(data + size, 0, 4 - size);
+        }
+
+        for (size_t i(0); i != 4; ++i)
+            if (isalpha(data[i]))
+                data[i] &= 0xdf;
+    }
+
+    if (offset == 0)
+        data[0] = (data[0] & 0x3f) | "\x80\x00\xc0\x40"[data[0] >> 6];
+
+    /* XXX: ntohl may be more honest */
+    return OSSwapInt32(*reinterpret_cast<uint32_t *>(data));
+}
+
+CYString &(*PackageName)(Package *self, SEL sel);
+
+CFComparisonResult PackageNameCompare(Package *lhs, Package *rhs, void *arg) {
+    _profile(PackageNameCompare)
+        CYString &lhi(PackageName(lhs, @selector(cyname)));
+        CYString &rhi(PackageName(rhs, @selector(cyname)));
+        CFStringRef lhn(lhi), rhn(rhi);
+
+        if (lhn == NULL)
+            return rhn == NULL ? NSOrderedSame : NSOrderedAscending;
+        else if (rhn == NULL)
+            return NSOrderedDescending;
+
+        _profile(PackageNameCompare$NumbersLast)
+            if (!lhi.empty() && !rhi.empty()) {
+                UniChar lhc(CFStringGetCharacterAtIndex(lhn, 0));
+                UniChar rhc(CFStringGetCharacterAtIndex(rhn, 0));
+                bool lha(CFUniCharIsMemberOf(lhc, kCFUniCharLetterCharacterSet));
+                if (lha != CFUniCharIsMemberOf(rhc, kCFUniCharLetterCharacterSet))
+                    return lha ? NSOrderedAscending : NSOrderedDescending;
+            }
+        _end
+
+        CFIndex length = CFStringGetLength(lhn);
+
+        _profile(PackageNameCompare$Compare)
+            return CFStringCompareWithOptionsAndLocale(lhn, rhn, CFRangeMake(0, length), LaxCompareFlags_, Locale_);
+        _end
+    _end
+}
+
+CFComparisonResult PackageNameCompare_(Package **lhs, Package **rhs, void *context) {
+    return PackageNameCompare(*lhs, *rhs, context);
+}
+
+struct PackageNameOrdering :
+    std::binary_function<Package *, Package *, bool>
+{
+    _finline bool operator ()(Package *lhs, Package *rhs) const {
+        return PackageNameCompare(lhs, rhs, NULL) == NSOrderedAscending;
+    }
+};
+
+@implementation Package
+
+- (NSString *) description {
+    return [NSString stringWithFormat:@"<Package:%@>", static_cast<NSString *>(name_)];
+}
+
+- (void) dealloc {
+    if (source_ != nil)
+        [source_ release];
+    if (section$_ != nil)
+        [section$_ release];
+
+    if (latest_ != nil)
+        [latest_ release];
+
+    if (sponsor$_ != nil)
+        [sponsor$_ release];
+    if (author$_ != nil)
+        [author$_ release];
+    if (tags_ != nil)
+        [tags_ release];
+    if (role_ != nil)
+        [role_ release];
+
+    if (relationships_ != nil)
+        [relationships_ release];
+    if (metadata_ != nil)
+        [metadata_ release];
+
+    [super dealloc];
+}
+
++ (NSString *) webScriptNameForSelector:(SEL)selector {
+    if (selector == @selector(hasTag:))
+        return @"hasTag";
+    else
+        return nil;
+}
+
++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
+    return [self webScriptNameForSelector:selector] == nil;
+}
+
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"longDescription", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"longSection", @"maintainer", @"mode", @"name", @"purposes", @"section", @"shortDescription", @"shortSection", @"simpleSection", @"size", @"source", @"sponsor", @"support", @"warnings", nil];
+}
+
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (void) parse {
+    if (parsed_)
+        return;
+    parsed_ = true;
+    if (file_.end())
+        return;
+
+    _profile(Package$parse)
+        pkgRecords::Parser *parser;
+
+        _profile(Package$parse$Lookup)
+            parser = &[database_ records]->Lookup(file_);
+        _end
+
+        CYString website;
+
+        _profile(Package$parse$Find)
+            struct {
+                const char *name_;
+                CYString *value_;
+            } names[] = {
+                {"icon", &icon_},
+                {"depiction", &depiction_},
+                {"homepage", &homepage_},
+                {"website", &website},
+                {"bugs", &bugs_},
+                {"support", &support_},
+                {"sponsor", &sponsor_},
+                {"author", &author_},
+            };
+
+            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+                const char *start, *end;
+
+                if (parser->Find(names[i].name_, start, end)) {
+                    CYString &value(*names[i].value_);
+                    _profile(Package$parse$Value)
+                        value.set(pool_, start, end - start);
+                    _end
+                }
+            }
+        _end
+
+        _profile(Package$parse$Tagline)
+            const char *start, *end;
+            if (parser->ShortDesc(start, end)) {
+                const char *stop(reinterpret_cast<const char *>(memchr(start, '\n', end - start)));
+                if (stop == NULL)
+                    stop = end;
+                while (stop != start && stop[-1] == '\r')
+                    --stop;
+                tagline_.set(pool_, start, stop - start);
+            }
+        _end
+
+        _profile(Package$parse$Retain)
+            if (homepage_.empty())
+                homepage_ = website;
+            if (homepage_ == depiction_)
+                homepage_.clear();
+        _end
+    _end
+}
+
+- (void) setVisible {
+    visible_ = required_ && [self unfiltered];
+}
+
+- (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
+    if ((self = [super init]) != nil) {
+    _profile(Package$initWithVersion)
+    @synchronized (database) {
+        era_ = [database era];
+        pool_ = pool;
+
+        version_ = version;
+        iterator_ = version.ParentPkg();
+        database_ = database;
+
+        _profile(Package$initWithVersion$Latest)
+            latest_ = (NSString *) StripVersion(version_.VerStr());
+        _end
+
+        pkgCache::VerIterator current;
+        _profile(Package$initWithVersion$Versions)
+            current = iterator_.CurrentVer();
+            if (!current.end())
+                installed_.set(pool_, StripVersion_(current.VerStr()));
+
+            if (!version_.end())
+                file_ = version_.FileList();
+            else {
+                pkgCache &cache([database_ cache]);
+                file_ = pkgCache::VerFileIterator(cache, cache.VerFileP);
+            }
+        _end
+
+        _profile(Package$initWithVersion$Name)
+            id_.set(pool_, iterator_.Name());
+            name_.set(pool, iterator_.Display());
+        _end
+
+        if (!file_.end()) {
+            _profile(Package$initWithVersion$Source)
+                source_ = [database_ getSource:file_.File()];
+                if (source_ != nil)
+                    [source_ retain];
+                cached_ = true;
+            _end
+        }
+
+        required_ = true;
+
+        _profile(Package$initWithVersion$Tags)
+            pkgCache::TagIterator tag(iterator_.TagList());
+            if (!tag.end()) {
+                tags_ = [[NSMutableArray alloc] initWithCapacity:8];
+                do {
+                    const char *name(tag.Name());
+                    [tags_ addObject:(NSString *)CFCString(name)];
+                    if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
+                        role_ = (NSString *) CFCString(name + 6);
+                    if (required_ && strncmp(name, "require::", 9) == 0 && (
+                        true
+                    ))
+                        required_ = false;
+                    ++tag;
+                } while (!tag.end());
+            }
+        _end
+
+        bool changed(false);
+        NSString *key([static_cast<id>(id_) lowercaseString]);
+
+        _profile(Package$initWithVersion$Metadata)
+            metadata_ = [Packages_ objectForKey:key];
+
+            if (metadata_ == nil) {
+                firstSeen_ = now_;
+
+                metadata_ = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
+                    firstSeen_, @"FirstSeen",
+                    latest_, @"LastVersion",
+                nil] mutableCopy];
+
+                changed = true;
+            } else {
+                firstSeen_ = [metadata_ objectForKey:@"FirstSeen"];
+                lastSeen_ = [metadata_ objectForKey:@"LastSeen"];
+
+                if (NSNumber *subscribed = [metadata_ objectForKey:@"IsSubscribed"])
+                    subscribed_ = [subscribed boolValue];
+
+                NSString *version([metadata_ objectForKey:@"LastVersion"]);
+
+                if (firstSeen_ == nil) {
+                    firstSeen_ = lastSeen_ == nil ? now_ : lastSeen_;
+                    [metadata_ setObject:firstSeen_ forKey:@"FirstSeen"];
+                    changed = true;
+                }
+
+                if (version == nil) {
+                    [metadata_ setObject:latest_ forKey:@"LastVersion"];
+                    changed = true;
+                } else if (![version isEqualToString:latest_]) {
+                    [metadata_ setObject:latest_ forKey:@"LastVersion"];
+                    lastSeen_ = now_;
+                    [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
+                    changed = true;
+                }
+            }
+
+            metadata_ = [metadata_ retain];
+
+            if (changed) {
+                [Packages_ setObject:metadata_ forKey:key];
+                Changed_ = true;
+            }
+        _end
+
+        _profile(Package$initWithVersion$Section)
+            section_.set(pool_, iterator_.Section());
+        _end
+
+        obsolete_ = [self hasTag:@"cydia::obsolete"];
+        essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
+        [self setVisible];
+    } _end } return self;
+}
+
++ (Package *) packageWithIterator:(pkgCache::PkgIterator)iterator withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database {
+@synchronized ([Database class]) {
+    pkgCache::VerIterator version;
+
+    _profile(Package$packageWithIterator$GetCandidateVer)
+        version = [database policy]->GetCandidateVer(iterator);
+    _end
+
+    if (version.end())
+        return nil;
+
+    return [[[Package alloc]
+        initWithVersion:version
+        withZone:zone
+        inPool:pool
+        database:database
+    ] autorelease];
+} }
+
+- (pkgCache::PkgIterator) iterator {
+    return iterator_;
+}
+
+- (NSString *) section {
+    if (section$_ == nil) {
+        if (section_.empty())
+            return nil;
+
+        std::replace(section_.data(), section_.data() + section_.size(), ' ', '_');
+        NSString *name(section_);
+
+      lookup:
+        if (NSDictionary *value = [SectionMap_ objectForKey:name])
+            if (NSString *rename = [value objectForKey:@"Rename"]) {
+                name = rename;
+                goto lookup;
+            }
+
+        section$_ = [[name stringByReplacingCharacter:'_' withCharacter:' '] retain];
+    } return section$_;
+}
+
+- (NSString *) simpleSection {
+    if (NSString *section = [self section])
+        return Simplify(section);
+    else
+        return nil;
+}
+
+- (NSString *) longSection {
+    return LocalizeSection([self section]);
+}
+
+- (NSString *) shortSection {
+    return [[NSBundle mainBundle] localizedStringForKey:[self simpleSection] value:nil table:@"Sections"];
+}
+
+- (NSString *) uri {
+    return nil;
+#if 0
+    pkgIndexFile *index;
+    pkgCache::PkgFileIterator file(file_.File());
+    if (![database_ list].FindIndex(file, index))
+        return nil;
+    return [NSString stringWithUTF8String:iterator_->Path];
+    //return [NSString stringWithUTF8String:file.Site()];
+    //return [NSString stringWithUTF8String:index->ArchiveURI(file.FileName()).c_str()];
+#endif
+}
+
+- (Address *) maintainer {
+    if (file_.end())
+        return nil;
+    pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
+    const std::string &maintainer(parser->Maintainer());
+    return maintainer.empty() ? nil : [Address addressWithString:[NSString stringWithUTF8String:maintainer.c_str()]];
+}
+
+- (size_t) size {
+    return version_.end() ? 0 : version_->InstalledSize;
+}
+
+- (NSString *) longDescription {
+    if (file_.end())
+        return nil;
+    pkgRecords::Parser *parser = &[database_ records]->Lookup(file_);
+    NSString *description([NSString stringWithUTF8String:parser->LongDesc().c_str()]);
+
+    NSArray *lines = [description componentsSeparatedByString:@"\n"];
+    NSMutableArray *trimmed = [NSMutableArray arrayWithCapacity:([lines count] - 1)];
+    if ([lines count] < 2)
+        return nil;
+
+    NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet];
+    for (size_t i(1), e([lines count]); i != e; ++i) {
+        NSString *trim = [[lines objectAtIndex:i] stringByTrimmingCharactersInSet:whitespace];
+        [trimmed addObject:trim];
+    }
+
+    return [trimmed componentsJoinedByString:@"\n"];
+}
+
+- (NSString *) shortDescription {
+    return tagline_;
+}
+
+- (unichar) index {
+    _profile(Package$index)
+        CFStringRef name((CFStringRef) [self name]);
+        if (CFStringGetLength(name) == 0)
+            return '#';
+        UniChar character(CFStringGetCharacterAtIndex(name, 0));
+        if (!CFUniCharIsMemberOf(character, kCFUniCharLetterCharacterSet))
+            return '#';
+        return toupper(character);
+    _end
+}
+
+- (NSMutableDictionary *) metadata {
+    return metadata_;
+}
+
+- (NSDate *) seen {
+    if (subscribed_ && lastSeen_ != nil)
+        return lastSeen_;
+    return firstSeen_;
+}
+
+- (BOOL) subscribed {
+    return subscribed_;
+}
+
+- (BOOL) ignored {
+    NSDictionary *metadata([self metadata]);
+    if (NSNumber *ignored = [metadata objectForKey:@"IsIgnored"])
+        return [ignored boolValue];
+    else
+        return false;
+}
+
+- (NSString *) latest {
+    return latest_;
+}
+
+- (NSString *) installed {
+    return installed_;
+}
+
+- (BOOL) uninstalled {
+    return installed_.empty();
+}
+
+- (BOOL) valid {
+    return !version_.end();
+}
+
+- (BOOL) upgradableAndEssential:(BOOL)essential {
+    _profile(Package$upgradableAndEssential)
+        pkgCache::VerIterator current(iterator_.CurrentVer());
+        if (current.end())
+            return essential && essential_ && visible_;
+        else
+            return !version_.end() && version_ != current;// && (!essential || ![database_ cache][iterator_].Keep());
+    _end
+}
+
+- (BOOL) essential {
+    return essential_;
+}
+
+- (BOOL) broken {
+    return [database_ cache][iterator_].InstBroken();
+}
+
+- (BOOL) unfiltered {
+    NSString *section([self section]);
+    return !obsolete_ && [self hasSupportingRole] && (section == nil || isSectionVisible(section));
+}
+
+- (BOOL) visible {
+    return visible_;
+}
+
+- (BOOL) half {
+    unsigned char current(iterator_->CurrentState);
+    return current == pkgCache::State::HalfConfigured || current == pkgCache::State::HalfInstalled;
+}
+
+- (BOOL) halfConfigured {
+    return iterator_->CurrentState == pkgCache::State::HalfConfigured;
+}
+
+- (BOOL) halfInstalled {
+    return iterator_->CurrentState == pkgCache::State::HalfInstalled;
+}
+
+- (BOOL) hasMode {
+    pkgDepCache::StateCache &state([database_ cache][iterator_]);
+    return state.Mode != pkgDepCache::ModeKeep;
+}
+
+- (NSString *) mode {
+    pkgDepCache::StateCache &state([database_ cache][iterator_]);
+
+    switch (state.Mode) {
+        case pkgDepCache::ModeDelete:
+            if ((state.iFlags & pkgDepCache::Purge) != 0)
+                return @"PURGE";
+            else
+                return @"REMOVE";
+        case pkgDepCache::ModeKeep:
+            if ((state.iFlags & pkgDepCache::ReInstall) != 0)
+                return @"REINSTALL";
+            /*else if ((state.iFlags & pkgDepCache::AutoKept) != 0)
+                return nil;*/
+            else
+                return nil;
+        case pkgDepCache::ModeInstall:
+            /*if ((state.iFlags & pkgDepCache::ReInstall) != 0)
+                return @"REINSTALL";
+            else*/ switch (state.Status) {
+                case -1:
+                    return @"DOWNGRADE";
+                case 0:
+                    return @"INSTALL";
+                case 1:
+                    return @"UPGRADE";
+                case 2:
+                    return @"NEW_INSTALL";
+                _nodefault
+            }
+        _nodefault
+    }
+}
+
+- (NSString *) id {
+    return id_;
+}
+
+- (NSString *) name {
+    return name_.empty() ? id_ : name_;
+}
+
+- (UIImage *) icon {
+    NSString *section = [self simpleSection];
+
+    UIImage *icon(nil);
+    if (!icon_.empty())
+        if ([static_cast<id>(icon_) hasPrefix:@"file:///"])
+            // XXX: correct escaping
+            icon = [UIImage imageAtPath:[static_cast<id>(icon_) substringFromIndex:7]];
+    if (icon == nil) if (section != nil)
+        icon = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]];
+    if (icon == nil) if (source_ != nil) if (NSString *dicon = [source_ defaultIcon])
+        if ([dicon hasPrefix:@"file:///"])
+            // XXX: correct escaping
+            icon = [UIImage imageAtPath:[dicon substringFromIndex:7]];
+    if (icon == nil)
+        icon = [UIImage applicationImageNamed:@"unknown.png"];
+    return icon;
+}
+
+- (NSString *) homepage {
+    return homepage_;
+}
+
+- (NSString *) depiction {
+    return !depiction_.empty() ? depiction_ : [[self source] depictionForPackage:id_];
+}
+
+- (Address *) sponsor {
+    if (sponsor$_ == nil) {
+        if (sponsor_.empty())
+            return nil;
+        sponsor$_ = [[Address addressWithString:sponsor_] retain];
+    } return sponsor$_;
+}
+
+- (Address *) author {
+    if (author$_ == nil) {
+        if (author_.empty())
+            return nil;
+        author$_ = [[Address addressWithString:author_] retain];
+    } return author$_;
+}
+
+- (NSString *) support {
+    return !bugs_.empty() ? bugs_ : [[self source] supportForPackage:id_];
+}
+
+- (NSArray *) files {
+    NSString *path = [NSString stringWithFormat:@"/var/lib/dpkg/info/%@.list", static_cast<NSString *>(id_)];
+    NSMutableArray *files = [NSMutableArray arrayWithCapacity:128];
+
+    std::ifstream fin;
+    fin.open([path UTF8String]);
+    if (!fin.is_open())
+        return nil;
+
+    std::string line;
+    while (std::getline(fin, line))
+        [files addObject:[NSString stringWithUTF8String:line.c_str()]];
+
+    return files;
+}
+
+- (NSArray *) relationships {
+    return relationships_;
+}
+
+- (NSArray *) warnings {
+    NSMutableArray *warnings([NSMutableArray arrayWithCapacity:4]);
+    const char *name(iterator_.Name());
+
+    size_t length(strlen(name));
+    if (length < 2) invalid:
+        [warnings addObject:UCLocalize("ILLEGAL_PACKAGE_IDENTIFIER")];
+    else for (size_t i(0); i != length; ++i)
+        if (
+            /* XXX: technically this is not allowed */
+            (name[i] < 'A' || name[i] > 'Z') &&
+            (name[i] < 'a' || name[i] > 'z') &&
+            (name[i] < '0' || name[i] > '9') &&
+            (i == 0 || name[i] != '+' && name[i] != '-' && name[i] != '.')
+        ) goto invalid;
+
+    if (strcmp(name, "cydia") != 0) {
+        bool cydia = false;
+        bool user = false;
+        bool _private = false;
+        bool stash = false;
+
+        bool repository = [[self section] isEqualToString:@"Repositories"];
+
+        if (NSArray *files = [self files])
+            for (NSString *file in files)
+                if (!cydia && [file isEqualToString:@"/Applications/Cydia.app"])
+                    cydia = true;
+                else if (!user && [file isEqualToString:@"/User"])
+                    user = true;
+                else if (!_private && [file isEqualToString:@"/private"])
+                    _private = true;
+                else if (!stash && [file isEqualToString:@"/var/stash"])
+                    stash = true;
+
+        /* XXX: this is not sensitive enough. only some folders are valid. */
+        if (cydia && !repository)
+            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"Cydia.app"]];
+        if (user)
+            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/User"]];
+        if (_private)
+            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/private"]];
+        if (stash)
+            [warnings addObject:[NSString stringWithFormat:UCLocalize("FILES_INSTALLED_TO"), @"/var/stash"]];
+    }
+
+    return [warnings count] == 0 ? nil : warnings;
+}
+
+- (NSArray *) applications {
+    NSString *me([[NSBundle mainBundle] bundleIdentifier]);
+
+    NSMutableArray *applications([NSMutableArray arrayWithCapacity:2]);
+
+    static Pcre application_r("^/Applications/(.*)\\.app/Info.plist$");
+    if (NSArray *files = [self files])
+        for (NSString *file in files)
+            if (application_r(file)) {
+                NSDictionary *info([NSDictionary dictionaryWithContentsOfFile:file]);
+                NSString *id([info objectForKey:@"CFBundleIdentifier"]);
+                if ([id isEqualToString:me])
+                    continue;
+
+                NSString *display([info objectForKey:@"CFBundleDisplayName"]);
+                if (display == nil)
+                    display = application_r[1];
+
+                NSString *bundle([file stringByDeletingLastPathComponent]);
+                NSString *icon([info objectForKey:@"CFBundleIconFile"]);
+                if (icon == nil || [icon length] == 0)
+                    icon = @"icon.png";
+                NSURL *url([NSURL fileURLWithPath:[bundle stringByAppendingPathComponent:icon]]);
+
+                NSMutableArray *application([NSMutableArray arrayWithCapacity:2]);
+                [applications addObject:application];
+
+                [application addObject:id];
+                [application addObject:display];
+                [application addObject:url];
+            }
+
+    return [applications count] == 0 ? nil : applications;
+}
+
+- (Source *) source {
+    if (!cached_) {
+        @synchronized (database_) {
+            if ([database_ era] != era_ || file_.end())
+                source_ = nil;
+            else {
+                source_ = [database_ getSource:file_.File()];
+                if (source_ != nil)
+                    [source_ retain];
+            }
+
+            cached_ = true;
+        }
+    }
+
+    return source_;
+}
+
+- (NSString *) role {
+    return role_;
+}
+
+- (BOOL) matches:(NSString *)text {
+    if (text == nil)
+        return NO;
+
+    NSRange range;
+
+    range = [[self id] rangeOfString:text options:MatchCompareOptions_];
+    if (range.location != NSNotFound)
+        return YES;
+
+    range = [[self name] rangeOfString:text options:MatchCompareOptions_];
+    if (range.location != NSNotFound)
+        return YES;
+
+    range = [[self shortDescription] rangeOfString:text options:MatchCompareOptions_];
+    if (range.location != NSNotFound)
+        return YES;
+
+    return NO;
+}
+
+- (bool) hasSupportingRole {
+    if (role_ == nil)
+        return true;
+    if ([role_ isEqualToString:@"enduser"])
+        return true;
+    if ([Role_ isEqualToString:@"User"])
+        return false;
+    if ([role_ isEqualToString:@"hacker"])
+        return true;
+    if ([Role_ isEqualToString:@"Hacker"])
+        return false;
+    if ([role_ isEqualToString:@"developer"])
+        return true;
+    if ([Role_ isEqualToString:@"Developer"])
+        return false;
+    _assert(false);
+}
+
+- (BOOL) hasTag:(NSString *)tag {
+    return tags_ == nil ? NO : [tags_ containsObject:tag];
+}
+
+- (NSString *) primaryPurpose {
+    for (NSString *tag in tags_)
+        if ([tag hasPrefix:@"purpose::"])
+            return [tag substringFromIndex:9];
+    return nil;
+}
+
+- (NSArray *) purposes {
+    NSMutableArray *purposes([NSMutableArray arrayWithCapacity:2]);
+    for (NSString *tag in tags_)
+        if ([tag hasPrefix:@"purpose::"])
+            [purposes addObject:[tag substringFromIndex:9]];
+    return [purposes count] == 0 ? nil : purposes;
+}
+
+- (bool) isCommercial {
+    return [self hasTag:@"cydia::commercial"];
+}
+
+- (CYString &) cyname {
+    return name_.empty() ? id_ : name_;
+}
+
+- (uint32_t) compareBySection:(NSArray *)sections {
+    NSString *section([self section]);
+    for (size_t i(0), e([sections count]); i != e; ++i) {
+        if ([section isEqualToString:[[sections objectAtIndex:i] name]])
+            return i;
+    }
+
+    return _not(uint32_t);
+}
+
+- (uint32_t) compareForChanges {
+    union {
+        uint32_t key;
+
+        struct {
+            uint32_t timestamp : 30;
+            uint32_t ignored : 1;
+            uint32_t upgradable : 1;
+        } bits;
+    } value;
+
+    bool upgradable([self upgradableAndEssential:YES]);
+    value.bits.upgradable = upgradable ? 1 : 0;
+
+    if (upgradable) {
+        value.bits.timestamp = 0;
+        value.bits.ignored = [self ignored] ? 0 : 1;
+        value.bits.upgradable = 1;
+    } else {
+        value.bits.timestamp = static_cast<uint32_t>([[self seen] timeIntervalSince1970]) >> 2;
+        value.bits.ignored = 0;
+        value.bits.upgradable = 0;
+    }
+
+    return _not(uint32_t) - value.key;
+}
+
+- (void) clear {
+    pkgProblemResolver *resolver = [database_ resolver];
+    resolver->Clear(iterator_);
+    resolver->Protect(iterator_);
+}
+
+- (void) install {
+    pkgProblemResolver *resolver = [database_ resolver];
+    resolver->Clear(iterator_);
+    resolver->Protect(iterator_);
+    pkgCacheFile &cache([database_ cache]);
+    cache->MarkInstall(iterator_, false);
+    pkgDepCache::StateCache &state((*cache)[iterator_]);
+    if (!state.Install())
+        cache->SetReInstall(iterator_, true);
+}
+
+- (void) remove {
+    pkgProblemResolver *resolver = [database_ resolver];
+    resolver->Clear(iterator_);
+    resolver->Protect(iterator_);
+    resolver->Remove(iterator_);
+    [database_ cache]->MarkDelete(iterator_, true);
+}
+
+- (bool) isUnfilteredAndSearchedForBy:(NSString *)search {
+    _profile(Package$isUnfilteredAndSearchedForBy)
+        bool value(true);
+
+        _profile(Package$isUnfilteredAndSearchedForBy$Unfiltered)
+            value &= [self unfiltered];
+        _end
+
+        _profile(Package$isUnfilteredAndSearchedForBy$Match)
+            value &= [self matches:search];
+        _end
+
+        return value;
+    _end
+}
+
+- (bool) isUnfilteredAndSelectedForBy:(NSString *)search {
+    if ([search length] == 0)
+        return false;
+
+    _profile(Package$isUnfilteredAndSelectedForBy)
+        bool value(true);
+
+        _profile(Package$isUnfilteredAndSelectedForBy$Unfiltered)
+            value &= [self unfiltered];
+        _end
+
+        _profile(Package$isUnfilteredAndSelectedForBy$Match)
+            value &= [[self name] compare:search options:MatchCompareOptions_ range:NSMakeRange(0, [search length])] == NSOrderedSame;
+        _end
+
+        return value;
+    _end
+}
+
+- (bool) isInstalledAndVisible:(NSNumber *)number {
+    return (![number boolValue] || [self visible]) && ![self uninstalled];
+}
+
+- (bool) isVisibleInSection:(NSString *)name {
+    NSString *section = [self section];
+
+    return
+        [self visible] && (
+            name == nil ||
+            section == nil && [name length] == 0 ||
+            [name isEqualToString:section]
+        );
+}
+
+- (bool) isVisibleInSource:(Source *)source {
+    return [self source] == source && [self visible];
+}
+
+@end
+/* }}} */
+/* Section Class {{{ */
+@interface Section : NSObject {
+    NSString *name_;
+    unichar index_;
+    size_t row_;
+    size_t count_;
+    NSString *localized_;
+}
+
+- (NSComparisonResult) compareByLocalized:(Section *)section;
+- (Section *) initWithName:(NSString *)name localized:(NSString *)localized;
+- (Section *) initWithName:(NSString *)name localize:(BOOL)localize;
+- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize;
+- (Section *) initWithIndex:(unichar)index row:(size_t)row;
+- (NSString *) name;
+- (unichar) index;
+
+- (size_t) row;
+- (size_t) count;
+
+- (void) addToRow;
+- (void) addToCount;
+
+- (void) setCount:(size_t)count;
+- (NSString *) localized;
+
+@end
+
+@implementation Section
+
+- (void) dealloc {
+    [name_ release];
+    if (localized_ != nil)
+        [localized_ release];
+    [super dealloc];
+}
+
+- (NSComparisonResult) compareByLocalized:(Section *)section {
+    NSString *lhs(localized_);
+    NSString *rhs([section localized]);
+
+    /*if ([lhs length] != 0 && [rhs length] != 0) {
+        unichar lhc = [lhs characterAtIndex:0];
+        unichar rhc = [rhs characterAtIndex:0];
+
+        if (isalpha(lhc) && !isalpha(rhc))
+            return NSOrderedAscending;
+        else if (!isalpha(lhc) && isalpha(rhc))
+            return NSOrderedDescending;
+    }*/
+
+    return [lhs compare:rhs options:LaxCompareOptions_];
+}
+
+- (Section *) initWithName:(NSString *)name localized:(NSString *)localized {
+    if ((self = [self initWithName:name localize:NO]) != nil) {
+        if (localized != nil)
+            localized_ = [localized retain];
+    } return self;
+}
+
+- (Section *) initWithName:(NSString *)name localize:(BOOL)localize {
+    return [self initWithName:name row:0 localize:localize];
+}
+
+- (Section *) initWithName:(NSString *)name row:(size_t)row localize:(BOOL)localize {
+    if ((self = [super init]) != nil) {
+        name_ = [name retain];
+        index_ = '\0';
+        row_ = row;
+        if (localize)
+            localized_ = [LocalizeSection(name_) retain];
+    } return self;
+}
+
+/* XXX: localize the index thingees */
+- (Section *) initWithIndex:(unichar)index row:(size_t)row {
+    if ((self = [super init]) != nil) {
+        name_ = [[NSString stringWithCharacters:&index length:1] retain];
+        index_ = index;
+        row_ = row;
+    } return self;
+}
+
+- (NSString *) name {
+    return name_;
+}
+
+- (unichar) index {
+    return index_;
+}
+
+- (size_t) row {
+    return row_;
+}
+
+- (size_t) count {
+    return count_;
+}
+
+- (void) addToRow {
+    ++row_;
+}
+
+- (void) addToCount {
+    ++count_;
+}
+
+- (void) setCount:(size_t)count {
+    count_ = count;
+}
+
+- (NSString *) localized {
+    return localized_;
+}
+
+@end
+/* }}} */
+
+static NSString *Colon_;
+static NSString *Error_;
+static NSString *Warning_;
+
+/* Database Implementation {{{ */
+@implementation Database
+
++ (Database *) sharedInstance {
+    static Database *instance;
+    if (instance == nil)
+        instance = [[Database alloc] init];
+    return instance;
+}
+
+- (unsigned) era {
+    return era_;
+}
+
+- (void) dealloc {
+    _assert(false);
+    NSRecycleZone(zone_);
+    // XXX: malloc_destroy_zone(zone_);
+    apr_pool_destroy(pool_);
+    [super dealloc];
+}
+
+- (void) _readCydia:(NSNumber *)fd { _pooled
+    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
+    std::istream is(&ib);
+    std::string line;
+
+    static Pcre finish_r("^finish:([^:]*)$");
+
+    while (std::getline(is, line)) {
+        const char *data(line.c_str());
+        size_t size = line.size();
+        lprintf("C:%s\n", data);
+
+        if (finish_r(data, size)) {
+            NSString *finish = finish_r[1];
+            int index = [Finishes_ indexOfObject:finish];
+            if (index != INT_MAX && index > Finish_)
+                Finish_ = index;
+        }
+    }
+
+    _assume(false);
+}
+
+- (void) _readStatus:(NSNumber *)fd { _pooled
+    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
+    std::istream is(&ib);
+    std::string line;
+
+    static Pcre conffile_r("^status: [^ ]* : conffile-prompt : (.*?) *$");
+    static Pcre pmstatus_r("^([^:]*):([^:]*):([^:]*):(.*)$");
+
+    while (std::getline(is, line)) {
+        const char *data(line.c_str());
+        size_t size(line.size());
+        lprintf("S:%s\n", data);
+
+        if (conffile_r(data, size)) {
+            [delegate_ setConfigurationData:conffile_r[1]];
+        } else if (strncmp(data, "status: ", 8) == 0) {
+            NSString *string = [NSString stringWithUTF8String:(data + 8)];
+            [delegate_ setProgressTitle:string];
+        } else if (pmstatus_r(data, size)) {
+            std::string type([pmstatus_r[1] UTF8String]);
+            NSString *id = pmstatus_r[2];
+
+            float percent([pmstatus_r[3] floatValue]);
+            [delegate_ setProgressPercent:(percent / 100)];
+
+            NSString *string = pmstatus_r[4];
+
+            if (type == "pmerror")
+                [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
+                    withObject:[NSArray arrayWithObjects:string, id, nil]
+                    waitUntilDone:YES
+                ];
+            else if (type == "pmstatus") {
+                [delegate_ setProgressTitle:string];
+            } else if (type == "pmconffile")
+                [delegate_ setConfigurationData:string];
+            else
+                lprintf("E:unknown pmstatus\n");
+        } else
+            lprintf("E:unknown status\n");
+    }
+
+    _assume(false);
+}
+
+- (void) _readOutput:(NSNumber *)fd { _pooled
+    __gnu_cxx::stdio_filebuf<char> ib([fd intValue], std::ios::in);
+    std::istream is(&ib);
+    std::string line;
+
+    while (std::getline(is, line)) {
+        lprintf("O:%s\n", line.c_str());
+        [delegate_ addProgressOutput:[NSString stringWithUTF8String:line.c_str()]];
+    }
+
+    _assume(false);
+}
+
+- (FILE *) input {
+    return input_;
+}
+
+- (Package *) packageWithName:(NSString *)name {
+@synchronized ([Database class]) {
+    if (static_cast<pkgDepCache *>(cache_) == NULL)
+        return nil;
+    pkgCache::PkgIterator iterator(cache_->FindPkg([name UTF8String]));
+    return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:pool_ database:self];
+} }
+
+- (id) init {
+    if ((self = [super init]) != nil) {
+        policy_ = NULL;
+        records_ = NULL;
+        resolver_ = NULL;
+        fetcher_ = NULL;
+        lock_ = NULL;
+
+        zone_ = NSCreateZone(1024 * 1024, 256 * 1024, NO);
+        apr_pool_create(&pool_, NULL);
+
+        packages_ = [[NSMutableArray alloc] init];
+
+        int fds[2];
+
+        _assert(pipe(fds) != -1);
+        cydiafd_ = fds[1];
+
+        _config->Set("APT::Keep-Fds::", cydiafd_);
+        setenv("CYDIA", [[[[NSNumber numberWithInt:cydiafd_] stringValue] stringByAppendingString:@" 1"] UTF8String], _not(int));
+
+        [NSThread
+            detachNewThreadSelector:@selector(_readCydia:)
+            toTarget:self
+            withObject:[[NSNumber numberWithInt:fds[0]] retain]
+        ];
+
+        _assert(pipe(fds) != -1);
+        statusfd_ = fds[1];
+
+        [NSThread
+            detachNewThreadSelector:@selector(_readStatus:)
+            toTarget:self
+            withObject:[[NSNumber numberWithInt:fds[0]] retain]
+        ];
+
+        _assert(pipe(fds) != -1);
+        _assert(dup2(fds[0], 0) != -1);
+        _assert(close(fds[0]) != -1);
+
+        input_ = fdopen(fds[1], "a");
+
+        _assert(pipe(fds) != -1);
+        _assert(dup2(fds[1], 1) != -1);
+        _assert(close(fds[1]) != -1);
+
+        [NSThread
+            detachNewThreadSelector:@selector(_readOutput:)
+            toTarget:self
+            withObject:[[NSNumber numberWithInt:fds[0]] retain]
+        ];
+    } return self;
+}
+
+- (pkgCacheFile &) cache {
+    return cache_;
+}
+
+- (pkgDepCache::Policy *) policy {
+    return policy_;
+}
+
+- (pkgRecords *) records {
+    return records_;
+}
+
+- (pkgProblemResolver *) resolver {
+    return resolver_;
+}
+
+- (pkgAcquire &) fetcher {
+    return *fetcher_;
+}
+
+- (pkgSourceList &) list {
+    return *list_;
+}
+
+- (NSArray *) packages {
+    return packages_;
+}
+
+- (NSArray *) sources {
+    NSMutableArray *sources([NSMutableArray arrayWithCapacity:sources_.size()]);
+    for (SourceMap::const_iterator i(sources_.begin()); i != sources_.end(); ++i)
+        [sources addObject:i->second];
+    return sources;
+}
+
+- (NSArray *) issues {
+    if (cache_->BrokenCount() == 0)
+        return nil;
+
+    NSMutableArray *issues([NSMutableArray arrayWithCapacity:4]);
+
+    for (Package *package in packages_) {
+        if (![package broken])
+            continue;
+        pkgCache::PkgIterator pkg([package iterator]);
+
+        NSMutableArray *entry([NSMutableArray arrayWithCapacity:4]);
+        [entry addObject:[package name]];
+        [issues addObject:entry];
+
+        pkgCache::VerIterator ver(cache_[pkg].InstVerIter(cache_));
+        if (ver.end())
+            continue;
+
+        for (pkgCache::DepIterator dep(ver.DependsList()); !dep.end(); ) {
+            pkgCache::DepIterator start;
+            pkgCache::DepIterator end;
+            dep.GlobOr(start, end); // ++dep
+
+            if (!cache_->IsImportantDep(end))
+                continue;
+            if ((cache_[end] & pkgDepCache::DepGInstall) != 0)
+                continue;
+
+            NSMutableArray *failure([NSMutableArray arrayWithCapacity:4]);
+            [entry addObject:failure];
+            [failure addObject:[NSString stringWithUTF8String:start.DepType()]];
+
+            NSString *name([NSString stringWithUTF8String:start.TargetPkg().Name()]);
+            if (Package *package = [self packageWithName:name])
+                name = [package name];
+            [failure addObject:name];
+
+            pkgCache::PkgIterator target(start.TargetPkg());
+            if (target->ProvidesList != 0)
+                [failure addObject:@"?"];
+            else {
+                pkgCache::VerIterator ver(cache_[target].InstVerIter(cache_));
+                if (!ver.end())
+                    [failure addObject:[NSString stringWithUTF8String:ver.VerStr()]];
+                else if (!cache_[target].CandidateVerIter(cache_).end())
+                    [failure addObject:@"-"];
+                else if (target->ProvidesList == 0)
+                    [failure addObject:@"!"];
+                else
+                    [failure addObject:@"%"];
+            }
+
+            _forever {
+                if (start.TargetVer() != 0)
+                    [failure addObject:[NSString stringWithFormat:@"%s %s", start.CompType(), start.TargetVer()]];
+                if (start == end)
+                    break;
+                ++start;
+            }
+        }
+    }
+
+    return issues;
+}
+
+- (bool) popErrorWithTitle:(NSString *)title {
+    bool fatal(false);
+    std::string message;
+
+    while (!_error->empty()) {
+        std::string error;
+        bool warning(!_error->PopMessage(error));
+        if (!warning)
+            fatal = true;
+        for (;;) {
+            size_t size(error.size());
+            if (size == 0 || error[size - 1] != '\n')
+                break;
+            error.resize(size - 1);
+        }
+        lprintf("%c:[%s]\n", warning ? 'W' : 'E', error.c_str());
+
+        if (!message.empty())
+            message += "\n\n";
+        message += error;
+    }
+
+    if (fatal && !message.empty())
+        [delegate_ _setProgressError:[NSString stringWithUTF8String:message.c_str()] withTitle:[NSString stringWithFormat:Colon_, fatal ? Error_ : Warning_, title]];
+
+    return fatal;
+}
+
+- (bool) popErrorWithTitle:(NSString *)title forOperation:(bool)success {
+    return [self popErrorWithTitle:title] || !success;
+}
+
+- (void) reloadData { _pooled
+@synchronized ([Database class]) {
+    @synchronized (self) {
+        ++era_;
+    }
+
+    [packages_ removeAllObjects];
+    sources_.clear();
+
+    _error->Discard();
+
+    delete list_;
+    list_ = NULL;
+    manager_ = NULL;
+    delete lock_;
+    lock_ = NULL;
+    delete fetcher_;
+    fetcher_ = NULL;
+    delete resolver_;
+    resolver_ = NULL;
+    delete records_;
+    records_ = NULL;
+    delete policy_;
+    policy_ = NULL;
+
+    if (now_ != nil) {
+        [now_ release];
+        now_ = nil;
+    }
+
+    cache_.Close();
+
+    apr_pool_clear(pool_);
+    NSRecycleZone(zone_);
+
+    int chk(creat("/tmp/cydia.chk", 0644));
+    if (chk != -1)
+        close(chk);
+
+    NSString *title(UCLocalize("DATABASE"));
+
+    _trace();
+    if (!cache_.Open(progress_, true)) { pop:
+        std::string error;
+        bool warning(!_error->PopMessage(error));
+        lprintf("cache_.Open():[%s]\n", error.c_str());
+
+        if (error == "dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem. ")
+            [delegate_ repairWithSelector:@selector(configure)];
+        else if (error == "The package lists or status file could not be parsed or opened.")
+            [delegate_ repairWithSelector:@selector(update)];
+        // else if (error == "Could not open lock file /var/lib/dpkg/lock - open (13 Permission denied)")
+        // else if (error == "Could not get lock /var/lib/dpkg/lock - open (35 Resource temporarily unavailable)")
+        // else if (error == "The list of sources could not be read.")
+        else
+            [delegate_ _setProgressError:[NSString stringWithUTF8String:error.c_str()] withTitle:[NSString stringWithFormat:Colon_, warning ? Warning_ : Error_, title]];
+
+        if (warning)
+            goto pop;
+        _error->Discard();
+        return;
+    }
+    _trace();
+
+    unlink("/tmp/cydia.chk");
+
+    now_ = [[NSDate date] retain];
+
+    policy_ = new pkgDepCache::Policy();
+    records_ = new pkgRecords(cache_);
+    resolver_ = new pkgProblemResolver(cache_);
+    fetcher_ = new pkgAcquire(&status_);
+    lock_ = NULL;
+
+    list_ = new pkgSourceList();
+    if ([self popErrorWithTitle:title forOperation:list_->ReadMainList()])
+        return;
+
+    if (cache_->DelCount() != 0 || cache_->InstCount() != 0) {
+        [delegate_ _setProgressError:@"COUNTS_NONZERO_EX" withTitle:title];
+        return;
+    }
+
+    if ([self popErrorWithTitle:title forOperation:pkgApplyStatus(cache_)])
+        return;
+
+    if (cache_->BrokenCount() != 0) {
+        if ([self popErrorWithTitle:title forOperation:pkgFixBroken(cache_)])
+            return;
+
+        if (cache_->BrokenCount() != 0) {
+            [delegate_ _setProgressError:@"STILL_BROKEN_EX" withTitle:title];
+            return;
+        }
+
+        if ([self popErrorWithTitle:title forOperation:pkgMinimizeUpgrade(cache_)])
+            return;
+    }
+
+    _trace();
+
+    for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) {
+        std::vector<pkgIndexFile *> *indices = (*source)->GetIndexFiles();
+        for (std::vector<pkgIndexFile *>::const_iterator index = indices->begin(); index != indices->end(); ++index)
+            // XXX: this could be more intelligent
+            if (dynamic_cast<debPackagesIndex *>(*index) != NULL) {
+                pkgCache::PkgFileIterator cached((*index)->FindInCache(cache_));
+                if (!cached.end())
+                    sources_[cached->ID] = [[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease];
+            }
+    }
+
+    _trace();
+
+    {
+        /*std::vector<Package *> packages;
+        packages.reserve(std::max(10000U, [packages_ count] + 1000));
+        [packages_ release];
+        packages_ = nil;*/
+
+        _trace();
+
+        for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator)
+            if (Package *package = [Package packageWithIterator:iterator withZone:zone_ inPool:pool_ database:self])
+                //packages.push_back(package);
+                [packages_ addObject:package];
+
+        _trace();
+
+        /*if (packages.empty())
+            packages_ = [[NSArray alloc] init];
+        else
+            packages_ = [[NSArray alloc] initWithObjects:&packages.front() count:packages.size()];
+        _trace();*/
+
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(16)];
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(4)];
+        [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackagePrefixRadix) withContext:reinterpret_cast<void *>(0)];
+
+        /*_trace();
+        PrintTimes();
+        _trace();*/
+
+        _trace();
+
+        /*if (!packages.empty())
+            CFQSortArray(&packages.front(), packages.size(), sizeof(packages.front()), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare_), NULL);*/
+        //std::sort(packages.begin(), packages.end(), PackageNameOrdering());
+
+        //CFArraySortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+        CFArrayInsertionSortValues((CFMutableArrayRef) packages_, CFRangeMake(0, [packages_ count]), reinterpret_cast<CFComparatorFunction>(&PackageNameCompare), NULL);
+
+        //[packages_ sortUsingFunction:reinterpret_cast<NSComparisonResult (*)(id, id, void *)>(&PackageNameCompare) context:NULL];
+
+        _trace();
+    }
+} }
+
+- (void) configure {
+    NSString *dpkg = [NSString stringWithFormat:@"dpkg --configure -a --status-fd %u", statusfd_];
+    system([dpkg UTF8String]);
+}
+
+- (bool) clean {
+    // XXX: I don't remember this condition
+    if (lock_ != NULL)
+        return false;
+
+    FileFd Lock;
+    Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+
+    NSString *title(UCLocalize("CLEAN_ARCHIVES"));
+
+    if ([self popErrorWithTitle:title])
+        return false;
+
+    pkgAcquire fetcher;
+    fetcher.Clean(_config->FindDir("Dir::Cache::Archives"));
+
+    class LogCleaner :
+        public pkgArchiveCleaner
+    {
+      protected:
+        virtual void Erase(const char *File, std::string Pkg, std::string Ver, struct stat &St) {
+            unlink(File);
+        }
+    } cleaner;
+
+    if ([self popErrorWithTitle:title forOperation:cleaner.Go(_config->FindDir("Dir::Cache::Archives") + "partial/", cache_)])
+        return false;
+
+    return true;
+}
+
+- (bool) prepare {
+    fetcher_->Shutdown();
+
+    pkgRecords records(cache_);
+
+    lock_ = new FileFd();
+    lock_->Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+
+    NSString *title(UCLocalize("PREPARE_ARCHIVES"));
+
+    if ([self popErrorWithTitle:title])
+        return false;
+
+    pkgSourceList list;
+    if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+        return false;
+
+    manager_ = (_system->CreatePM(cache_));
+    if ([self popErrorWithTitle:title forOperation:manager_->GetArchives(fetcher_, &list, &records)])
+        return false;
+
+    return true;
+}
+
+- (void) perform {
+    NSString *title(UCLocalize("PERFORM_SELECTIONS"));
+
+    NSMutableArray *before = [NSMutableArray arrayWithCapacity:16]; {
+        pkgSourceList list;
+        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+            return;
+        for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
+            [before addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
+    }
+
+    if (fetcher_->Run(PulseInterval_) != pkgAcquire::Continue) {
+        _trace();
+        return;
+    }
+
+    bool failed = false;
+    for (pkgAcquire::ItemIterator item = fetcher_->ItemsBegin(); item != fetcher_->ItemsEnd(); item++) {
+        if ((*item)->Status == pkgAcquire::Item::StatDone && (*item)->Complete)
+            continue;
+        if ((*item)->Status == pkgAcquire::Item::StatIdle)
+            continue;
+
+        std::string uri = (*item)->DescURI();
+        std::string error = (*item)->ErrorText;
+
+        lprintf("pAf:%s:%s\n", uri.c_str(), error.c_str());
+        failed = true;
+
+        [delegate_ performSelectorOnMainThread:@selector(_setProgressErrorPackage:)
+            withObject:[NSArray arrayWithObjects:
+                [NSString stringWithUTF8String:error.c_str()],
+            nil]
+            waitUntilDone:YES
+        ];
+    }
+
+    if (failed) {
+        _trace();
+        return;
+    }
+
+    _system->UnLock();
+    pkgPackageManager::OrderResult result = manager_->DoInstall(statusfd_);
+
+    if (_error->PendingError()) {
+        _trace();
+        return;
+    }
+
+    if (result == pkgPackageManager::Failed) {
+        _trace();
+        return;
+    }
+
+    if (result != pkgPackageManager::Completed) {
+        _trace();
+        return;
+    }
+
+    NSMutableArray *after = [NSMutableArray arrayWithCapacity:16]; {
+        pkgSourceList list;
+        if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+            return;
+        for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source)
+            [after addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]];
+    }
+
+    if (![before isEqualToArray:after])
+        [self update];
+}
+
+- (bool) upgrade {
+    NSString *title(UCLocalize("UPGRADE"));
+    if ([self popErrorWithTitle:title forOperation:pkgDistUpgrade(cache_)])
+        return false;
+    return true;
+}
+
+- (void) update {
+    [self updateWithStatus:status_];
+}
+
+- (void) setVisible {
+    for (Package *package in packages_)
+        [package setVisible];
+}
+
+- (void) updateWithStatus:(Status &)status {
+    _transient NSObject<ProgressDelegate> *delegate(status.getDelegate());
+    NSString *title(UCLocalize("REFRESHING_DATA"));
+
+    pkgSourceList list;
+    if (!list.ReadMainList())
+        [delegate _setProgressError:@"Unable to read source list." withTitle:title];
+
+    FileFd lock;
+    lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
+    if ([self popErrorWithTitle:title])
+        return;
+
+    if ([self popErrorWithTitle:title forOperation:ListUpdate(status, list, PulseInterval_)])
+        /* XXX: ignore this because users suck and don't understand why refreshing is important: return */
+        /* XXX: why the hell is an empty if statement a clang error? */ (void) 0;
+
+    [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
+    Changed_ = true;
+}
+
+- (void) setDelegate:(id)delegate {
+    delegate_ = delegate;
+    status_.setDelegate(delegate);
+    progress_.setDelegate(delegate);
+}
+
+- (Source *) getSource:(pkgCache::PkgFileIterator)file {
+    SourceMap::const_iterator i(sources_.find(file->ID));
+    return i == sources_.end() ? nil : i->second;
+}
+
+@end
+/* }}} */
+
+/* Confirmation Controller {{{ */
+bool DepSubstrate(const pkgCache::VerIterator &iterator) {
+    if (!iterator.end())
+        for (pkgCache::DepIterator dep(iterator.DependsList()); !dep.end(); ++dep) {
+            if (dep->Type != pkgCache::Dep::Depends && dep->Type != pkgCache::Dep::PreDepends)
+                continue;
+            pkgCache::PkgIterator package(dep.TargetPkg());
+            if (package.end())
+                continue;
+            if (strcmp(package.Name(), "mobilesubstrate") == 0)
+                return true;
+        }
+
+    return false;
+}
+/* }}} */
+
+/* Web Scripting {{{ */
+@interface CydiaObject : NSObject {
+    id indirect_;
+    id delegate_;
+}
+
+- (id) initWithDelegate:(IndirectDelegate *)indirect;
+@end
+
+@implementation CydiaObject
+
+- (void) dealloc {
+    [indirect_ release];
+    [super dealloc];
+}
+
+- (id) initWithDelegate:(IndirectDelegate *)indirect {
+    if ((self = [super init]) != nil) {
+        indirect_ = [indirect retain];
+    } return self;
+}
+
+- (void) setDelegate:(id)delegate {
+    delegate_ = delegate;
+}
+
++ (NSArray *) _attributeKeys {
+    return [NSArray arrayWithObjects:@"device", @"firewire", @"imei", @"mac", @"serial", nil];
+}
+
+- (NSArray *) attributeKeys {
+    return [[self class] _attributeKeys];
+}
+
++ (BOOL) isKeyExcludedFromWebScript:(const char *)name {
+    return ![[self _attributeKeys] containsObject:[NSString stringWithUTF8String:name]] && [super isKeyExcludedFromWebScript:name];
+}
+
+- (NSString *) device {
+    return [[UIDevice currentDevice] uniqueIdentifier];
+}
+
+#if 0 // XXX: implement!
+- (NSString *) mac {
+    if (![indirect_ promptForSensitive:@"Mac Address"])
+        return nil;
+}
+
+- (NSString *) serial {
+    if (![indirect_ promptForSensitive:@"Serial #"])
+        return nil;
+}
+
+- (NSString *) firewire {
+    if (![indirect_ promptForSensitive:@"Firewire GUID"])
+        return nil;
+}
+
+- (NSString *) imei {
+    if (![indirect_ promptForSensitive:@"IMEI"])
+        return nil;
+}
+#endif
+
++ (NSString *) webScriptNameForSelector:(SEL)selector {
+    if (selector == @selector(close))
+        return @"close";
+    else if (selector == @selector(getInstalledPackages))
+        return @"getInstalledPackages";
+    else if (selector == @selector(getPackageById:))
+        return @"getPackageById";
+    else if (selector == @selector(installPackages:))
+        return @"installPackages";
+    else if (selector == @selector(setAutoPopup:))
+        return @"setAutoPopup";
+    else if (selector == @selector(setButtonImage:withStyle:toFunction:))
+        return @"setButtonImage";
+    else if (selector == @selector(setButtonTitle:withStyle:toFunction:))
+        return @"setButtonTitle";
+    else if (selector == @selector(setFinishHook:))
+        return @"setFinishHook";
+    else if (selector == @selector(setPopupHook:))
+        return @"setPopupHook";
+    else if (selector == @selector(setSpecial:))
+        return @"setSpecial";
+    else if (selector == @selector(setToken:))
+        return @"setToken";
+    else if (selector == @selector(setViewportWidth:))
+        return @"setViewportWidth";
+    else if (selector == @selector(supports:))
+        return @"supports";
+    else if (selector == @selector(stringWithFormat:arguments:))
+        return @"format";
+    else if (selector == @selector(localizedStringForKey:value:table:))
+        return @"localize";
+    else if (selector == @selector(du:))
+        return @"du";
+    else if (selector == @selector(statfs:))
+        return @"statfs";
+    else
+        return nil;
+}
+
++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
+    return [self webScriptNameForSelector:selector] == nil;
+}
+
+- (BOOL) supports:(NSString *)feature {
+    return [feature isEqualToString:@"window.open"];
+}
+
+- (NSArray *) getInstalledPackages {
+    NSArray *packages([[Database sharedInstance] packages]);
+    NSMutableArray *installed([NSMutableArray arrayWithCapacity:[packages count]]);
+    for (Package *package in packages)
+        if ([package installed] != nil)
+            [installed addObject:package];
+    return installed;
+}
+
+- (Package *) getPackageById:(NSString *)id {
+    Package *package([[Database sharedInstance] packageWithName:id]);
+    [package parse];
+    return package;
+}
+
+- (NSArray *) statfs:(NSString *)path {
+    struct statfs stat;
+
+    if (path == nil || statfs([path UTF8String], &stat) == -1)
+        return nil;
+
+    return [NSArray arrayWithObjects:
+        [NSNumber numberWithUnsignedLong:stat.f_bsize],
+        [NSNumber numberWithUnsignedLong:stat.f_blocks],
+        [NSNumber numberWithUnsignedLong:stat.f_bfree],
+    nil];
+}
+
+- (NSNumber *) du:(NSString *)path {
+    NSNumber *value(nil);
+
+    int fds[2];
+    _assert(pipe(fds) != -1);
+
+    pid_t pid(ExecFork());
+    if (pid == 0) {
+        _assert(dup2(fds[1], 1) != -1);
+        _assert(close(fds[0]) != -1);
+        _assert(close(fds[1]) != -1);
+        /* XXX: this should probably not use du */
+        execl("/usr/libexec/cydia/du", "du", "-s", [path UTF8String], NULL);
+        exit(1);
+        _assert(false);
+    }
+
+    _assert(close(fds[1]) != -1);
+
+    if (FILE *du = fdopen(fds[0], "r")) {
+        char line[1024];
+        while (fgets(line, sizeof(line), du) != NULL) {
+            size_t length(strlen(line));
+            while (length != 0 && line[length - 1] == '\n')
+                line[--length] = '\0';
+            if (char *tab = strchr(line, '\t')) {
+                *tab = '\0';
+                value = [NSNumber numberWithUnsignedLong:strtoul(line, NULL, 0)];
+            }
+        }
+
+        fclose(du);
+    } else _assert(close(fds[0]));
+
+    int status;
+  wait:
+    if (waitpid(pid, &status, 0) == -1)
+        if (errno == EINTR)
+            goto wait;
+        else _assert(false);
+
+    return value;
+}
+
+- (void) close {
+    [indirect_ close];
+}
+
+- (void) installPackages:(NSArray *)packages {
+    [delegate_ performSelectorOnMainThread:@selector(installPackages:) withObject:packages waitUntilDone:NO];
+}
+
+- (void) setAutoPopup:(BOOL)popup {
+    [indirect_ setAutoPopup:popup];
+}
+
+- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
+    [indirect_ setButtonImage:button withStyle:style toFunction:function];
+}
+
+- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function {
+    [indirect_ setButtonTitle:button withStyle:style toFunction:function];
+}
+
+- (void) setSpecial:(id)function {
+    [indirect_ setSpecial:function];
+}
+
+- (void) setToken:(NSString *)token {
+    if (Token_ != nil)
+        [Token_ release];
+    Token_ = [token retain];
+
+    [Metadata_ setObject:Token_ forKey:@"Token"];
+    Changed_ = true;
+}
+
+- (void) setFinishHook:(id)function {
+    [indirect_ setFinishHook:function];
+}
+
+- (void) setPopupHook:(id)function {
+    [indirect_ setPopupHook:function];
+}
+
+- (void) setViewportWidth:(float)width {
+    [indirect_ setViewportWidth:width];
+}
+
+- (NSString *) stringWithFormat:(NSString *)format arguments:(WebScriptObject *)arguments {
+    //NSLog(@"SWF:\"%@\" A:%@", format, [arguments description]);
+    unsigned count([arguments count]);
+    id values[count];
+    for (unsigned i(0); i != count; ++i)
+        values[i] = [arguments objectAtIndex:i];
+    return [[[NSString alloc] initWithFormat:format arguments:*(reinterpret_cast<va_list *>(&values))] autorelease];
+}
+
+- (NSString *) localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)table {
+    if (reinterpret_cast<id>(value) == [WebUndefined undefined])
+        value = nil;
+    if (reinterpret_cast<id>(table) == [WebUndefined undefined])
+        table = nil;
+    return [[NSBundle mainBundle] localizedStringForKey:key value:value table:table];
+}
+
+@end
+/* }}} */
+
+/* Cydia Browser Controller {{{ */
+@interface CYBrowserController : BrowserController {
+    CydiaObject *cydia_;
+}
+
+@end
+
+@implementation CYBrowserController
+
+- (void) dealloc {
+    [cydia_ release];
+    [super dealloc];
+}
+
+- (void) setHeaders:(NSDictionary *)headers forHost:(NSString *)host {
+}
+
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:sender didClearWindowObject:window forFrame:frame];
+
+    WebDataSource *source([frame dataSource]);
+    NSURLResponse *response([source response]);
+    NSURL *url([response URL]);
+    NSString *scheme([url scheme]);
+
+    NSHTTPURLResponse *http;
+    if (scheme != nil && ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]))
+        http = (NSHTTPURLResponse *) response;
+    else
+        http = nil;
+
+    NSDictionary *headers([http allHeaderFields]);
+    NSString *host([url host]);
+    [self setHeaders:headers forHost:host];
+
+    if (
+        [host isEqualToString:@"cydia.saurik.com"] ||
+        [host hasSuffix:@".cydia.saurik.com"] ||
+        [scheme isEqualToString:@"file"]
+    )
+        [window setValue:cydia_ forKey:@"cydia"];
+}
+
+- (void) _setMoreHeaders:(NSMutableURLRequest *)request {
+    if (System_ != NULL)
+        [request setValue:System_ forHTTPHeaderField:@"X-System"];
+    if (Machine_ != NULL)
+        [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
+    if (Token_ != nil)
+        [request setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"];
+    if (Role_ != nil)
+        [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
+}
+
+- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source {
+    NSMutableURLRequest *copy = [request mutableCopy];
+    [self _setMoreHeaders:copy];
+    return copy;
+}
+
+- (void) setDelegate:(id)delegate {
+    [super setDelegate:delegate];
+    [cydia_ setDelegate:delegate];
+}
+
+- (id) init {
+    if ((self = [super initWithWidth:0 ofClass:[CYBrowserController class]]) != nil) {
+        cydia_ = [[CydiaObject alloc] initWithDelegate:indirect_];
+
+        WebView *webview([document_ webView]);
+
+        Package *package([[Database sharedInstance] packageWithName:@"cydia"]);
+
+        NSString *application = package == nil ? @"Cydia" : [NSString
+            stringWithFormat:@"Cydia/%@",
+            [package installed]
+        ];
+
+        if (Safari_ != nil)
+            application = [NSString stringWithFormat:@"Safari/%@ %@", Safari_, application];
+        if (Build_ != nil)
+            application = [NSString stringWithFormat:@"Mobile/%@ %@", Build_, application];
+        if (Product_ != nil)
+            application = [NSString stringWithFormat:@"Version/%@ %@", Product_, application];
+
+        [webview setApplicationNameForUserAgent:application];
+    } return self;
+}
+
+@end
+/* }}} */
+
+/* Confirmation {{{ */
+@protocol ConfirmationControllerDelegate
+- (void) cancelAndClear:(bool)clear;
+- (void) confirmWithNavigationController:(UINavigationController *)navigation;
+- (void) queue;
+@end
+
+@interface ConfirmationController : CYBrowserController {
+    _transient Database *database_;
+    UIAlertView *essential_;
+    NSArray *changes_;
+    NSArray *issues_;
+    NSArray *sizes_;
+    BOOL substrate_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+
+@end
+
+@implementation ConfirmationController
+
+- (void) dealloc {
+    [changes_ release];
+    if (issues_ != nil)
+        [issues_ release];
+    [sizes_ release];
+    if (essential_ != nil)
+        [essential_ release];
+    [super dealloc];
+}
+
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
+
+    if ([context isEqualToString:@"remove"]) {
+        if (button == [alert cancelButtonIndex]) {
+            [self dismissModalViewControllerAnimated:YES];
+        } else if (button == [alert firstOtherButtonIndex]) {
+            if (substrate_)
+                Finish_ = 2;
+            [delegate_ confirmWithNavigationController:[self navigationController]];
+        }
+
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    } else if ([context isEqualToString:@"unable"]) {
+        [self dismissModalViewControllerAnimated:YES];
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    } else {
+        [super alertView:alert clickedButtonAtIndex:button];
+    }
+}
+
+- (id) invokeDefaultMethodWithArguments:(NSArray *)args {
+    [self dismissModalViewControllerAnimated:YES];
+    [delegate_ cancelAndClear:NO];
+
+    return nil;
+}
+
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:sender didClearWindowObject:window forFrame:frame];
+    [window setValue:changes_ forKey:@"changes"];
+    [window setValue:issues_ forKey:@"issues"];
+    [window setValue:sizes_ forKey:@"sizes"];
+    [window setValue:self forKey:@"queue"];
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+
+        [[self navigationItem] setTitle:UCLocalize("CONFIRM")];
+
+        NSMutableArray *installing = [NSMutableArray arrayWithCapacity:16];
+        NSMutableArray *reinstalling = [NSMutableArray arrayWithCapacity:16];
+        NSMutableArray *upgrading = [NSMutableArray arrayWithCapacity:16];
+        NSMutableArray *downgrading = [NSMutableArray arrayWithCapacity:16];
+        NSMutableArray *removing = [NSMutableArray arrayWithCapacity:16];
+
+        bool remove(false);
+
+        pkgDepCache::Policy *policy([database_ policy]);
+
+        pkgCacheFile &cache([database_ cache]);
+        NSArray *packages = [database_ packages];
+        for (Package *package in packages) {
+            pkgCache::PkgIterator iterator = [package iterator];
+            pkgDepCache::StateCache &state(cache[iterator]);
+
+            NSString *name([package name]);
+
+            if (state.NewInstall())
+                [installing addObject:name];
+            else if (!state.Delete() && (state.iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
+                [reinstalling addObject:name];
+            else if (state.Upgrade())
+                [upgrading addObject:name];
+            else if (state.Downgrade())
+                [downgrading addObject:name];
+            else if (state.Delete()) {
+                if ([package essential])
+                    remove = true;
+                [removing addObject:name];
+            } else continue;
+
+            substrate_ |= DepSubstrate(policy->GetCandidateVer(iterator));
+            substrate_ |= DepSubstrate(iterator.CurrentVer());
+        }
+
+        if (!remove)
+            essential_ = nil;
+        else if (Advanced_) {
+            NSString *parenthetical(UCLocalize("PARENTHETICAL"));
+
+            essential_ = [[UIAlertView alloc]
+                initWithTitle:UCLocalize("REMOVING_ESSENTIALS")
+                message:UCLocalize("REMOVING_ESSENTIALS_EX")
+                delegate:self
+                cancelButtonTitle:[NSString stringWithFormat:parenthetical, UCLocalize("CANCEL_OPERATION"), UCLocalize("SAFE")]
+                otherButtonTitles:[NSString stringWithFormat:parenthetical, UCLocalize("FORCE_REMOVAL"), UCLocalize("UNSAFE")], nil
+            ];
+
+            [essential_ setContext:@"remove"];
+        } else {
+            essential_ = [[UIAlertView alloc]
+                initWithTitle:UCLocalize("UNABLE_TO_COMPLY")
+                message:UCLocalize("UNABLE_TO_COMPLY_EX")
+                delegate:self
+                cancelButtonTitle:UCLocalize("OKAY")
+                otherButtonTitles:nil
+            ];
+
+            [essential_ setContext:@"unable"];
+        }
+
+        changes_ = [[NSArray alloc] initWithObjects:
+            installing,
+            reinstalling,
+            upgrading,
+            downgrading,
+            removing,
+        nil];
+
+        issues_ = [database_ issues];
+        if (issues_ != nil)
+            issues_ = [issues_ retain];
+
+        sizes_ = [[NSArray alloc] initWithObjects:
+            SizeString([database_ fetcher].FetchNeeded()),
+            SizeString([database_ fetcher].PartialPresent()),
+        nil];
+
+        [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"confirm" ofType:@"html"]]];
+
+        UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("CANCEL")
+            // OLD: [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("CANCEL"), UCLocalize("QUEUE")]
+            style:UIBarButtonItemStylePlain
+            target:self
+            action:@selector(cancelButtonClicked)
+        ];
+        [[self navigationItem] setLeftBarButtonItem:leftItem];
+        [leftItem release];
+    } return self;
+}
+
+- (void) applyRightButton {
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:UCLocalize("CONFIRM")
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(confirmButtonClicked)
+    ];
+#if !AlwaysReload && !IgnoreInstall
+    if (issues_ == nil && ![self isLoading]) [[self navigationItem] setRightBarButtonItem:rightItem];
+    else [super applyRightButton];
+#else
+    [[self navigationItem] setRightBarButtonItem:nil];
+#endif
+    [rightItem release];
+}
+
+- (void) cancelButtonClicked {
+    [self dismissModalViewControllerAnimated:YES];
+    [delegate_ cancelAndClear:YES];
+}
+
+#if !AlwaysReload
+- (void) confirmButtonClicked {
+#if IgnoreInstall
+    return;
+#endif
+    if (essential_ != nil)
+        [essential_ show];
+    else {
+        if (substrate_)
+            Finish_ = 2;
+        [delegate_ confirmWithNavigationController:[self navigationController]];
+    }
+}
+#endif
+
+@end
+/* }}} */
+
+/* Progress Data {{{ */
+@interface ProgressData : NSObject {
+    SEL selector_;
+    id target_;
+    id object_;
+}
+
+- (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object;
+
+- (SEL) selector;
+- (id) target;
+- (id) object;
+@end
+
+@implementation ProgressData
+
+- (ProgressData *) initWithSelector:(SEL)selector target:(id)target object:(id)object {
+    if ((self = [super init]) != nil) {
+        selector_ = selector;
+        target_ = target;
+        object_ = object;
+    } return self;
+}
+
+- (SEL) selector {
+    return selector_;
+}
+
+- (id) target {
+    return target_;
+}
+
+- (id) object {
+    return object_;
+}
+
+@end
+/* }}} */
+/* Progress Controller {{{ */
+@interface ProgressController : CYViewController <
+    ConfigurationDelegate,
+    ProgressDelegate
+> {
+    _transient Database *database_;
+    UIProgressBar *progress_;
+    UITextView *output_;
+    UITextLabel *status_;
+    UIPushButton *close_;
+    BOOL running_;
+    SHA1SumValue springlist_;
+    SHA1SumValue notifyconf_;
+    NSString *title_;
+}
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
+
+- (void) _retachThread;
+- (void) _detachNewThreadData:(ProgressData *)data;
+- (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title;
+
+- (BOOL) isRunning;
+
+@end
+
+@protocol ProgressControllerDelegate
+- (void) progressControllerIsComplete:(ProgressController *)sender;
+@end
+
+@implementation ProgressController
+
+- (void) dealloc {
+    [database_ setDelegate:nil];
+    [progress_ release];
+    [output_ release];
+    [status_ release];
+    [close_ release];
+    if (title_ != nil)
+        [title_ release];
+    [super dealloc];
+}
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+        [database_ setDelegate:self];
+        delegate_ = delegate;
+
+        [[self view] setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f]];
+
+        progress_ = [[UIProgressBar alloc] init];
+        [progress_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+        [progress_ setStyle:0];
+
+        status_ = [[UITextLabel alloc] init];
+        [status_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+        [status_ setColor:[UIColor whiteColor]];
+        [status_ setBackgroundColor:[UIColor clearColor]];
+        [status_ setCentersHorizontally:YES];
+        //[status_ setFont:font];
+
+        output_ = [[UITextView alloc] init];
+
+        [output_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        //[output_ setTextFont:@"Courier New"];
+        [output_ setFont:[[output_ font] fontWithSize:12]];
+        [output_ setTextColor:[UIColor whiteColor]];
+        [output_ setBackgroundColor:[UIColor clearColor]];
+        [output_ setMarginTop:0];
+        [output_ setAllowsRubberBanding:YES];
+        [output_ setEditable:NO];
+        [[self view] addSubview:output_];
+
+        close_ = [[UIPushButton alloc] init];
+        [close_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin)];
+        [close_ setAutosizesToFit:NO];
+        [close_ setDrawsShadow:YES];
+        [close_ setStretchBackground:YES];
+        [close_ setEnabled:YES];
+        [close_ setTitleFont:[UIFont boldSystemFontOfSize:22]];
+        [close_ addTarget:self action:@selector(closeButtonPushed) forEvents:UIControlEventTouchUpInside];
+        [close_ setBackground:[UIImage applicationImageNamed:@"green-up.png"] forState:0];
+        [close_ setBackground:[UIImage applicationImageNamed:@"green-dn.png"] forState:1];
+    } return self;
+}
+
+- (void) positionViews {
+    CGRect bounds = [[self view] bounds];
+    CGSize prgsize = [UIProgressBar defaultSize];
+
+    CGRect prgrect = {{
+        (bounds.size.width - prgsize.width) / 2,
+        bounds.size.height - prgsize.height - 64
+    }, prgsize};
+
+    float closewidth = bounds.size.width - 20;
+    if (closewidth > 300) closewidth = 300;
+
+    [progress_ setFrame:prgrect];
+    [status_ setFrame:CGRectMake(
+        10,
+        bounds.size.height - prgsize.height - 94,
+        bounds.size.width - 20,
+        24
+    )];
+    [output_ setFrame:CGRectMake(
+        10,
+        20,
+        bounds.size.width - 20,
+        bounds.size.height - 106
+    )];
+    [close_ setFrame:CGRectMake(
+        (bounds.size.width - closewidth) / 2,
+        bounds.size.height - prgsize.height - 94,
+        closewidth,
+        32 + prgsize.height
+    )];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    [[self navigationItem] setHidesBackButton:YES];
+    [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlack];
+
+    [self positionViews];
+}
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+    [self positionViews];
+}
+
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
+
+    if ([context isEqualToString:@"conffile"]) {
+        FILE *input = [database_ input];
+        if (button == [alert cancelButtonIndex]) fprintf(input, "N\n");
+        else if (button == [alert firstOtherButtonIndex]) fprintf(input, "Y\n");
+        fflush(input);
+    }
+}
+
+- (void) closeButtonPushed {
+    running_ = NO;
+
+    UpdateExternalStatus(0);
+
+    switch (Finish_) {
+        case 0:
+            [self dismissModalViewControllerAnimated:YES];
+        break;
+
+        case 1:
+            [delegate_ terminateWithSuccess];
+            /*if ([delegate_ respondsToSelector:@selector(suspendWithAnimation:)])
+                [delegate_ suspendWithAnimation:YES];
+            else
+                [delegate_ suspend];*/
+        break;
+
+        case 2:
+            system("launchctl stop com.apple.SpringBoard");
+        break;
+
+        case 3:
+            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
+        break;
+
+        case 4:
+            system("reboot");
+        break;
+    }
+}
+
+- (void) _retachThread {
+    [[self navigationItem] setTitle:UCLocalize("COMPLETE")];
+
+    [[self view] addSubview:close_];
+    [progress_ removeFromSuperview];
+    [status_ removeFromSuperview];
+
+    [database_ popErrorWithTitle:title_];
+    [delegate_ progressControllerIsComplete:self];
+
+    if (Finish_ < 4) {
+        FileFd file;
+        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            if (!(notifyconf_ == sha1.Result()))
+                Finish_ = 4;
+        }
+    }
+
+    if (Finish_ < 3) {
+        FileFd file;
+        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            if (!(springlist_ == sha1.Result()))
+                Finish_ = 3;
+        }
+    }
+
+    switch (Finish_) {
+        case 0: [close_ setTitle:UCLocalize("RETURN_TO_CYDIA")]; break; /* XXX: Maybe UCLocalize("DONE")? */
+        case 1: [close_ setTitle:UCLocalize("CLOSE_CYDIA")]; break;
+        case 2: [close_ setTitle:UCLocalize("RESTART_SPRINGBOARD")]; break;
+        case 3: [close_ setTitle:UCLocalize("RELOAD_SPRINGBOARD")]; break;
+        case 4: [close_ setTitle:UCLocalize("REBOOT_DEVICE")]; break;
+    }
+
+    system("su -c /usr/bin/uicache mobile");
+
+    UpdateExternalStatus(Finish_ == 0 ? 2 : 0);
+
+    [delegate_ setStatusBarShowsProgress:NO];
+}
+
+- (void) _detachNewThreadData:(ProgressData *)data { _pooled
+    [[data target] performSelector:[data selector] withObject:[data object]];
+    [data release];
+
+    [self performSelectorOnMainThread:@selector(_retachThread) withObject:nil waitUntilDone:YES];
+}
+
+- (void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)object title:(NSString *)title {
+    UpdateExternalStatus(1);
+
+    if (title_ != nil)
+        [title_ release];
+    if (title == nil)
+        title_ = nil;
+    else
+        title_ = [title retain];
+
+    [[self navigationItem] setTitle:title_];
+
+    [status_ setText:nil];
+    [output_ setText:@""];
+    [progress_ setProgress:0];
+
+    [close_ removeFromSuperview];
+    [[self view] addSubview:progress_];
+    [[self view] addSubview:status_];
+
+    [delegate_ setStatusBarShowsProgress:YES];
+    running_ = YES;
+
+    {
+        FileFd file;
+        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            notifyconf_ = sha1.Result();
+        }
+    }
+
+    {
+        FileFd file;
+        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            springlist_ = sha1.Result();
+        }
+    }
+
+    [NSThread
+        detachNewThreadSelector:@selector(_detachNewThreadData:)
+        toTarget:self
+        withObject:[[ProgressData alloc]
+            initWithSelector:selector
+            target:target
+            object:object
+        ]
+    ];
+}
+
+- (void) repairWithSelector:(SEL)selector {
+    [self
+        detachNewThreadSelector:selector
+        toTarget:database_
+        withObject:nil
+        title:UCLocalize("REPAIRING")
+    ];
+}
+
+- (void) setConfigurationData:(NSString *)data {
+    [self
+        performSelectorOnMainThread:@selector(_setConfigurationData:)
+        withObject:data
+        waitUntilDone:YES
+    ];
+}
+
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
+    CYActionSheet *sheet([[[CYActionSheet alloc]
+        initWithTitle:title
+        buttons:[NSArray arrayWithObjects:UCLocalize("OKAY"), nil]
+        defaultButtonIndex:0
+    ] autorelease]);
+
+    [sheet setMessage:error];
+    [sheet yieldToPopupAlertAnimated:YES];
+    [sheet dismiss];
+}
+
+- (void) setProgressTitle:(NSString *)title {
+    [self
+        performSelectorOnMainThread:@selector(_setProgressTitle:)
+        withObject:title
+        waitUntilDone:YES
+    ];
+}
+
+- (void) setProgressPercent:(float)percent {
+    [self
+        performSelectorOnMainThread:@selector(_setProgressPercent:)
+        withObject:[NSNumber numberWithFloat:percent]
+        waitUntilDone:YES
+    ];
+}
+
+- (void) startProgress {
+}
+
+- (void) addProgressOutput:(NSString *)output {
+    [self
+        performSelectorOnMainThread:@selector(_addProgressOutput:)
+        withObject:output
+        waitUntilDone:YES
+    ];
+}
+
+- (bool) isCancelling:(size_t)received {
+    return false;
+}
+
+- (void) _setConfigurationData:(NSString *)data {
+    static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$");
+
+    if (!conffile_r(data)) {
+        lprintf("E:invalid conffile\n");
+        return;
+    }
+
+    NSString *ofile = conffile_r[1];
+    //NSString *nfile = conffile_r[2];
+
+    UIAlertView *alert = [[[UIAlertView alloc]
+        initWithTitle:UCLocalize("CONFIGURATION_UPGRADE")
+        message:[NSString stringWithFormat:@"%@\n\n%@", UCLocalize("CONFIGURATION_UPGRADE_EX"), ofile]
+        delegate:self
+        cancelButtonTitle:UCLocalize("KEEP_OLD_COPY")
+        otherButtonTitles:UCLocalize("ACCEPT_NEW_COPY"),
+        // XXX: UCLocalize("SEE_WHAT_CHANGED"),
+        nil
+    ] autorelease];
+
+    [alert setContext:@"conffile"];
+    [alert show];
+}
+
+- (void) _setProgressTitle:(NSString *)title {
+    NSMutableArray *words([[title componentsSeparatedByString:@" "] mutableCopy]);
+    for (size_t i(0), e([words count]); i != e; ++i) {
+        NSString *word([words objectAtIndex:i]);
+        if (Package *package = [database_ packageWithName:word])
+            [words replaceObjectAtIndex:i withObject:[package name]];
+    }
+
+    [status_ setText:[words componentsJoinedByString:@" "]];
+}
+
+- (void) _setProgressPercent:(NSNumber *)percent {
+    [progress_ setProgress:[percent floatValue]];
+}
+
+- (void) _addProgressOutput:(NSString *)output {
+    [output_ setText:[NSString stringWithFormat:@"%@\n%@", [output_ text], output]];
+    CGSize size = [output_ contentSize];
+    CGRect rect = {{0, size.height}, {size.width, 0}};
+    [output_ scrollRectToVisible:rect animated:YES];
+}
+
+- (BOOL) isRunning {
+    return running_;
+}
+
+@end
+/* }}} */
+
+/* Cell Content View {{{ */
+@protocol ContentDelegate
+- (void) drawContentRect:(CGRect)rect;
+@end
+
+@interface ContentView : UIView {
+    _transient id<ContentDelegate> delegate_;
+}
+
+@end
+
+@implementation ContentView
+- (id) initWithFrame:(CGRect)frame {
+    if ((self = [super initWithFrame:frame]) != nil) {
+        /* Fix landscape stretching. */
+        [self setNeedsDisplayOnBoundsChange:YES];
+    } return self;
+}
+
+- (void) setDelegate:(id<ContentDelegate>)delegate {
+    delegate_ = delegate;
+}
+
+- (void) drawRect:(CGRect)rect {
+    [super drawRect:rect];
+    [delegate_ drawContentRect:rect];
+}
+@end
+/* }}} */
+/* Package Cell {{{ */
+@interface PackageCell : UITableViewCell <
+    ContentDelegate
+> {
+    UIImage *icon_;
+    NSString *name_;
+    NSString *description_;
+    bool commercial_;
+    NSString *source_;
+    UIImage *badge_;
+    Package *package_;
+    UIColor *color_;
+    ContentView *content_;
+    BOOL faded_;
+    float fade_;
+    UIImage *placard_;
+}
+
+- (PackageCell *) init;
+- (void) setPackage:(Package *)package;
+
++ (int) heightForPackage:(Package *)package;
+- (void) drawContentRect:(CGRect)rect;
+
+@end
+
+@implementation PackageCell
+
+- (void) clearPackage {
+    if (icon_ != nil) {
+        [icon_ release];
+        icon_ = nil;
+    }
+
+    if (name_ != nil) {
+        [name_ release];
+        name_ = nil;
+    }
+
+    if (description_ != nil) {
+        [description_ release];
+        description_ = nil;
+    }
+
+    if (source_ != nil) {
+        [source_ release];
+        source_ = nil;
+    }
+
+    if (badge_ != nil) {
+        [badge_ release];
+        badge_ = nil;
+    }
+
+    if (placard_ != nil) {
+        [placard_ release];
+        placard_ = nil;
+    }
+
+    [package_ release];
+    package_ = nil;
+}
+
+- (void) dealloc {
+    [self clearPackage];
+    [content_ release];
+    [color_ release];
+    [super dealloc];
+}
+
+- (float) fade {
+    return faded_ ? [self selectionPercent] : fade_;
+}
+
+- (PackageCell *) init {
+    CGRect frame(CGRectMake(0, 0, 320, 74));
+    if ((self = [super initWithFrame:frame reuseIdentifier:@"Package"]) != nil) {
+        UIView *content([self contentView]);
+        CGRect bounds([content bounds]);
+
+        content_ = [[ContentView alloc] initWithFrame:bounds];
+        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content addSubview:content_];
+
+        [content_ setDelegate:self];
+        [content_ setOpaque:YES];
+        if ([self respondsToSelector:@selector(selectionPercent)])
+            faded_ = YES;
+    } return self;
+}
+
+- (void) _setBackgroundColor {
+    UIColor *color;
+    if (NSString *mode = [package_ mode]) {
+        bool remove([mode isEqualToString:@"REMOVE"] || [mode isEqualToString:@"PURGE"]);
+        color = remove ? RemovingColor_ : InstallingColor_;
+    } else
+        color = [UIColor whiteColor];
+
+    [content_ setBackgroundColor:color];
+    [self setNeedsDisplay];
+}
+
+- (void) setPackage:(Package *)package {
+    [self clearPackage];
+    [package parse];
+
+    Source *source = [package source];
+
+    icon_ = [[package icon] retain];
+    name_ = [[package name] retain];
+
+    if (IsWildcat_)
+        description_ = [package longDescription];
+    if (description_ == nil)
+        description_ = [package shortDescription];
+    if (description_ != nil)
+        description_ = [description_ retain];
+
+    commercial_ = [package isCommercial];
+
+    package_ = [package retain];
+
+    NSString *label = nil;
+    bool trusted = false;
+
+    if (source != nil) {
+        label = [source label];
+        trusted = [source trusted];
+    } else if ([[package id] isEqualToString:@"firmware"])
+        label = UCLocalize("APPLE");
+    else
+        label = [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("UNKNOWN"), UCLocalize("LOCAL")];
+
+    NSString *from(label);
+
+    NSString *section = [package simpleSection];
+    if (section != nil && ![section isEqualToString:label]) {
+        section = [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"];
+        from = [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), from, section];
+    }
+
+    from = [NSString stringWithFormat:UCLocalize("FROM"), from];
+    source_ = [from retain];
+
+    if (NSString *purpose = [package primaryPurpose])
+        if ((badge_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Purposes/%@.png", App_, purpose]]) != nil)
+            badge_ = [badge_ retain];
+
+    if ([package installed] != nil)
+        if ((placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/installed.png", App_]]) != nil)
+            placard_ = [placard_ retain];
+
+    [self _setBackgroundColor];
+    [content_ setNeedsDisplay];
+}
+
+- (void) drawContentRect:(CGRect)rect {
+    bool selected([self isSelected]);
+    float width([self bounds].size.width);
+
+#if 0
+    CGContextRef context(UIGraphicsGetCurrentContext());
+    [([[self selectedBackgroundView] superview] != nil ? [UIColor clearColor] : [self backgroundColor]) set];
+    CGContextFillRect(context, rect);
+#endif
+
+    if (icon_ != nil) {
+        CGRect rect;
+        rect.size = [icon_ size];
+
+        rect.size.width /= 2;
+        rect.size.height /= 2;
+
+        rect.origin.x = 25 - rect.size.width / 2;
+        rect.origin.y = 25 - rect.size.height / 2;
+
+        [icon_ drawInRect:rect];
+    }
+
+    if (badge_ != nil) {
+        CGSize size = [badge_ size];
+
+        [badge_ drawAtPoint:CGPointMake(
+            36 - size.width / 2,
+            36 - size.height / 2
+        )];
+    }
+
+    if (selected)
+        UISetColor(White_);
+
+    if (!selected)
+        UISetColor(commercial_ ? Purple_ : Black_);
+    [name_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - (placard_ == nil ? 80 : 106)) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation];
+    [source_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation];
+
+    if (!selected)
+        UISetColor(commercial_ ? Purplish_ : Gray_);
+    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 46) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation];
+
+    if (placard_ != nil)
+        [placard_ drawAtPoint:CGPointMake(width - 52, 9)];
+}
+
+- (void) setSelected:(BOOL)selected animated:(BOOL)fade {
+    //[self _setBackgroundColor];
+    [super setSelected:selected animated:fade];
+    [content_ setNeedsDisplay];
+}
+
++ (int) heightForPackage:(Package *)package {
+    return 73;
+}
+
+@end
+/* }}} */
+/* Section Cell {{{ */
+@interface SectionCell : UITableViewCell <
+    ContentDelegate
+> {
+    NSString *basic_;
+    NSString *section_;
+    NSString *name_;
+    NSString *count_;
+    UIImage *icon_;
+    ContentView *content_;
+    id switch_;
+    BOOL editing_;
+}
+
+- (void) setSection:(Section *)section editing:(BOOL)editing;
+
+@end
+
+@implementation SectionCell
+
+- (void) clearSection {
+    if (basic_ != nil) {
+        [basic_ release];
+        basic_ = nil;
+    }
+
+    if (section_ != nil) {
+        [section_ release];
+        section_ = nil;
+    }
+
+    if (name_ != nil) {
+        [name_ release];
+        name_ = nil;
+    }
+
+    if (count_ != nil) {
+        [count_ release];
+        count_ = nil;
+    }
+}
+
+- (void) dealloc {
+    [self clearSection];
+    [icon_ release];
+    [switch_ release];
+    [content_ release];
+
+    [super dealloc];
+}
+
+- (id) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
+    if ((self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) != nil) {
+        icon_ = [[UIImage applicationImageNamed:@"folder.png"] retain];
+        switch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(218, 9, 60, 25)];
+        [switch_ addTarget:self action:@selector(onSwitch:) forEvents:UIControlEventValueChanged];
+
+        UIView *content([self contentView]);
+        CGRect bounds([content bounds]);
+
+        content_ = [[ContentView alloc] initWithFrame:bounds];
+        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content addSubview:content_];
+        [content_ setBackgroundColor:[UIColor whiteColor]];
+
+        [content_ setDelegate:self];
+    } return self;
+}
+
+- (void) onSwitch:(id)sender {
+    NSMutableDictionary *metadata = [Sections_ objectForKey:basic_];
+    if (metadata == nil) {
+        metadata = [NSMutableDictionary dictionaryWithCapacity:2];
+        [Sections_ setObject:metadata forKey:basic_];
+    }
+
+    Changed_ = true;
+    [metadata setObject:[NSNumber numberWithBool:([switch_ isOn] == NO)] forKey:@"Hidden"];
+}
+
+- (void) setSection:(Section *)section editing:(BOOL)editing {
+    if (editing != editing_) {
+        if (editing_)
+            [switch_ removeFromSuperview];
+        else
+            [self addSubview:switch_];
+        editing_ = editing;
+    }
+
+    [self clearSection];
+
+    if (section == nil) {
+        name_ = [UCLocalize("ALL_PACKAGES") retain];
+        count_ = nil;
+    } else {
+        basic_ = [section name];
+        if (basic_ != nil)
+            basic_ = [basic_ retain];
+
+        section_ = [section localized];
+        if (section_ != nil)
+            section_ = [section_ retain];
+
+        name_  = [(section_ == nil || [section_ length] == 0 ? UCLocalize("NO_SECTION") : section_) retain];
+        count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
+
+        if (editing_)
+            [switch_ setOn:(isSectionVisible(basic_) ? 1 : 0) animated:NO];
+    }
+
+    [self setAccessoryType:editing ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator];
+    [content_ setNeedsDisplay];
+}
+
+- (void) setFrame:(CGRect)frame {
+    [super setFrame:frame];
+
+    CGRect rect([switch_ frame]);
+    [switch_ setFrame:CGRectMake(frame.size.width - 102, 9, rect.size.width, rect.size.height)];
+}
+
+- (void) drawContentRect:(CGRect)rect {
+    BOOL selected = [self isSelected];
+
+    [icon_ drawInRect:CGRectMake(8, 7, 32, 32)];
+
+    if (selected)
+        UISetColor(White_);
+
+    if (!selected)
+        UISetColor(Black_);
+
+    float width(rect.size.width);
+    if (editing_)
+        width -= 87;
+
+    [name_ drawAtPoint:CGPointMake(48, 9) forWidth:(width - 70) withFont:Font22Bold_ lineBreakMode:UILineBreakModeTailTruncation];
+
+    CGSize size = [count_ sizeWithFont:Font14_];
+
+    UISetColor(White_);
+    if (count_ != nil)
+        [count_ drawAtPoint:CGPointMake(13 + (29 - size.width) / 2, 16) withFont:Font12Bold_];
+}
+
+@end
+/* }}} */
+
+/* File Table {{{ */
+@interface FileTable : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    Package *package_;
+    NSString *name_;
+    NSMutableArray *files_;
+    UITableView *list_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+- (void) setPackage:(Package *)package;
+
+@end
+
+@implementation FileTable
+
+- (void) dealloc {
+    if (package_ != nil)
+        [package_ release];
+    if (name_ != nil)
+        [name_ release];
+    [files_ release];
+    [list_ release];
+    [super dealloc];
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return files_ == nil ? 0 : [files_ count];
+}
+
+/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 24.0f;
+}*/
+
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    static NSString *reuseIdentifier = @"Cell";
+
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
+    if (cell == nil) {
+        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
+        [cell setFont:[UIFont systemFontOfSize:16]];
+    }
+    [cell setText:[files_ objectAtIndex:indexPath.row]];
+    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
+
+    return cell;
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+
+        [[self navigationItem] setTitle:UCLocalize("INSTALLED_FILES")];
+
+        files_ = [[NSMutableArray arrayWithCapacity:32] retain];
+
+        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [list_ setRowHeight:24.0f];
+        [[self view] addSubview:list_];
+
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+    } return self;
+}
+
+- (void) setPackage:(Package *)package {
+    if (package_ != nil) {
+        [package_ autorelease];
+        package_ = nil;
+    }
+
+    if (name_ != nil) {
+        [name_ release];
+        name_ = nil;
+    }
+
+    [files_ removeAllObjects];
+
+    if (package != nil) {
+        package_ = [package retain];
+        name_ = [[package id] retain];
+
+        if (NSArray *files = [package files])
+            [files_ addObjectsFromArray:files];
+
+        if ([files_ count] != 0) {
+            if ([[files_ objectAtIndex:0] isEqualToString:@"/."])
+                [files_ removeObjectAtIndex:0];
+            [files_ sortUsingSelector:@selector(compareByPath:)];
+
+            NSMutableArray *stack = [NSMutableArray arrayWithCapacity:8];
+            [stack addObject:@"/"];
+
+            for (int i(0), e([files_ count]); i != e; ++i) {
+                NSString *file = [files_ objectAtIndex:i];
+                while (![file hasPrefix:[stack lastObject]])
+                    [stack removeLastObject];
+                NSString *directory = [stack lastObject];
+                [stack addObject:[file stringByAppendingString:@"/"]];
+                [files_ replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%*s%@",
+                    ([stack count] - 2) * 3, "",
+                    [file substringFromIndex:[directory length]]
+                ]];
+            }
+        }
+    }
+
+    [list_ reloadData];
+}
+
+- (void) reloadData {
+    [self setPackage:[database_ packageWithName:name_]];
+}
+
+@end
+/* }}} */
+/* Package Controller {{{ */
+@interface PackageController : CYBrowserController <
+    UIActionSheetDelegate
+> {
+    _transient Database *database_;
+    Package *package_;
+    NSString *name_;
+    bool commercial_;
+    NSMutableArray *buttons_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+- (void) setPackage:(Package *)package;
+
+@end
+
+@implementation PackageController
+
+- (void) dealloc {
+    if (package_ != nil)
+        [package_ release];
+    if (name_ != nil)
+        [name_ release];
+    [buttons_ release];
+    [super dealloc];
+}
+
+- (void) release {
+    if ([self retainCount] == 1)
+        [delegate_ setPackageController:self];
+    [super release];
+}
+
+/* XXX: this is not safe at all... localization of /fail/ */
+- (void) _clickButtonWithName:(NSString *)name {
+    if ([name isEqualToString:UCLocalize("CLEAR")])
+        [delegate_ clearPackage:package_];
+    else if ([name isEqualToString:UCLocalize("INSTALL")])
+        [delegate_ installPackage:package_];
+    else if ([name isEqualToString:UCLocalize("REINSTALL")])
+        [delegate_ installPackage:package_];
+    else if ([name isEqualToString:UCLocalize("REMOVE")])
+        [delegate_ removePackage:package_];
+    else if ([name isEqualToString:UCLocalize("UPGRADE")])
+        [delegate_ installPackage:package_];
+    else _assert(false);
+}
+
+- (void) actionSheet:(UIActionSheet *)sheet clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"modify"]) {
+        if (button != [sheet cancelButtonIndex]) {
+            NSString *buttonName = [buttons_ objectAtIndex:button];
+            [self _clickButtonWithName:buttonName];
+        }
+
+        [sheet dismissWithClickedButtonIndex:-1 animated:YES];
+    }
+}
+
+- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
+    return [super webView:sender didFinishLoadForFrame:frame];
+}
+
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    [super webView:sender didClearWindowObject:window forFrame:frame];
+    [window setValue:package_ forKey:@"package"];
+}
+
+- (bool) _allowJavaScriptPanel {
+    return commercial_;
+}
+
+#if !AlwaysReload
+- (void) _customButtonClicked {
+    int count([buttons_ count]);
+    if (count == 0)
+        return;
+
+    if (count == 1)
+        [self _clickButtonWithName:[buttons_ objectAtIndex:0]];
+    else {
+        NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:count];
+        [buttons addObjectsFromArray:buttons_];
+
+        UIActionSheet *sheet = [[[UIActionSheet alloc]
+            initWithTitle:nil
+            delegate:self
+            cancelButtonTitle:nil
+            destructiveButtonTitle:nil
+            otherButtonTitles:nil
+        ] autorelease];
+
+        for (NSString *button in buttons) [sheet addButtonWithTitle:button];
+        if (!IsWildcat_) {
+           [sheet addButtonWithTitle:UCLocalize("CANCEL")];
+           [sheet setCancelButtonIndex:[sheet numberOfButtons] - 1];
+        }
+        [sheet setContext:@"modify"];
+
+        [delegate_ showActionSheet:sheet fromItem:[[self navigationItem] rightBarButtonItem]];
+    }
+}
+
+// We don't want to allow non-commercial packages to do custom things to the install button,
+// so it must call customButtonClicked with a custom commercial_ == 1 fallthrough.
+- (void) customButtonClicked {
+    if (commercial_)
+        [super customButtonClicked];
+    else
+        [self _customButtonClicked];
+}
+
+- (void) reloadButtonClicked {
+    // Don't reload a package view by clicking the button.
+}
+
+- (void) applyLoadingTitle {
+    // Don't show "Loading" as the title. Ever.
+}
+
+- (UIBarButtonItem *) rightButton {
+    int count = [buttons_ count];
+    return [[[UIBarButtonItem alloc]
+        initWithTitle:count == 0 ? nil : count != 1 ? UCLocalize("MODIFY") : [buttons_ objectAtIndex:0]
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(customButtonClicked)
+    ] autorelease];
+}
+#endif
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+        buttons_ = [[NSMutableArray alloc] initWithCapacity:4];
+        [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"package" ofType:@"html"]]];
+    } return self;
+}
+
+- (void) setPackage:(Package *)package {
+    if (package_ != nil) {
+        [package_ autorelease];
+        package_ = nil;
+    }
+
+    if (name_ != nil) {
+        [name_ release];
+        name_ = nil;
+    }
+
+    [buttons_ removeAllObjects];
+
+    if (package != nil) {
+        [package parse];
+
+        package_ = [package retain];
+        name_ = [[package id] retain];
+        commercial_ = [package isCommercial];
+
+        if ([package_ mode] != nil)
+            [buttons_ addObject:UCLocalize("CLEAR")];
+        if ([package_ source] == nil);
+        else if ([package_ upgradableAndEssential:NO])
+            [buttons_ addObject:UCLocalize("UPGRADE")];
+        else if ([package_ uninstalled])
+            [buttons_ addObject:UCLocalize("INSTALL")];
+        else
+            [buttons_ addObject:UCLocalize("REINSTALL")];
+        if (![package_ uninstalled])
+            [buttons_ addObject:UCLocalize("REMOVE")];
+
+        if (special_ != NULL) {
+            CGRect frame([document_ frame]);
+            frame.size.height = 0;
+            [document_ setFrame:frame];
+
+            if ([scroller_ respondsToSelector:@selector(scrollPointVisibleAtTopLeft:)])
+                [scroller_ scrollPointVisibleAtTopLeft:CGPointZero];
+            else
+                [scroller_ scrollRectToVisible:CGRectZero animated:NO];
+
+            WebThreadLock();
+            [[[document_ webView] windowScriptObject] setValue:package_ forKey:@"package"];
+
+            [self setButtonTitle:nil withStyle:nil toFunction:nil];
+
+            [self setFinishHook:nil];
+            [self setPopupHook:nil];
+            WebThreadUnlock();
+
+            //[self yieldToSelector:@selector(callFunction:) withObject:special_];
+            [super callFunction:special_];
+        }
+    }
+}
+
+- (bool) isLoading {
+    return commercial_ ? [super isLoading] : false;
+}
+
+- (void) reloadData {
+    [self setPackage:[database_ packageWithName:name_]];
+}
+
+@end
+/* }}} */
+/* Package Table {{{ */
+@interface PackageTable : UIView <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    NSMutableArray *packages_;
+    NSMutableArray *sections_;
+    UITableView *list_;
+    NSMutableArray *index_;
+    NSMutableDictionary *indices_;
+    id target_;
+    SEL action_;
+    id delegate_;
+}
+
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action;
+
+- (void) setDelegate:(id)delegate;
+
+- (void) reloadData;
+- (void) resetCursor;
+
+- (UITableView *) list;
+
+- (void) setShouldHideHeaderInShortLists:(BOOL)hide;
+
+- (void) deselectWithAnimation:(BOOL)animated;
+
+@end
+
+@implementation PackageTable
+
+- (void) dealloc {
+    [packages_ release];
+    [sections_ release];
+    [list_ release];
+    [index_ release];
+    [indices_ release];
+
+    [super dealloc];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
+    NSInteger count([sections_ count]);
+    return count == 0 ? 1 : count;
+}
+
+- (NSString *) tableView:(UITableView *)list titleForHeaderInSection:(NSInteger)section {
+    if ([sections_ count] == 0)
+        return nil;
+    return [[sections_ objectAtIndex:section] name];
+}
+
+- (NSInteger) tableView:(UITableView *)list numberOfRowsInSection:(NSInteger)section {
+    if ([sections_ count] == 0)
+        return 0;
+    return [[sections_ objectAtIndex:section] count];
+}
+
+- (Package *) packageAtIndexPath:(NSIndexPath *)path {
+    Section *section([sections_ objectAtIndex:[path section]]);
+    NSInteger row([path row]);
+    Package *package([packages_ objectAtIndex:([section row] + row)]);
+    return package;
+}
+
+- (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path {
+    PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]);
+    if (cell == nil)
+        cell = [[[PackageCell alloc] init] autorelease];
+    [cell setPackage:[self packageAtIndexPath:path]];
+    return cell;
+}
+
+- (void) deselectWithAnimation:(BOOL)animated {
+    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+}
+
+/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path {
+    return [PackageCell heightForPackage:[self packageAtIndexPath:path]];
+}*/
+
+- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path {
+    Package *package([self packageAtIndexPath:path]);
+    package = [database_ packageWithName:[package id]];
+    [target_ performSelector:action_ withObject:package];
+    return path;
+}
+
+- (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView {
+    return [packages_ count] > 20 ? index_ : nil;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
+    return index;
+}
+
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action {
+    if ((self = [super initWithFrame:frame]) != nil) {
+        database_ = database;
+
+        target_ = target;
+        action_ = action;
+
+        index_ = [[NSMutableArray alloc] initWithCapacity:32];
+        indices_ = [[NSMutableDictionary alloc] initWithCapacity:32];
+
+        packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
+        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
+
+        list_ = [[UITableView alloc] initWithFrame:[self bounds] style:UITableViewStylePlain];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [list_ setRowHeight:73.0f];
+        [self addSubview:list_];
+
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+    } return self;
+}
+
+- (void) setDelegate:(id)delegate {
+    delegate_ = delegate;
+}
+
+- (bool) hasPackage:(Package *)package {
+    return true;
+}
+
+- (void) reloadData {
+    NSArray *packages = [database_ packages];
+
+    [packages_ removeAllObjects];
+    [sections_ removeAllObjects];
+
+    _profile(PackageTable$reloadData$Filter)
+        for (Package *package in packages)
+            if ([self hasPackage:package])
+                [packages_ addObject:package];
+    _end
+
+    [index_ removeAllObjects];
+    [indices_ removeAllObjects];
+
+    Section *section = nil;
+
+    _profile(PackageTable$reloadData$Section)
+        for (size_t offset(0), end([packages_ count]); offset != end; ++offset) {
+            Package *package;
+            unichar index;
+
+            _profile(PackageTable$reloadData$Section$Package)
+                package = [packages_ objectAtIndex:offset];
+                index = [package index];
+            _end
+
+            if (section == nil || [section index] != index) {
+                _profile(PackageTable$reloadData$Section$Allocate)
+                    section = [[[Section alloc] initWithIndex:index row:offset] autorelease];
+                _end
+
+                [index_ addObject:[section name]];
+                //[indices_ setObject:[NSNumber numberForInt:[sections_ count]] forKey:index];
+
+                _profile(PackageTable$reloadData$Section$Add)
+                    [sections_ addObject:section];
+                _end
+            }
+
+            [section addToCount];
+        }
+    _end
+
+    _profile(PackageTable$reloadData$List)
+        [list_ reloadData];
+    _end
+}
+
+- (void) resetCursor {
+    [list_ scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:NO];
+}
+
+- (UITableView *) list {
+    return list_;
+}
+
+- (void) setShouldHideHeaderInShortLists:(BOOL)hide {
+    //XXX:[list_ setShouldHideHeaderInShortLists:hide];
+}
+
+@end
+/* }}} */
+/* Filtered Package Table {{{ */
+@interface FilteredPackageTable : PackageTable {
+    SEL filter_;
+    IMP imp_;
+    id object_;
+}
+
+- (void) setObject:(id)object;
+- (void) setObject:(id)object forFilter:(SEL)filter;
+
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object;
+
+@end
+
+@implementation FilteredPackageTable
+
+- (void) dealloc {
+    if (object_ != nil)
+        [object_ release];
+    [super dealloc];
+}
+
+- (void) setFilter:(SEL)filter {
+    filter_ = filter;
+
+    /* XXX: this is an unsafe optimization of doomy hell */
+    Method method(class_getInstanceMethod([Package class], filter));
+    _assert(method != NULL);
+    imp_ = method_getImplementation(method);
+    _assert(imp_ != NULL);
+}
+
+- (void) setObject:(id)object {
+    if (object_ != nil)
+        [object_ release];
+    if (object == nil)
+        object_ = nil;
+    else
+        object_ = [object retain];
+}
+
+- (void) setObject:(id)object forFilter:(SEL)filter {
+    [self setFilter:filter];
+    [self setObject:object];
+}
+
+- (bool) hasPackage:(Package *)package {
+    _profile(FilteredPackageTable$hasPackage)
+        return [package valid] && (*reinterpret_cast<bool (*)(id, SEL, id)>(imp_))(package, filter_, object_);
+    _end
+}
+
+- (id) initWithFrame:(CGRect)frame database:(Database *)database target:(id)target action:(SEL)action filter:(SEL)filter with:(id)object {
+    if ((self = [super initWithFrame:frame database:database target:target action:action]) != nil) {
+        [self setFilter:filter];
+        object_ = [object retain];
+        [self reloadData];
+    } return self;
+}
+
+@end
+/* }}} */
+
+/* Filtered Package Controller {{{ */
+@interface FilteredPackageController : CYViewController {
+    _transient Database *database_;
+    FilteredPackageTable *packages_;
+    NSString *title_;
+}
+
+- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object;
+
+@end
+
+@implementation FilteredPackageController
+
+- (void) dealloc {
+    [packages_ release];
+    [title_ release];
+
+    [super dealloc];
+}
+
+- (void) viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    [packages_ deselectWithAnimation:animated];
+}
+
+- (void) didSelectPackage:(Package *)package {
+    PackageController *view([delegate_ packageController]);
+    [view setPackage:package];
+    [view setDelegate:delegate_];
+    [[self navigationController] pushViewController:view animated:YES];
+}
+
+- (NSString *) title { return title_; }
+
+- (id) initWithDatabase:(Database *)database title:(NSString *)title filter:(SEL)filter with:(id)object {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+        title_ = [title copy];
+        [[self navigationItem] setTitle:title_];
+
+        packages_ = [[FilteredPackageTable alloc]
+            initWithFrame:[[self view] bounds]
+            database:database
+            target:self
+            action:@selector(didSelectPackage:)
+            filter:filter
+            with:object
+        ];
+
+        [packages_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [[self view] addSubview:packages_];
+    } return self;
+}
+
+- (void) reloadData {
+    [packages_ reloadData];
+}
+
+- (void) setDelegate:(id)delegate {
+    [super setDelegate:delegate];
+    [packages_ setDelegate:delegate];
+}
+
+@end
+
+/* }}} */
+
+/* Add Source Controller {{{ */
+@interface AddSourceController : CYViewController {
+    _transient Database *database_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+
+@end
+
+@implementation AddSourceController
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+    } return self;
+}
+
+@end
+/* }}} */
+/* Source Cell {{{ */
+@interface SourceCell : UITableViewCell <
+    ContentDelegate
+> {
+    UIImage *icon_;
+    NSString *origin_;
+    NSString *description_;
+    NSString *label_;
+    ContentView *content_;
+}
+
+- (void) setSource:(Source *)source;
+
+@end
+
+@implementation SourceCell
+
+- (void) clearSource {
+    [icon_ release];
+    [origin_ release];
+    [description_ release];
+    [label_ release];
+
+    icon_ = nil;
+    origin_ = nil;
+    description_ = nil;
+    label_ = nil;
+}
+
+- (void) setSource:(Source *)source {
+    [self clearSource];
+
+    if (icon_ == nil)
+        icon_ = [UIImage applicationImageNamed:[NSString stringWithFormat:@"Sources/%@.png", [source host]]];
+    if (icon_ == nil)
+        icon_ = [UIImage applicationImageNamed:@"unknown.png"];
+    icon_ = [icon_ retain];
+
+    origin_ = [[source name] retain];
+    label_ = [[source uri] retain];
+    description_ = [[source description] retain];
+
+    [content_ setNeedsDisplay];
+}
+
+- (void) dealloc {
+    [self clearSource];
+    [content_ release];
+    [super dealloc];
+}
+
+- (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
+    if ((self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) != nil) {
+        UIView *content([self contentView]);
+        CGRect bounds([content bounds]);
+
+        content_ = [[ContentView alloc] initWithFrame:bounds];
+        [content_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [content_ setBackgroundColor:[UIColor whiteColor]];
+        [content addSubview:content_];
+
+        [content_ setDelegate:self];
+        [content_ setOpaque:YES];
+    } return self;
+}
+
+- (void) setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+    [content_ setNeedsDisplay];
+}
+
+- (void) drawContentRect:(CGRect)rect {
+    bool selected([self isSelected]);
+    float width(rect.size.width);
+
+    if (icon_ != nil)
+        [icon_ drawInRect:CGRectMake(10, 10, 30, 30)];
+
+    if (selected)
+        UISetColor(White_);
+
+    if (!selected)
+        UISetColor(Black_);
+    [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation];
+
+    if (!selected)
+        UISetColor(Blue_);
+    [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation];
+
+    if (!selected)
+        UISetColor(Gray_);
+    [description_ drawAtPoint:CGPointMake(12, 46) forWidth:(width - 40) withFont:Font14_ lineBreakMode:UILineBreakModeTailTruncation];
+}
+
+@end
+/* }}} */
+/* Source Table {{{ */
+@interface SourceTable : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    UITableView *list_;
+    NSMutableArray *sources_;
+    int offset_;
+
+    NSString *href_;
+    UIProgressHUD *hud_;
+    NSError *error_;
+
+    //NSURLConnection *installer_;
+    NSURLConnection *trivial_;
+    NSURLConnection *trivial_bz2_;
+    NSURLConnection *trivial_gz_;
+    //NSURLConnection *automatic_;
+
+    BOOL cydia_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+
+- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated;
+
+@end
+
+@implementation SourceTable
+
+- (void) _deallocConnection:(NSURLConnection *)connection {
+    if (connection != nil) {
+        [connection cancel];
+        //[connection setDelegate:nil];
+        [connection release];
+    }
+}
+
+- (void) dealloc {
+    if (href_ != nil)
+        [href_ release];
+    if (hud_ != nil)
+        [hud_ release];
+    if (error_ != nil)
+        [error_ release];
+
+    //[self _deallocConnection:installer_];
+    [self _deallocConnection:trivial_];
+    [self _deallocConnection:trivial_gz_];
+    [self _deallocConnection:trivial_bz2_];
+    //[self _deallocConnection:automatic_];
+
+    [sources_ release];
+    [list_ release];
+    [super dealloc];
+}
+
+- (void) viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+    return offset_ == 0 ? 1 : 2;
+}
+
+- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+    switch (section + (offset_ == 0 ? 1 : 0)) {
+        case 0: return UCLocalize("ENTERED_BY_USER");
+        case 1: return UCLocalize("INSTALLED_BY_PACKAGE");
+
+        _nodefault
+    }
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    int count = [sources_ count];
+    switch (section) {
+        case 0: return (offset_ == 0 ? count : offset_);
+        case 1: return count - offset_;
+
+        _nodefault
+    }
+}
+
+- (Source *) sourceAtIndexPath:(NSIndexPath *)indexPath {
+    unsigned idx = 0;
+    switch (indexPath.section) {
+        case 0: idx = indexPath.row; break;
+        case 1: idx = indexPath.row + offset_; break;
+
+        _nodefault
+    }
+    return [sources_ objectAtIndex:idx];
+}
+
+- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    Source *source = [self sourceAtIndexPath:indexPath];
+    return [source description] == nil ? 56 : 73;
+}
+
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    static NSString *cellIdentifier = @"SourceCell";
+
+    SourceCell *cell = (SourceCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
+    if(cell == nil) cell = [[[SourceCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
+    [cell setSource:[self sourceAtIndexPath:indexPath]];
+
+    return cell;
+}
+
+- (UITableViewCellAccessoryType) tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
+    return UITableViewCellAccessoryDisclosureIndicator;
+}
+
+- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    Source *source = [self sourceAtIndexPath:indexPath];
+
+    FilteredPackageController *packages = [[[FilteredPackageController alloc]
+        initWithDatabase:database_
+        title:[source label]
+        filter:@selector(isVisibleInSource:)
+        with:source
+    ] autorelease];
+
+    [packages setDelegate:delegate_];
+
+    [[self navigationController] pushViewController:packages animated:YES];
+}
+
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+    Source *source = [self sourceAtIndexPath:indexPath];
+    return [source record] != nil;
+}
+
+- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+    Source *source = [self sourceAtIndexPath:indexPath];
+    [Sources_ removeObjectForKey:[source key]];
+    [delegate_ syncData];
+}
+
+- (void) complete {
+    [Sources_ setObject:[NSDictionary dictionaryWithObjectsAndKeys:
+        @"deb", @"Type",
+        href_, @"URI",
+        @"./", @"Distribution",
+    nil] forKey:[NSString stringWithFormat:@"deb:%@:./", href_]];
+
+    [delegate_ syncData];
+}
+
+- (NSString *) getWarning {
+    NSString *href(href_);
+    NSRange colon([href rangeOfString:@"://"]);
+    if (colon.location != NSNotFound)
+        href = [href substringFromIndex:(colon.location + 3)];
+    href = [href stringByAddingPercentEscapes];
+    href = [CydiaURL(@"api/repotag/") stringByAppendingString:href];
+    href = [href stringByCachingURLWithCurrentCDN];
+
+    NSURL *url([NSURL URLWithString:href]);
+
+    NSStringEncoding encoding;
+    NSError *error(nil);
+
+    if (NSString *warning = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:&error])
+        return [warning length] == 0 ? nil : warning;
+    return nil;
+}
+
+- (void) _endConnection:(NSURLConnection *)connection {
+    NSURLConnection **field = NULL;
+    if (connection == trivial_)
+        field = &trivial_;
+    else if (connection == trivial_bz2_)
+        field = &trivial_bz2_;
+    else if (connection == trivial_gz_)
+        field = &trivial_gz_;
+    _assert(field != NULL);
+    [connection release];
+    *field = nil;
+
+    if (
+        trivial_ == nil &&
+        trivial_bz2_ == nil &&
+        trivial_gz_ == nil
+    ) {
+        bool defer(false);
+
+        if (cydia_) {
+            if (NSString *warning = [self yieldToSelector:@selector(getWarning)]) {
+                defer = true;
+
+                UIAlertView *alert = [[[UIAlertView alloc]
+                    initWithTitle:UCLocalize("SOURCE_WARNING")
+                    message:warning
+                    delegate:self
+                    cancelButtonTitle:UCLocalize("CANCEL")
+                    otherButtonTitles:UCLocalize("ADD_ANYWAY"), nil
+                ] autorelease];
+
+                [alert setContext:@"warning"];
+                [alert setNumberOfRows:1];
+                [alert show];
+            } else
+                [self complete];
+        } else if (error_ != nil) {
+            UIAlertView *alert = [[[UIAlertView alloc]
+                initWithTitle:UCLocalize("VERIFICATION_ERROR")
+                message:[error_ localizedDescription]
+                delegate:self
+                cancelButtonTitle:UCLocalize("OK")
+                otherButtonTitles:nil
+            ] autorelease];
+
+            [alert setContext:@"urlerror"];
+            [alert show];
+        } else {
+            UIAlertView *alert = [[[UIAlertView alloc]
+                initWithTitle:UCLocalize("NOT_REPOSITORY")
+                message:UCLocalize("NOT_REPOSITORY_EX")
+                delegate:self
+                cancelButtonTitle:UCLocalize("OK")
+                otherButtonTitles:nil
+            ] autorelease];
+
+            [alert setContext:@"trivial"];
+            [alert show];
+        }
+
+        [delegate_ setStatusBarShowsProgress:NO];
+        [delegate_ removeProgressHUD:hud_];
+
+        [hud_ autorelease];
+        hud_ = nil;
+
+        if (!defer) {
+            [href_ release];
+            href_ = nil;
+        }
+
+        if (error_ != nil) {
+            [error_ release];
+            error_ = nil;
+        }
+    }
+}
+
+- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
+    switch ([response statusCode]) {
+        case 200:
+            cydia_ = YES;
+    }
+}
+
+- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
+    lprintf("connection:\"%s\" didFailWithError:\"%s\"", [href_ UTF8String], [[error localizedDescription] UTF8String]);
+    if (error_ != nil)
+        error_ = [error retain];
+    [self _endConnection:connection];
+}
+
+- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
+    [self _endConnection:connection];
+}
+
+- (NSString *) title { return UCLocalize("SOURCES"); }
+
+- (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method {
+    NSMutableURLRequest *request = [NSMutableURLRequest
+        requestWithURL:[NSURL URLWithString:href]
+        cachePolicy:NSURLRequestUseProtocolCachePolicy
+        timeoutInterval:120.0
+    ];
+
+    [request setHTTPMethod:method];
+
+    if (Machine_ != NULL)
+        [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"];
+    if (UniqueID_ != nil)
+        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
+    if (Role_ != nil)
+        [request setValue:Role_ forHTTPHeaderField:@"X-Role"];
+
+    return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
+}
+
+- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
+
+    if ([context isEqualToString:@"source"]) {
+        switch (button) {
+            case 1: {
+                NSString *href = [[alert textField] text];
+
+                //installer_ = [[self _requestHRef:href method:@"GET"] retain];
+
+                if (![href hasSuffix:@"/"])
+                    href_ = [href stringByAppendingString:@"/"];
+                else
+                    href_ = href;
+                href_ = [href_ retain];
+
+                trivial_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages"] method:@"HEAD"] retain];
+                trivial_bz2_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.bz2"] method:@"HEAD"] retain];
+                trivial_gz_ = [[self _requestHRef:[href_ stringByAppendingString:@"Packages.gz"] method:@"HEAD"] retain];
+                //trivial_bz2_ = [[self _requestHRef:[href stringByAppendingString:@"dists/Release"] method:@"HEAD"] retain];
+
+                cydia_ = false;
+
+                hud_ = [[delegate_ addProgressHUD] retain];
+                [hud_ setText:UCLocalize("VERIFYING_URL")];
+            } break;
+
+            case 0:
+            break;
+
+            _nodefault
+        }
+
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    } else if ([context isEqualToString:@"trivial"])
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    else if ([context isEqualToString:@"urlerror"])
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    else if ([context isEqualToString:@"warning"]) {
+        switch (button) {
+            case 1:
+                [self complete];
+            break;
+
+            case 0:
+            break;
+
+            _nodefault
+        }
+
+        [href_ release];
+        href_ = nil;
+
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    }
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        [[self navigationItem] setTitle:UCLocalize("SOURCES")];
+        [self updateButtonsForEditingStatus:NO animated:NO];
+
+        database_ = database;
+        sources_ = [[NSMutableArray arrayWithCapacity:16] retain];
+
+        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [[self view] addSubview:list_];
+
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+
+        [self reloadData];
+    } return self;
+}
+
+- (void) reloadData {
+    pkgSourceList list;
+    if (!list.ReadMainList())
+        return;
+
+    [sources_ removeAllObjects];
+    [sources_ addObjectsFromArray:[database_ sources]];
+    _trace();
+    [sources_ sortUsingSelector:@selector(compareByNameAndType:)];
+    _trace();
+
+     int count([sources_ count]);
+    offset_ = 0;
+    for (int i = 0; i != count; i++) {
+        if ([[sources_ objectAtIndex:i] record] == nil) break;
+        else offset_++;
+    }
+
+    [list_ setEditing:NO];
+    [self updateButtonsForEditingStatus:NO animated:NO];
+    [list_ reloadData];
+}
+
+- (void) addButtonClicked {
+    /*[book_ pushPage:[[[AddSourceController alloc]
+        initWithBook:book_
+        database:database_
+    ] autorelease]];*/
+
+    UIAlertView *alert = [[[UIAlertView alloc]
+        initWithTitle:UCLocalize("ENTER_APT_URL")
+        message:nil
+        delegate:self
+        cancelButtonTitle:UCLocalize("CANCEL")
+        otherButtonTitles:UCLocalize("ADD_SOURCE"), nil
+    ] autorelease];
+
+    [alert setContext:@"source"];
+    [alert setTransform:CGAffineTransformTranslate([alert transform], 0.0, 100.0)];
+
+    [alert setNumberOfRows:1];
+    [alert addTextFieldWithValue:@"http://" label:@""];
+
+    UITextInputTraits *traits = [[alert textField] textInputTraits];
+    [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+    [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+    [traits setKeyboardType:UIKeyboardTypeURL];
+    // XXX: UIReturnKeyDone
+    [traits setReturnKeyType:UIReturnKeyNext];
+
+    [alert show];
+}
+
+- (void) updateButtonsForEditingStatus:(BOOL)editing animated:(BOOL)animated {
+    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+        initWithTitle:UCLocalize("ADD")
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(addButtonClicked)
+    ];
+    [[self navigationItem] setLeftBarButtonItem:editing ? leftItem : [[self navigationItem] backBarButtonItem] animated:animated];
+    [leftItem release];
+
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:editing ? UCLocalize("DONE") : UCLocalize("EDIT")
+        style:editing ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
+        target:self
+        action:@selector(editButtonClicked)
+    ];
+    [[self navigationItem] setRightBarButtonItem:rightItem animated:animated];
+    [rightItem release];
+
+    if (IsWildcat_ && !editing) {
+        UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("SETTINGS")
+            style:UIBarButtonItemStylePlain
+            target:self
+            action:@selector(settingsButtonClicked)
+            ];
+        [[self navigationItem] setLeftBarButtonItem:settingsItem];
+        [settingsItem release];
+    }
+}
+
+- (void) settingsButtonClicked {
+    [delegate_ showSettings];
+}
+
+- (void) editButtonClicked {
+    [list_ setEditing:![list_ isEditing] animated:YES];
+
+    [self updateButtonsForEditingStatus:[list_ isEditing] animated:YES];
+}
+
+@end
+/* }}} */
+
+/* Installed Controller {{{ */
+@interface InstalledController : FilteredPackageController {
+    BOOL expert_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+
+- (void) updateRoleButton;
+- (void) queueStatusDidChange;
+
+@end
+
+@implementation InstalledController
+
+- (void) dealloc {
+    [super dealloc];
+}
+
+- (NSString *) title { return UCLocalize("INSTALLED"); }
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super initWithDatabase:database title:UCLocalize("INSTALLED") filter:@selector(isInstalledAndVisible:) with:[NSNumber numberWithBool:YES]]) != nil) {
+        [self updateRoleButton];
+        [self queueStatusDidChange];
+    } return self;
+}
+
+#if !AlwaysReload
+- (void) queueButtonClicked {
+    [delegate_ queue];
+}
+#endif
+
+- (void) queueStatusDidChange {
+#if !AlwaysReload
+    if (IsWildcat_) {
+        UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("QUEUE")
+            style:UIBarButtonItemStyleDone
+            target:self
+            action:@selector(queueButtonClicked)
+        ];
+        if (Queuing_) [[self navigationItem] setLeftBarButtonItem:queueItem];
+        else [[self navigationItem] setLeftBarButtonItem:nil];
+        [queueItem release];
+    }
+#endif
+}
+
+- (void) reloadData {
+    [packages_ reloadData];
+}
+
+- (void) updateRoleButton {
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:expert_ ? UCLocalize("EXPERT") : UCLocalize("SIMPLE")
+        style:expert_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain
+        target:self
+        action:@selector(roleButtonClicked)
+    ];
+    if (Role_ != nil && ![Role_ isEqualToString:@"Developer"]) [[self navigationItem] setRightBarButtonItem:rightItem];
+    [rightItem release];
+}
+
+- (void) roleButtonClicked {
+    [packages_ setObject:[NSNumber numberWithBool:expert_]];
+    [packages_ reloadData];
+    expert_ = !expert_;
+
+    [self updateRoleButton];
+}
+
+- (void) setDelegate:(id)delegate {
+    [super setDelegate:delegate];
+    [packages_ setDelegate:delegate];
+}
+
+@end
+/* }}} */
+
+/* Home Controller {{{ */
+@interface HomeController : CYBrowserController {
+}
+
+@end
+
+@implementation HomeController
+
+- (void) _setMoreHeaders:(NSMutableURLRequest *)request {
+    [super _setMoreHeaders:request];
+    if (ChipID_ != nil)
+        [request setValue:ChipID_ forHTTPHeaderField:@"X-Chip-ID"];
+    if (UniqueID_ != nil)
+        [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"];
+}
+
+- (void) aboutButtonClicked {
+    UIAlertView *alert = [[[UIAlertView alloc] init] autorelease];
+    [alert setTitle:UCLocalize("ABOUT_CYDIA")];
+    [alert addButtonWithTitle:UCLocalize("CLOSE")];
+    [alert setCancelButtonIndex:0];
+
+    [alert setMessage:
+        @"Copyright (C) 2008-2010\n"
+        "Jay Freeman (saurik)\n"
+        "saurik@saurik.com\n"
+        "http://www.saurik.com/"
+    ];
+
+    [alert show];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [[self navigationController] setNavigationBarHidden:YES animated:animated];
+}
+
+- (void) viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    [[self navigationController] setNavigationBarHidden:NO animated:animated];
+}
+
+- (id) init {
+    if ((self = [super init]) != nil) {
+        UIBarButtonItem *aboutItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("ABOUT")
+            style:UIBarButtonItemStylePlain
+            target:self
+            action:@selector(aboutButtonClicked)
+        ];
+        [[self navigationItem] setLeftBarButtonItem:aboutItem];
+        [aboutItem release];
+    } return self;
+}
+
+@end
+/* }}} */
+/* Manage Controller {{{ */
+@interface ManageController : CYBrowserController {
+}
+
+- (void) queueStatusDidChange;
+@end
+
+@implementation ManageController
+
+- (id) init {
+    if ((self = [super init]) != nil) {
+        [[self navigationItem] setTitle:UCLocalize("MANAGE")];
+
+        UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("SETTINGS")
+            style:UIBarButtonItemStylePlain
+            target:self
+            action:@selector(settingsButtonClicked)
+        ];
+        [[self navigationItem] setLeftBarButtonItem:settingsItem];
+        [settingsItem release];
+
+        [self queueStatusDidChange];
+    } return self;
+}
+
+- (void) settingsButtonClicked {
+    [delegate_ showSettings];
+}
+
+#if !AlwaysReload
+- (void) queueButtonClicked {
+    [delegate_ queue];
+}
+
+- (void) applyLoadingTitle {
+    // No "Loading" title.
+}
+
+- (void) applyRightButton {
+    // No right button.
+}
+#endif
+
+- (void) queueStatusDidChange {
+#if !AlwaysReload
+    if (!IsWildcat_ && Queuing_) {
+        UIBarButtonItem *queueItem = [[UIBarButtonItem alloc]
+            initWithTitle:UCLocalize("QUEUE")
+            style:UIBarButtonItemStyleDone
+            target:self
+            action:@selector(queueButtonClicked)
+        ];
+        [[self navigationItem] setRightBarButtonItem:queueItem];
+
+        [queueItem release];
+    } else {
+        [[self navigationItem] setRightBarButtonItem:nil];
+    }
+#endif
+}
+
+- (bool) isLoading {
+    return false;
+}
+
+@end
+/* }}} */
+
+/* Refresh Bar {{{ */
+@interface RefreshBar : UINavigationBar {
+    UIProgressIndicator *indicator_;
+    UITextLabel *prompt_;
+    UIProgressBar *progress_;
+    UINavigationButton *cancel_;
+}
+
+@end
+
+@implementation RefreshBar
+
+- (void) positionViews {
+    CGRect frame = [cancel_ frame];
+    frame.origin.x = [self frame].size.width - frame.size.width - 5;
+    frame.origin.y = ([self frame].size.height - frame.size.height) / 2;
+    [cancel_ setFrame:frame];
+
+    CGSize prgsize = {75, 100};
+    CGRect prgrect = {{
+        [self frame].size.width - prgsize.width - 10,
+        ([self frame].size.height - prgsize.height) / 2
+    } , prgsize};
+    [progress_ setFrame:prgrect];
+
+    CGSize indsize([UIProgressIndicator defaultSizeForStyle:[indicator_ activityIndicatorViewStyle]]);
+    unsigned indoffset = ([self frame].size.height - indsize.height) / 2;
+    CGRect indrect = {{indoffset, indoffset}, indsize};
+    [indicator_ setFrame:indrect];
+
+    CGSize prmsize = {215, indsize.height + 4};
+    CGRect prmrect = {{
+        indoffset * 2 + indsize.width,
+        unsigned([self frame].size.height - prmsize.height) / 2 - 1
+    }, prmsize};
+    [prompt_ setFrame:prmrect];
+}
+
+- (void)setFrame:(CGRect)frame {
+    [super setFrame:frame];
+
+    [self positionViews];
+}
+
+- (id) initWithFrame:(CGRect)frame delegate:(id)delegate {
+    if ((self = [super initWithFrame:frame])) {
+        [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
+
+        [self setTintColor:[UIColor colorWithRed:0.23 green:0.23 blue:0.23 alpha:1]];
+        [self setBarStyle:UIBarStyleBlack];
+
+        UIBarStyle barstyle([self _barStyle:NO]);
+        bool ugly(barstyle == UIBarStyleDefault);
+
+        UIProgressIndicatorStyle style = ugly ?
+            UIProgressIndicatorStyleMediumBrown :
+            UIProgressIndicatorStyleMediumWhite;
+
+        indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectZero];
+        [indicator_ setStyle:style];
+        [indicator_ startAnimation];
+        [self addSubview:indicator_];
+
+        prompt_ = [[UITextLabel alloc] initWithFrame:CGRectZero];
+        [prompt_ setColor:[UIColor colorWithCGColor:(ugly ? Blueish_ : Off_)]];
+        [prompt_ setBackgroundColor:[UIColor clearColor]];
+        [prompt_ setFont:[UIFont systemFontOfSize:15]];
+        [self addSubview:prompt_];
+
+        progress_ = [[UIProgressBar alloc] initWithFrame:CGRectZero];
+        [progress_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin];
+        [progress_ setStyle:0];
+        [self addSubview:progress_];
+
+        cancel_ = [[UINavigationButton alloc] initWithTitle:UCLocalize("CANCEL") style:UINavigationButtonStyleHighlighted];
+        [cancel_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+        [cancel_ addTarget:delegate action:@selector(cancelPressed) forControlEvents:UIControlEventTouchUpInside];
+        [cancel_ setBarStyle:barstyle];
+
+        [self positionViews];
+    } return self;
+}
+
+- (void) cancel {
+    [cancel_ removeFromSuperview];
+}
+
+- (void) start {
+    [prompt_ setText:UCLocalize("UPDATING_DATABASE")];
+    [progress_ setProgress:0];
+    [self addSubview:cancel_];
+}
+
+- (void) stop {
+    [cancel_ removeFromSuperview];
+}
+
+- (void) setPrompt:(NSString *)prompt {
+    [prompt_ setText:prompt];
+}
+
+- (void) setProgress:(float)progress {
+    [progress_ setProgress:progress];
+}
+
+@end
+/* }}} */
+
+@class CYNavigationController;
+
+/* Cydia Tab Bar Controller {{{ */
+@interface CYTabBarController : UITabBarController {
+    Database *database_;
+}
+
+@end
+
+@implementation CYTabBarController
+
+/* XXX: some logic should probably go here related to
+freeing the view controllers on tab change */
+
+- (void) reloadData {
+    size_t count([[self viewControllers] count]);
+    for (size_t i(0); i != count; ++i) {
+        CYNavigationController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
+        [page reloadData];
+    }
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+    } return self;
+}
+
+@end
+/* }}} */
+
+/* Cydia Navigation Controller {{{ */
+@interface CYNavigationController : UINavigationController {
+    _transient Database *database_;
+    id<UINavigationControllerDelegate> delegate_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+- (void) reloadData;
+
+@end
+
+
+@implementation CYNavigationController
+
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
+    // Inherit autorotation settings for modal parents.
+    if ([self parentViewController] && [[self parentViewController] modalViewController] == self) {
+        return [[self parentViewController] shouldAutorotateToInterfaceOrientation:orientation];
+    } else {
+        return [super shouldAutorotateToInterfaceOrientation:orientation];
+    }
+}
+
+- (void) dealloc {
+    [super dealloc];
+}
+
+- (void) reloadData {
+    size_t count([[self viewControllers] count]);
+    for (size_t i(0); i != count; ++i) {
+        CYViewController *page([[self viewControllers] objectAtIndex:(count - i - 1)]);
+        [page reloadData];
+    }
+}
+
+- (void) setDelegate:(id<UINavigationControllerDelegate>)delegate {
+    delegate_ = delegate;
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+    } return self;
+}
+
+@end
+/* }}} */
+/* Cydia:// Protocol {{{ */
+@interface CydiaURLProtocol : NSURLProtocol {
+}
+
+@end
+
+@implementation CydiaURLProtocol
+
++ (BOOL) canInitWithRequest:(NSURLRequest *)request {
+    NSURL *url([request URL]);
+    if (url == nil)
+        return NO;
+    NSString *scheme([[url scheme] lowercaseString]);
+    if (scheme == nil || ![scheme isEqualToString:@"cydia"])
+        return NO;
+    return YES;
+}
+
++ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
+    return request;
+}
+
+- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request {
+    id<NSURLProtocolClient> client([self client]);
+    if (icon == nil)
+        [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]];
+    else {
+        NSData *data(UIImagePNGRepresentation(icon));
+
+        NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]);
+        [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
+        [client URLProtocol:self didLoadData:data];
+        [client URLProtocolDidFinishLoading:self];
+    }
+}
+
+- (void) startLoading {
+    id<NSURLProtocolClient> client([self client]);
+    NSURLRequest *request([self request]);
+
+    NSURL *url([request URL]);
+    NSString *href([url absoluteString]);
+
+    NSString *path([href substringFromIndex:8]);
+    NSRange slash([path rangeOfString:@"/"]);
+
+    NSString *command;
+    if (slash.location == NSNotFound) {
+        command = path;
+        path = nil;
+    } else {
+        command = [path substringToIndex:slash.location];
+        path = [path substringFromIndex:(slash.location + 1)];
+    }
+
+    Database *database([Database sharedInstance]);
+
+    if ([command isEqualToString:@"package-icon"]) {
+        if (path == nil)
+            goto fail;
+        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        Package *package([database packageWithName:path]);
+        if (package == nil)
+            goto fail;
+        UIImage *icon([package icon]);
+        [self _returnPNGWithImage:icon forRequest:request];
+    } else if ([command isEqualToString:@"source-icon"]) {
+        if (path == nil)
+            goto fail;
+        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        NSString *source(Simplify(path));
+        UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sources/%@.png", App_, source]]);
+        if (icon == nil)
+            icon = [UIImage applicationImageNamed:@"unknown.png"];
+        [self _returnPNGWithImage:icon forRequest:request];
+    } else if ([command isEqualToString:@"uikit-image"]) {
+        if (path == nil)
+            goto fail;
+        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        UIImage *icon(_UIImageWithName(path));
+        [self _returnPNGWithImage:icon forRequest:request];
+    } else if ([command isEqualToString:@"section-icon"]) {
+        if (path == nil)
+            goto fail;
+        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        NSString *section(Simplify(path));
+        UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]);
+        if (icon == nil)
+            icon = [UIImage applicationImageNamed:@"unknown.png"];
+        [self _returnPNGWithImage:icon forRequest:request];
+    } else fail: {
+        [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]];
+    }
+}
+
+- (void) stopLoading {
+}
+
+@end
+/* }}} */
+
+/* Sections Controller {{{ */
+@interface SectionsController : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    NSMutableArray *sections_;
+    NSMutableArray *filtered_;
+    UITableView *list_;
+    UIView *accessory_;
+    BOOL editing_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+- (void) reloadData;
+- (void) resetView;
+
+- (void) editButtonClicked;
+
+@end
+
+@implementation SectionsController
+
+- (void) dealloc {
+    [list_ setDataSource:nil];
+    [list_ setDelegate:nil];
+
+    [sections_ release];
+    [filtered_ release];
+    [list_ release];
+    [accessory_ release];
+    [super dealloc];
+}
+
+- (void) viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+}
+
+- (Section *) sectionAtIndexPath:(NSIndexPath *)indexPath {
+    Section *section = (editing_ ? [sections_ objectAtIndex:[indexPath row]] : ([indexPath row] == 0 ? nil : [filtered_ objectAtIndex:([indexPath row] - 1)]));
+    return section;
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return editing_ ? [sections_ count] : [filtered_ count] + 1;
+}
+
+/*- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 45.0f;
+}*/
+
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    static NSString *reuseIdentifier = @"SectionCell";
+
+    SectionCell *cell = (SectionCell *) [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
+    if (cell == nil) cell = [[[SectionCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
+    [cell setSection:[self sectionAtIndexPath:indexPath] editing:editing_];
+
+    return cell;
+}
+
+- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    Section *section = [self sectionAtIndexPath:indexPath];
+    NSString *name = [section name];
+    NSString *title;
+
+    if ([indexPath row] == 0) {
+        section = nil;
+        name = nil;
+        title = UCLocalize("ALL_PACKAGES");
+    } else {
+        if (name != nil) {
+            name = [NSString stringWithString:name];
+            title = [[NSBundle mainBundle] localizedStringForKey:Simplify(name) value:nil table:@"Sections"];
+        } else {
+            name = @"";
+            title = UCLocalize("NO_SECTION");
+        }
+    }
+
+    FilteredPackageController *table = [[[FilteredPackageController alloc]
+        initWithDatabase:database_
+        title:title
+        filter:@selector(isVisibleInSection:)
+        with:name
+    ] autorelease];
+
+    [table setDelegate:delegate_];
+
+    [[self navigationController] pushViewController:table animated:YES];
+}
+
+- (NSString *) title { return UCLocalize("SECTIONS"); }
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+
+        [[self navigationItem] setTitle:UCLocalize("SECTIONS")];
+
+        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
+        filtered_ = [[NSMutableArray arrayWithCapacity:16] retain];
+
+        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds]];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [list_ setRowHeight:45.0f];
+        [[self view] addSubview:list_];
+
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+
+        [self reloadData];
+    } return self;
+}
+
+- (void) reloadData {
+    NSArray *packages = [database_ packages];
+
+    [sections_ removeAllObjects];
+    [filtered_ removeAllObjects];
+
+#if 0
+    typedef __gnu_cxx::hash_map<NSString *, Section *, NSStringMapHash, NSStringMapEqual> SectionMap;
+    SectionMap sections;
+    sections.resize(64);
+#else
+    NSMutableDictionary *sections([NSMutableDictionary dictionaryWithCapacity:32]);
+#endif
+
+    _trace();
+    for (Package *package in packages) {
+        NSString *name([package section]);
+        NSString *key(name == nil ? @"" : name);
+
+#if 0
+        Section **section;
+
+        _profile(SectionsView$reloadData$Section)
+            section = &sections[key];
+            if (*section == nil) {
+                _profile(SectionsView$reloadData$Section$Allocate)
+                    *section = [[[Section alloc] initWithName:name localize:YES] autorelease];
+                _end
+            }
+        _end
+
+        [*section addToCount];
+
+        _profile(SectionsView$reloadData$Filter)
+            if (![package valid] || ![package visible])
+                continue;
+        _end
+
+        [*section addToRow];
+#else
+        Section *section;
+
+        _profile(SectionsView$reloadData$Section)
+            section = [sections objectForKey:key];
+            if (section == nil) {
+                _profile(SectionsView$reloadData$Section$Allocate)
+                    section = [[[Section alloc] initWithName:name localize:YES] autorelease];
+                    [sections setObject:section forKey:key];
+                _end
+            }
+        _end
+
+        [section addToCount];
+
+        _profile(SectionsView$reloadData$Filter)
+            if (![package valid] || ![package visible])
+                continue;
+        _end
+
+        [section addToRow];
+#endif
+    }
+    _trace();
+
+#if 0
+    for (SectionMap::const_iterator i(sections.begin()), e(sections.end()); i != e; ++i)
+        [sections_ addObject:i->second];
+#else
+    [sections_ addObjectsFromArray:[sections allValues]];
+#endif
+
+    [sections_ sortUsingSelector:@selector(compareByLocalized:)];
+
+    for (Section *section in sections_) {
+        size_t count([section row]);
+        if (count == 0)
+            continue;
+
+        section = [[[Section alloc] initWithName:[section name] localized:[section localized]] autorelease];
+        [section setCount:count];
+        [filtered_ addObject:section];
+    }
+
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:[sections_ count] == 0 ? nil : UCLocalize("EDIT")
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(editButtonClicked)
+    ];
+    [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] != nil];
+    [rightItem release];
+
+    [list_ reloadData];
+    _trace();
+}
+
+- (void) resetView {
+    if (editing_)
+        [self editButtonClicked];
+}
+
+- (void) editButtonClicked {
+    if ((editing_ = !editing_))
+        [list_ reloadData];
+    else
+        [delegate_ updateData];
+
+    [[self navigationItem] setTitle:editing_ ? UCLocalize("SECTION_VISIBILITY") : UCLocalize("SECTIONS")];
+    [[[self navigationItem] rightBarButtonItem] setTitle:[sections_ count] == 0 ? nil : editing_ ? UCLocalize("DONE") : UCLocalize("EDIT")];
+    [[[self navigationItem] rightBarButtonItem] setStyle:editing_ ? UIBarButtonItemStyleDone : UIBarButtonItemStylePlain];
+}
+
+- (UIView *) accessoryView {
+    return accessory_;
+}
+
+@end
+/* }}} */
+/* Changes Controller {{{ */
+@interface ChangesController : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    NSMutableArray *packages_;
+    NSMutableArray *sections_;
+    UITableView *list_;
+    unsigned upgrades_;
+    BOOL hasSentFirstLoad_;
+}
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate;
+- (void) reloadData;
+
+@end
+
+@implementation ChangesController
+
+- (void) dealloc {
+    [list_ setDelegate:nil];
+    [list_ setDataSource:nil];
+
+    [packages_ release];
+    [sections_ release];
+    [list_ release];
+    [super dealloc];
+}
+
+- (void) viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    if (!hasSentFirstLoad_) {
+        hasSentFirstLoad_ = YES;
+        [self performSelector:@selector(reloadData) withObject:nil afterDelay:0.0];
+    } else {
+        [list_ deselectRowAtIndexPath:[list_ indexPathForSelectedRow] animated:animated];
+    }
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)list {
+    NSInteger count([sections_ count]);
+    return count == 0 ? 1 : count;
+}
+
+- (NSString *) tableView:(UITableView *)list titleForHeaderInSection:(NSInteger)section {
+    if ([sections_ count] == 0)
+        return nil;
+    return [[sections_ objectAtIndex:section] name];
+}
+
+- (NSInteger) tableView:(UITableView *)list numberOfRowsInSection:(NSInteger)section {
+    if ([sections_ count] == 0)
+        return 0;
+    return [[sections_ objectAtIndex:section] count];
+}
+
+- (Package *) packageAtIndexPath:(NSIndexPath *)path {
+    Section *section([sections_ objectAtIndex:[path section]]);
+    NSInteger row([path row]);
+    return [packages_ objectAtIndex:([section row] + row)];
+}
+
+- (UITableViewCell *) tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)path {
+    PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]);
+    if (cell == nil)
+        cell = [[[PackageCell alloc] init] autorelease];
+    [cell setPackage:[self packageAtIndexPath:path]];
+    return cell;
+}
+
+/*- (CGFloat) tableView:(UITableView *)table heightForRowAtIndexPath:(NSIndexPath *)path {
+    return [PackageCell heightForPackage:[self packageAtIndexPath:path]];
+}*/
+
+- (NSIndexPath *) tableView:(UITableView *)table willSelectRowAtIndexPath:(NSIndexPath *)path {
+    Package *package([self packageAtIndexPath:path]);
+    PackageController *view([delegate_ packageController]);
+    [view setDelegate:delegate_];
+    [view setPackage:package];
+    [[self navigationController] pushViewController:view animated:YES];
+    return path;
+}
+
+- (void) refreshButtonClicked {
+    [delegate_ beginUpdate];
+    [[self navigationItem] setLeftBarButtonItem:nil];
+}
+
+- (void) upgradeButtonClicked {
+    [delegate_ distUpgrade];
+}
+
+- (NSString *) title { return UCLocalize("CHANGES"); }
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+        [[self navigationItem] setTitle:UCLocalize("CHANGES")];
+
+        packages_ = [[NSMutableArray arrayWithCapacity:16] retain];
+        sections_ = [[NSMutableArray arrayWithCapacity:16] retain];
+
+        list_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain];
+        [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [list_ setRowHeight:73.0f];
+        [[self view] addSubview:list_];
+
+        [list_ setDataSource:self];
+        [list_ setDelegate:self];
+
+        delegate_ = delegate;
+    } return self;
+}
+
+- (void) _reloadPackages:(NSArray *)packages {
+    _trace();
+    for (Package *package in packages)
+        if (
+            [package uninstalled] && [package valid] && [package visible] ||
+            [package upgradableAndEssential:YES]
+        )
+            [packages_ addObject:package];
+
+    _trace();
+    [packages_ radixSortUsingFunction:reinterpret_cast<SKRadixFunction>(&PackageChangesRadix) withContext:NULL];
+    _trace();
+}
+
+- (void) reloadData {
+    NSArray *packages = [database_ packages];
+
+    [packages_ removeAllObjects];
+    [sections_ removeAllObjects];
+
+    UIProgressHUD *hud([delegate_ addProgressHUD]);
+    // XXX: localize
+    [hud setText:@"Loading Changes"];
+    NSLog(@"HUD:%@::%@", delegate_, hud);
+    [self yieldToSelector:@selector(_reloadPackages:) withObject:packages];
+    [delegate_ removeProgressHUD:hud];
+
+    Section *upgradable = [[[Section alloc] initWithName:UCLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease];
+    Section *ignored = [[[Section alloc] initWithName:UCLocalize("IGNORED_UPGRADES") localize:NO] autorelease];
+    Section *section = nil;
+    NSDate *last = nil;
+
+    upgrades_ = 0;
+    bool unseens = false;
+
+    CFDateFormatterRef formatter(CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle));
+
+    for (size_t offset = 0, count = [packages_ count]; offset != count; ++offset) {
+        Package *package = [packages_ objectAtIndex:offset];
+
+        BOOL uae = [package upgradableAndEssential:YES];
+
+        if (!uae) {
+            unseens = true;
+            NSDate *seen;
+
+            _profile(ChangesController$reloadData$Remember)
+                seen = [package seen];
+            _end
+
+            if (section == nil || last != seen && (seen == nil || [seen compare:last] != NSOrderedSame)) {
+                last = seen;
+
+                NSString *name;
+                if (seen == nil)
+                    name = UCLocalize("UNKNOWN");
+                else {
+                    name = (NSString *) CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen);
+                    [name autorelease];
+                }
+
+                _profile(ChangesController$reloadData$Allocate)
+                    name = [NSString stringWithFormat:UCLocalize("NEW_AT"), name];
+                    section = [[[Section alloc] initWithName:name row:offset localize:NO] autorelease];
+                    [sections_ addObject:section];
+                _end
+            }
+
+            [section addToCount];
+        } else if ([package ignored])
+            [ignored addToCount];
+        else {
+            ++upgrades_;
+            [upgradable addToCount];
+        }
+    }
+    _trace();
+
+    CFRelease(formatter);
+
+    if (unseens) {
+        Section *last = [sections_ lastObject];
+        size_t count = [last count];
+        [packages_ removeObjectsInRange:NSMakeRange([packages_ count] - count, count)];
+        [sections_ removeLastObject];
+    }
+
+    if ([ignored count] != 0)
+        [sections_ insertObject:ignored atIndex:0];
+    if (upgrades_ != 0)
+        [sections_ insertObject:upgradable atIndex:0];
+
+    [list_ reloadData];
+
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:[NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]]
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(upgradeButtonClicked)
+    ];
+    if (upgrades_ > 0) [[self navigationItem] setRightBarButtonItem:rightItem];
+    [rightItem release];
+
+    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]
+        initWithTitle:UCLocalize("REFRESH")
+        style:UIBarButtonItemStylePlain
+        target:self
+        action:@selector(refreshButtonClicked)
+    ];
+    if (![delegate_ updating]) [[self navigationItem] setLeftBarButtonItem:leftItem];
+    [leftItem release];
+}
+
+@end
+/* }}} */
+/* Search Controller {{{ */
+@interface SearchController : FilteredPackageController <
+    UISearchBarDelegate
+> {
+    UISearchBar *search_;
+}
+
+- (id) initWithDatabase:(Database *)database;
+- (void) reloadData;
+
+@end
+
+@implementation SearchController
+
+- (void) dealloc {
+    [search_ release];
+    [super dealloc];
+}
+
+- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
+    [packages_ setObject:[search_ text] forFilter:@selector(isUnfilteredAndSearchedForBy:)];
+    [search_ resignFirstResponder];
+    [self reloadData];
+}
+
+- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text {
+    [packages_ setObject:text forFilter:@selector(isUnfilteredAndSelectedForBy:)];
+    [self reloadData];
+}
+
+- (NSString *) title { return nil; }
+
+- (id) initWithDatabase:(Database *)database {
+    return [super initWithDatabase:database title:UCLocalize("SEARCH") filter:@selector(isUnfilteredAndSearchedForBy:) with:nil];
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    if (!search_) {
+        search_ = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, 44.0f)];
+        [search_ layoutSubviews];
+        [search_ setPlaceholder:UCLocalize("SEARCH_EX")];
+        UITextField *textField = [search_ searchField];
+        [textField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
+        [search_ setDelegate:self];
+        [textField setEnablesReturnKeyAutomatically:NO];
+        [[self navigationItem] setTitleView:textField];
+    }
+}
+
+- (void) _reloadData {
+}
+
+- (void) reloadData {
+    _profile(SearchController$reloadData)
+        [packages_ reloadData];
+    _end
+    PrintTimes();
+    [packages_ resetCursor];
+}
+
+- (void) didSelectPackage:(Package *)package {
+    [search_ resignFirstResponder];
+    [super didSelectPackage:package];
+}
+
+@end
+/* }}} */
+/* Settings Controller {{{ */
+@interface SettingsController : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    NSString *name_;
+    Package *package_;
+    UITableView *table_;
+    id subscribedSwitch_;
+    id ignoredSwitch_;
+    UITableViewCell *subscribedCell_;
+    UITableViewCell *ignoredCell_;
+}
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package;
+
+@end
+
+@implementation SettingsController
+
+- (void) dealloc {
+    [name_ release];
+    if (package_ != nil)
+        [package_ release];
+    [table_ release];
+    [subscribedSwitch_ release];
+    [ignoredSwitch_ release];
+    [subscribedCell_ release];
+    [ignoredCell_ release];
+
+    [super dealloc];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+    if (package_ == nil)
+        return 0;
+
+    return 1;
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    if (package_ == nil)
+        return 0;
+
+    return 1;
+}
+
+- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
+    return UCLocalize("SHOW_ALL_CHANGES_EX");
+}
+
+- (void) onSomething:(BOOL)value withKey:(NSString *)key {
+    if (package_ == nil)
+        return;
+
+    NSMutableDictionary *metadata([package_ metadata]);
+
+    BOOL before;
+    if (NSNumber *number = [metadata objectForKey:key])
+        before = [number boolValue];
+    else
+        before = NO;
+
+    if (value != before) {
+        [metadata setObject:[NSNumber numberWithBool:value] forKey:key];
+        Changed_ = true;
+        [delegate_ updateData];
+    }
+}
+
+- (void) onSubscribed:(id)control {
+    [self onSomething:(int) [control isOn] withKey:@"IsSubscribed"];
+}
+
+- (void) onIgnored:(id)control {
+    [self onSomething:(int) [control isOn] withKey:@"IsIgnored"];
+}
+
+- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    if (package_ == nil)
+        return nil;
+
+    switch ([indexPath row]) {
+        case 0: return subscribedCell_;
+        case 1: return ignoredCell_;
+
+        _nodefault
+    }
+
+    return nil;
+}
+
+- (NSString *) title { return UCLocalize("SETTINGS"); }
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+    if ((self = [super init])) {
+        database_ = database;
+        name_ = [package retain];
+
+        [[self navigationItem] setTitle:UCLocalize("SETTINGS")];
+
+        table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
+        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [[self view] addSubview:table_];
+
+        subscribedSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+        [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+        [subscribedSwitch_ addTarget:self action:@selector(onSubscribed:) forEvents:UIControlEventValueChanged];
+
+        ignoredSwitch_ = [[objc_getClass("UISwitch") alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
+        [ignoredSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
+        [ignoredSwitch_ addTarget:self action:@selector(onIgnored:) forEvents:UIControlEventValueChanged];
+
+        subscribedCell_ = [[UITableViewCell alloc] init];
+        [subscribedCell_ setText:UCLocalize("SHOW_ALL_CHANGES")];
+        [subscribedCell_ setAccessoryView:subscribedSwitch_];
+        [subscribedCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
+
+        ignoredCell_ = [[UITableViewCell alloc] init];
+        [ignoredCell_ setText:UCLocalize("IGNORE_UPGRADES")];
+        [ignoredCell_ setAccessoryView:ignoredSwitch_];
+        [ignoredCell_ setSelectionStyle:UITableViewCellSelectionStyleNone];
+
+        [table_ setDataSource:self];
+        [table_ setDelegate:self];
+        [self reloadData];
+    } return self;
+}
+
+- (void) reloadData {
+    if (package_ != nil)
+        [package_ autorelease];
+    package_ = [database_ packageWithName:name_];
+    if (package_ != nil) {
+        [package_ retain];
+        [subscribedSwitch_ setOn:([package_ subscribed] ? 1 : 0) animated:NO];
+        [ignoredSwitch_ setOn:([package_ ignored] ? 1 : 0) animated:NO];
+    }
+
+    [table_ reloadData];
+}
+
+@end
+/* }}} */
+
+/* Signature Controller {{{ */
+@interface SignatureController : CYBrowserController {
+    _transient Database *database_;
+    NSString *package_;
+}
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package;
+
+@end
+
+@implementation SignatureController
+
+- (void) dealloc {
+    [package_ release];
+    [super dealloc];
+}
+
+- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
+    // XXX: dude!
+    [super webView:sender didClearWindowObject:window forFrame:frame];
+}
+
+- (id) initWithDatabase:(Database *)database package:(NSString *)package {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+        package_ = [package retain];
+        [self reloadData];
+    } return self;
+}
+
+- (void) reloadData {
+    [self loadURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"signature" ofType:@"html"]]];
+}
+
+@end
+/* }}} */
+/* Role Controller {{{ */
+@interface RoleController : CYViewController <
+    UITableViewDataSource,
+    UITableViewDelegate
+> {
+    _transient Database *database_;
+    id roledelegate_;
+    UITableView *table_;
+    UISegmentedControl *segment_;
+    UIView *container_;
+}
+
+- (void) showDoneButton;
+- (void) resizeSegmentedControl;
+
+@end
+
+@implementation RoleController
+- (void) dealloc {
+    [table_ release];
+    [segment_ release];
+    [container_ release];
+
+    [super dealloc];
+}
+
+- (id) initWithDatabase:(Database *)database delegate:(id)delegate {
+    if ((self = [super init])) {
+        database_ = database;
+        roledelegate_ = delegate;
+
+        [[self navigationItem] setTitle:UCLocalize("WHO_ARE_YOU")];
+
+        NSArray *items = [NSArray arrayWithObjects:
+            UCLocalize("USER"),
+            UCLocalize("HACKER"),
+            UCLocalize("DEVELOPER"),
+        nil];
+        segment_ = [[UISegmentedControl alloc] initWithItems:items];
+        container_ = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)];
+        [container_ addSubview:segment_];
+
+        int index = -1;
+        if ([Role_ isEqualToString:@"User"]) index = 0;
+        if ([Role_ isEqualToString:@"Hacker"]) index = 1;
+        if ([Role_ isEqualToString:@"Developer"]) index = 2;
+        if (index != -1) {
+            [segment_ setSelectedSegmentIndex:index];
+            [self showDoneButton];
+        }
+
+        [segment_ addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged];
+        [self resizeSegmentedControl];
+
+        table_ = [[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped];
+        [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [table_ setDelegate:self];
+        [table_ setDataSource:self];
+        [[self view] addSubview:table_];
+        [table_ reloadData];
+    } return self;
+}
+
+- (void) resizeSegmentedControl {
+    CGFloat width = [[self view] frame].size.width;
+    [segment_ setFrame:CGRectMake(width / 32.0f, 0, width - (width / 32.0f * 2.0f), 44.0f)];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+
+    [self resizeSegmentedControl];
+}
+
+- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+    [self resizeSegmentedControl];
+}
+
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+    [self resizeSegmentedControl];
+}
+
+- (void) save {
+    NSString *role(nil);
+
+    switch ([segment_ selectedSegmentIndex]) {
+        case 0: role = @"User"; break;
+        case 1: role = @"Hacker"; break;
+        case 2: role = @"Developer"; break;
+
+        _nodefault
+    }
+
+    if (![role isEqualToString:Role_]) {
+        bool rolling(Role_ == nil);
+        Role_ = role;
+
+        Settings_ = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+            Role_, @"Role",
+        nil];
+
+        [Metadata_ setObject:Settings_ forKey:@"Settings"];
+
+        Changed_ = true;
+
+        if (rolling)
+            [roledelegate_ loadData];
+        else
+            [roledelegate_ updateData];
+    }
+}
+
+- (void) segmentChanged:(UISegmentedControl *)control {
+    [self showDoneButton];
+}
+
+- (void) doneButtonClicked {
+    [self save];
+    [[self navigationController] dismissModalViewControllerAnimated:YES];
+}
+
+- (void) showDoneButton {
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]
+        initWithTitle:UCLocalize("DONE")
+        style:UIBarButtonItemStyleDone
+        target:self
+        action:@selector(doneButtonClicked)
+    ];
+    [[self navigationItem] setRightBarButtonItem:rightItem animated:[[self navigationItem] rightBarButtonItem] == nil];
+    [rightItem release];
+}
+
+- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+    // XXX: For not having a single cell in the table, this sure is a lot of sections.
+    return 6;
+}
+
+- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return 0; // :(
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return nil; // This method is required by the protocol.
+}
+
+- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
+    if (section == 1)
+        return UCLocalize("ROLE_EX");
+    if (section == 4)
+        return [NSString stringWithFormat:
+            @"%@: %@\n%@: %@\n%@: %@",
+            UCLocalize("USER"), UCLocalize("USER_EX"),
+            UCLocalize("HACKER"), UCLocalize("HACKER_EX"),
+            UCLocalize("DEVELOPER"), UCLocalize("DEVELOPER_EX")
+        ];
+    else return nil;
+}
+
+- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+    if (section == 3) return 44.0f;
+    else return 0;
+}
+
+- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
+    if (section == 3) return container_;
+    else return nil;
+}
+
+@end
+/* }}} */
+
+/* Cydia Container {{{ */
+@interface CYContainer : UIViewController <ProgressDelegate> {
+    _transient Database *database_;
+    RefreshBar *refreshbar_;
+
+    bool dropped_;
+    bool updating_;
+    id updatedelegate_;
+    UITabBarController *root_;
+}
+
+- (void) setTabBarController:(UITabBarController *)controller;
+
+- (void) dropBar:(BOOL)animated;
+- (void) beginUpdate;
+- (void) raiseBar:(BOOL)animated;
+- (BOOL) updating;
+
+@end
+
+@implementation CYContainer
+
+- (BOOL) _reallyWantsFullScreenLayout {
+    return YES;
+}
+
+// NOTE: UIWindow only sends the top controller these messages,
+//       So we have to forward them on.
+
+- (void) viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    [root_ viewDidAppear:animated];
+}
+
+- (void) viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [root_ viewWillAppear:animated];
+}
+
+- (void) viewDidDisappear:(BOOL)animated {
+    [super viewDidDisappear:animated];
+    [root_ viewDidDisappear:animated];
+}
+
+- (void) viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    [root_ viewWillDisappear:animated];
+}
+
+- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
+    return IsWildcat_;
+}
+
+- (void) setTabBarController:(UITabBarController *)controller {
+    root_ = controller;
+    [[self view] addSubview:[root_ view]];
+}
+
+- (void) setUpdate:(NSDate *)date {
+    [self beginUpdate];
+}
+
+- (void) beginUpdate {
+    [self dropBar:YES];
+    [refreshbar_ start];
+
+    updating_ = true;
+
+    [NSThread
+        detachNewThreadSelector:@selector(performUpdate)
+        toTarget:self
+        withObject:nil
+    ];
+}
+
+- (void) performUpdate { _pooled
+    Status status;
+    status.setDelegate(self);
+    [database_ updateWithStatus:status];
+
+    [self
+        performSelectorOnMainThread:@selector(completeUpdate)
+        withObject:nil
+        waitUntilDone:NO
+    ];
+}
+
+- (void) completeUpdate {
+    updating_ = false;
+
+    [self raiseBar:YES];
+    [refreshbar_ stop];
+    [updatedelegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+}
+
+- (void) cancelUpdate {
+    [refreshbar_ cancel];
+    [self completeUpdate];
+}
+
+- (void) cancelPressed {
+    [self cancelUpdate];
+}
+
+- (BOOL) updating {
+    return updating_;
+}
+
+- (void) setProgressError:(NSString *)error withTitle:(NSString *)title {
+    [refreshbar_ setPrompt:[NSString stringWithFormat:UCLocalize("COLON_DELIMITED"), UCLocalize("ERROR"), error]];
+}
+
+- (void) startProgress {
+}
+
+- (void) setProgressTitle:(NSString *)title {
+    [self
+        performSelectorOnMainThread:@selector(_setProgressTitle:)
+        withObject:title
+        waitUntilDone:YES
+    ];
+}
+
+- (bool) isCancelling:(size_t)received {
+    return !updating_;
+}
+
+- (void) setProgressPercent:(float)percent {
+    [self
+        performSelectorOnMainThread:@selector(_setProgressPercent:)
+        withObject:[NSNumber numberWithFloat:percent]
+        waitUntilDone:YES
+    ];
+}
+
+- (void) addProgressOutput:(NSString *)output {
+    [self
+        performSelectorOnMainThread:@selector(_addProgressOutput:)
+        withObject:output
+        waitUntilDone:YES
+    ];
+}
+
+- (void) _setProgressTitle:(NSString *)title {
+    [refreshbar_ setPrompt:title];
+}
+
+- (void) _setProgressPercent:(NSNumber *)percent {
+    [refreshbar_ setProgress:[percent floatValue]];
+}
+
+- (void) _addProgressOutput:(NSString *)output {
+}
+
+- (void) setUpdateDelegate:(id)delegate {
+    updatedelegate_ = delegate;
+}
+
+- (CGFloat) statusBarHeight {
+    if (UIInterfaceOrientationIsPortrait([self interfaceOrientation])) {
+        return [[UIApplication sharedApplication] statusBarFrame].size.height;
+    } else {
+        return [[UIApplication sharedApplication] statusBarFrame].size.width;
+    }
+}
+
+- (void) dropBar:(BOOL)animated {
+    if (dropped_) return;
+    dropped_ = true;
+
+    [[self view] addSubview:refreshbar_];
+
+    CGFloat sboffset = [self statusBarHeight];
+
+    CGRect barframe = [refreshbar_ frame];
+    barframe.origin.y = sboffset;
+    [refreshbar_ setFrame:barframe];
+
+    if (animated) [UIView beginAnimations:nil context:NULL];
+    CGRect viewframe = [[root_ view] frame];
+    viewframe.origin.y += barframe.size.height + sboffset;
+    viewframe.size.height -= barframe.size.height + sboffset;
+    [[root_ view] setFrame:viewframe];
+    if (animated) [UIView commitAnimations];
+
+    // Ensure bar has the proper width for our view, it might have changed
+    barframe.size.width = viewframe.size.width;
+    [refreshbar_ setFrame:barframe];
+
+    // XXX: fix Apple's layout bug
+    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
+}
+
+- (void) raiseBar:(BOOL)animated {
+    if (!dropped_) return;
+    dropped_ = false;
+
+    [refreshbar_ removeFromSuperview];
+
+    CGFloat sboffset = [self statusBarHeight];
+
+    if (animated) [UIView beginAnimations:nil context:NULL];
+    CGRect barframe = [refreshbar_ frame];
+    CGRect viewframe = [[root_ view] frame];
+    viewframe.origin.y -= barframe.size.height + sboffset;
+    viewframe.size.height += barframe.size.height + sboffset;
+    [[root_ view] setFrame:viewframe];
+    if (animated) [UIView commitAnimations];
+
+    // XXX: fix Apple's layout bug
+    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
+}
+
+- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
+    // XXX: fix Apple's layout bug
+    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
+}
+
+- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+    if (dropped_) {
+        [self raiseBar:NO];
+        [self dropBar:NO];
+    }
+
+    // XXX: fix Apple's layout bug
+    [[root_ selectedViewController] _updateLayoutForStatusBarAndInterfaceOrientation];
+}
+
+- (void) statusBarFrameChanged:(NSNotification *)notification {
+    if (dropped_) {
+        [self raiseBar:NO];
+        [self dropBar:NO];
+    }
+}
+
+- (void) dealloc {
+    [refreshbar_ release];
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+    [super dealloc];
+}
+
+- (id) initWithDatabase:(Database *)database {
+    if ((self = [super init]) != nil) {
+        database_ = database;
+
+        [[self view] setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
+
+        refreshbar_ = [[RefreshBar alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, [UINavigationBar defaultSize].height) delegate:self];
+    } return self;
+}
+
+@end
+/* }}} */
+
+typedef enum {
+    kCydiaTag = 0,
+    kSectionsTag = 1,
+    kChangesTag = 2,
+    kManageTag = 3,
+    kInstalledTag = 4,
+    kSourcesTag = 5,
+    kSearchTag = 6
+} CYTabTag;
+
+@interface Cydia : UIApplication <
+    ConfirmationControllerDelegate,
+    ProgressControllerDelegate,
+    CydiaDelegate,
+    UINavigationControllerDelegate
+> {
+    UIWindow *window_;
+    CYContainer *container_;
+
+    id tabbar_;
+
+    NSMutableArray *essential_;
+    NSMutableArray *broken_;
+
+    Database *database_;
+
+    int tag_;
+
+    UIKeyboard *keyboard_;
+    UIProgressHUD *hud_;
+
+    SectionsController *sections_;
+    ChangesController *changes_;
+    ManageController *manage_;
+    SearchController *search_;
+    SourceTable *sources_;
+    InstalledController *installed_;
+    id queueDelegate_;
+
+#if RecyclePackageViews
+    NSMutableArray *details_;
+#endif
+
+    bool loaded_;
+}
+
+- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class;
+- (void) setPage:(CYViewController *)page;
+- (void) loadData;
+
+@end
+
+static _finline void _setHomePage(Cydia *self) {
+    [self setPage:[self _pageForURL:[NSURL URLWithString:CydiaURL(@"")] withClass:[HomeController class]]];
+}
+
+@implementation Cydia
+
+- (void) beginUpdate {
+    [container_ beginUpdate];
+}
+
+- (BOOL) updating {
+    return [container_ updating];
+}
+
+- (UIView *) rotatingContentViewForWindow:(UIWindow *)window {
+    return window_;
+}
+
+- (void) _loaded {
+    if ([broken_ count] != 0) {
+        int count = [broken_ count];
+
+        UIAlertView *alert = [[[UIAlertView alloc]
+            initWithTitle:(count == 1 ? UCLocalize("HALFINSTALLED_PACKAGE") : [NSString stringWithFormat:UCLocalize("HALFINSTALLED_PACKAGES"), count])
+            message:UCLocalize("HALFINSTALLED_PACKAGE_EX")
+            delegate:self
+            cancelButtonTitle:UCLocalize("FORCIBLY_CLEAR")
+            otherButtonTitles:UCLocalize("TEMPORARY_IGNORE"), nil
+        ] autorelease];
+
+        [alert setContext:@"fixhalf"];
+        [alert show];
+    } else if (!Ignored_ && [essential_ count] != 0) {
+        int count = [essential_ count];
+
+        UIAlertView *alert = [[[UIAlertView alloc]
+            initWithTitle:(count == 1 ? UCLocalize("ESSENTIAL_UPGRADE") : [NSString stringWithFormat:UCLocalize("ESSENTIAL_UPGRADES"), count])
+            message:UCLocalize("ESSENTIAL_UPGRADE_EX")
+            delegate:self
+            cancelButtonTitle:UCLocalize("TEMPORARY_IGNORE")
+            otherButtonTitles:UCLocalize("UPGRADE_ESSENTIAL"), UCLocalize("COMPLETE_UPGRADE"), nil
+        ] autorelease];
+
+        [alert setContext:@"upgrade"];
+        [alert show];
+    }
+}
+
+- (void) _saveConfig {
+    if (Changed_) {
+        _trace();
+        NSString *error(nil);
+        if (NSData *data = [NSPropertyListSerialization dataFromPropertyList:Metadata_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]) {
+            _trace();
+            NSError *error(nil);
+            if (![data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error])
+                NSLog(@"failure to save metadata data: %@", error);
+            _trace();
+        } else {
+            NSLog(@"failure to serialize metadata: %@", error);
+            return;
+        }
+
+        Changed_ = false;
+    }
+}
+
+- (void) _updateData {
+    [self _saveConfig];
+
+    /* XXX: this is just stupid */
+    if (tag_ != 1 && sections_ != nil)
+        [sections_ reloadData];
+    if (tag_ != 2 && changes_ != nil)
+        [changes_ reloadData];
+    if (tag_ != 4 && search_ != nil)
+        [search_ reloadData];
+
+    [(CYNavigationController *)[tabbar_ selectedViewController] reloadData];
+}
+
+- (int)indexOfTabWithTag:(int)tag {
+    int i = 0;
+    for (UINavigationController *controller in [tabbar_ viewControllers]) {
+        if ([[controller tabBarItem] tag] == tag) return i;
+        i += 1;
+    }
+
+    return -1;
+}
+
+- (void) _refreshIfPossible {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    SCNetworkReachabilityFlags flags; {
+        SCNetworkReachabilityRef reachability(SCNetworkReachabilityCreateWithName(NULL, "cydia.saurik.com"));
+        SCNetworkReachabilityGetFlags(reachability, &flags);
+        CFRelease(reachability);
+    }
+
+    // XXX: this elaborate mess is what Apple is using to determine this? :(
+    // XXX: do we care if the user has to intervene? maybe that's ok?
+    bool reachable(
+        (flags & kSCNetworkReachabilityFlagsReachable) != 0 && (
+            (flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0 || (
+                (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0 ||
+                (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0
+            ) && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0 ||
+            (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0
+        )
+    );
+
+    if (loaded_ || ManualRefresh || !reachable) loaded:
+        [self performSelectorOnMainThread:@selector(_loaded) withObject:nil waitUntilDone:NO];
+    else {
+        loaded_ = true;
+
+        NSDate *update([Metadata_ objectForKey:@"LastUpdate"]);
+
+        if (update != nil) {
+            NSTimeInterval interval([update timeIntervalSinceNow]);
+            if (interval <= 0 && interval > -(15*60))
+                goto loaded;
+        }
+
+        [container_ performSelectorOnMainThread:@selector(setUpdate:) withObject:update waitUntilDone:NO];
+    }
+
+    [pool release];
+}
+
+- (void) refreshIfPossible {
+    [NSThread detachNewThreadSelector:@selector(_refreshIfPossible) toTarget:self withObject:nil];
+}
+
+- (void) _reloadData {
+    UIProgressHUD *hud([self addProgressHUD]);
+    [hud setText:(loaded_ ? UCLocalize("RELOADING_DATA") : UCLocalize("LOADING_DATA"))];
+
+    [database_ yieldToSelector:@selector(reloadData) withObject:nil];
+    _trace();
+
+    [self removeProgressHUD:hud];
+
+    size_t changes(0);
+
+    [essential_ removeAllObjects];
+    [broken_ removeAllObjects];
+
+    NSArray *packages([database_ packages]);
+    for (Package *package in packages) {
+        if ([package half])
+            [broken_ addObject:package];
+        if ([package upgradableAndEssential:NO]) {
+            if ([package essential])
+                [essential_ addObject:package];
+            ++changes;
+        }
+    }
+
+    if (changes != 0) {
+        NSString *badge([[NSNumber numberWithInt:changes] stringValue]);
+        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:badge];
+        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:YES];
+
+        if ([self respondsToSelector:@selector(setApplicationBadge:)])
+            [self setApplicationBadge:badge];
+        else
+            [self setApplicationBadgeString:badge];
+    } else {
+        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setBadgeValue:nil];
+        [[[[tabbar_ viewControllers] objectAtIndex:[self indexOfTabWithTag:kChangesTag]] tabBarItem] setAnimatedBadge:NO];
+
+        if ([self respondsToSelector:@selector(removeApplicationBadge)])
+            [self removeApplicationBadge];
+        else // XXX: maybe use setApplicationBadgeString also?
+            [self setApplicationIconBadgeNumber:0];
+    }
+
+    [self _updateData];
+
+    [self refreshIfPossible];
+}
+
+- (void) updateData {
+    [database_ setVisible];
+    [self _updateData];
+}
+
+- (void) update_ {
+    [database_ update];
+}
+
+- (void) syncData {
+    FILE *file(fopen("/etc/apt/sources.list.d/cydia.list", "w"));
+    _assert(file != NULL);
+
+    for (NSString *key in [Sources_ allKeys]) {
+        NSDictionary *source([Sources_ objectForKey:key]);
+
+        fprintf(file, "%s %s %s\n",
+            [[source objectForKey:@"Type"] UTF8String],
+            [[source objectForKey:@"URI"] UTF8String],
+            [[source objectForKey:@"Distribution"] UTF8String]
+        );
+    }
+
+    fclose(file);
+
+    [self _saveConfig];
+
+    ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
+    CYNavigationController *navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
+    if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
+    [container_ presentModalViewController:navigation animated:YES];
+
+    [progress
+        detachNewThreadSelector:@selector(update_)
+        toTarget:self
+        withObject:nil
+        title:UCLocalize("UPDATING_SOURCES")
+    ];
+}
+
+- (void) reloadData {
+    @synchronized (self) {
+        [self _reloadData];
+    }
+}
+
+- (void) resolve {
+    pkgProblemResolver *resolver = [database_ resolver];
+
+    resolver->InstallProtect();
+    if (!resolver->Resolve(true))
+        _error->Discard();
+}
+
+- (CGRect) popUpBounds {
+    return [[tabbar_ view] bounds];
+}
+
+- (bool) perform {
+    if (![database_ prepare])
+        return false;
+
+    ConfirmationController *page([[[ConfirmationController alloc] initWithDatabase:database_] autorelease]);
+    [page setDelegate:self];
+    CYNavigationController *confirm_ = [[CYNavigationController alloc] initWithRootViewController:page];
+    [confirm_ setDelegate:self];
+
+    if (IsWildcat_) [confirm_ setModalPresentationStyle:UIModalPresentationFormSheet];
+    [container_ presentModalViewController:confirm_ animated:YES];
+
+    return true;
+}
+
+- (void) queue {
+    @synchronized (self) {
+        [self perform];
+    }
+}
+
+- (void) clearPackage:(Package *)package {
+    @synchronized (self) {
+        [package clear];
+        [self resolve];
+        [self perform];
+    }
+}
+
+- (void) installPackages:(NSArray *)packages {
+    @synchronized (self) {
+        for (Package *package in packages)
+            [package install];
+        [self resolve];
+        [self perform];
+    }
+}
+
+- (void) installPackage:(Package *)package {
+    @synchronized (self) {
+        [package install];
+        [self resolve];
+        [self perform];
+    }
+}
+
+- (void) removePackage:(Package *)package {
+    @synchronized (self) {
+        [package remove];
+        [self resolve];
+        [self perform];
+    }
+}
+
+- (void) distUpgrade {
+    @synchronized (self) {
+        if (![database_ upgrade])
+            return;
+        [self perform];
+    }
+}
+
+- (void) complete {
+    @synchronized (self) {
+        [self _reloadData];
+    }
+}
+
+- (void) confirmWithNavigationController:(UINavigationController *)navigation {
+    ProgressController *progress = [[[ProgressController alloc] initWithDatabase:database_ delegate:self] autorelease];
+
+    if (navigation != nil) {
+        [navigation pushViewController:progress animated:YES];
+    } else {
+        navigation = [[[CYNavigationController alloc] initWithRootViewController:progress] autorelease];
+        if (IsWildcat_) [navigation setModalPresentationStyle:UIModalPresentationFormSheet];
+        [container_ presentModalViewController:navigation animated:YES];
+    }
+
+    [progress
+        detachNewThreadSelector:@selector(perform)
+        toTarget:database_
+        withObject:nil
+        title:UCLocalize("RUNNING")
+    ];
+}
+
+- (void) progressControllerIsComplete:(ProgressController *)progress {
+    [self complete];
+}
+
+- (void) setPage:(CYViewController *)page {
+    [page setDelegate:self];
+
+    CYNavigationController *navController = (CYNavigationController *) [tabbar_ selectedViewController];
+    [navController setViewControllers:[NSArray arrayWithObject:page]];
+    for (CYNavigationController *page in [tabbar_ viewControllers]) {
+        if (page != navController) [page setViewControllers:nil];
+    }
+}
+
+- (CYViewController *) _pageForURL:(NSURL *)url withClass:(Class)_class {
+    CYBrowserController *browser = [[[_class alloc] init] autorelease];
+    [browser loadURL:url];
+    return browser;
+}
+
+- (SectionsController *) sectionsController {
+    if (sections_ == nil)
+        sections_ = [[SectionsController alloc] initWithDatabase:database_];
+    return sections_;
+}
+
+- (ChangesController *) changesController {
+    if (changes_ == nil)
+        changes_ = [[ChangesController alloc] initWithDatabase:database_ delegate:self];
+    return changes_;
+}
+
+- (ManageController *) manageController {
+    if (manage_ == nil) {
+        manage_ = (ManageController *) [[self
+            _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]
+            withClass:[ManageController class]
+        ] retain];
+        if (!IsWildcat_) queueDelegate_ = manage_;
+    }
+    return manage_;
+}
+
+- (SearchController *) searchController {
+    if (search_ == nil)
+        search_ = [[SearchController alloc] initWithDatabase:database_];
+    return search_;
+}
+
+- (SourceTable *) sourcesController {
+    if (sources_ == nil)
+        sources_ = [[SourceTable alloc] initWithDatabase:database_];
+    return sources_;
+}
+
+- (InstalledController *) installedController {
+    if (installed_ == nil) {
+        installed_ = [[InstalledController alloc] initWithDatabase:database_];
+        if (IsWildcat_) queueDelegate_ = installed_;
+    }
+    return installed_;
+}
+
+- (void) tabBarController:(id)tabBarController didSelectViewController:(UIViewController *)viewController {
+    int tag = [[viewController tabBarItem] tag];
+    if (tag == tag_) {
+        [(CYNavigationController *)[tabbar_ selectedViewController] popToRootViewControllerAnimated:YES];
+        return;
+    } else if (tag_ == 1) {
+        [[self sectionsController] resetView];
+    }
+
+    switch (tag) {
+        case kCydiaTag: _setHomePage(self); break;
+
+        case kSectionsTag: [self setPage:[self sectionsController]]; break;
+        case kChangesTag: [self setPage:[self changesController]]; break;
+        case kManageTag: [self setPage:[self manageController]]; break;
+        case kInstalledTag: [self setPage:[self installedController]]; break;
+        case kSourcesTag: [self setPage:[self sourcesController]]; break;
+        case kSearchTag: [self setPage:[self searchController]]; break;
+
+        _nodefault
+    }
+
+    tag_ = tag;
+}
+
+- (void) showSettings {
+    RoleController *role = [[RoleController alloc] initWithDatabase:database_ delegate:self];
+    CYNavigationController *nav = [[CYNavigationController alloc] initWithRootViewController:role];
+    if (IsWildcat_) [nav setModalPresentationStyle:UIModalPresentationFormSheet];
+    [container_ presentModalViewController:nav animated:YES];
+}
+
+- (void) setPackageController:(PackageController *)view {
+    WebThreadLock();
+    [view setPackage:nil];
+#if RecyclePackageViews
+    if ([details_ count] < 3)
+        [details_ addObject:view];
+#endif
+    WebThreadUnlock();
+}
+
+- (PackageController *) _packageController {
+    return [[[PackageController alloc] initWithDatabase:database_] autorelease];
+}
+
+- (PackageController *) packageController {
+#if RecyclePackageViews
+    PackageController *view;
+    size_t count([details_ count]);
+
+    if (count == 0) {
+        view = [self _packageController];
+      renew:
+        [details_ addObject:[self _packageController]];
+    } else {
+        view = [[[details_ lastObject] retain] autorelease];
+        [details_ removeLastObject];
+        if (count == 1)
+            goto renew;
+    }
+
+    return view;
+#else
+    return [self _packageController];
+#endif
+}
+
+// Returns the navigation controller for the queuing badge.
+- (id) queueBadgeController {
+    int index = [self indexOfTabWithTag:kManageTag];
+    if (index == -1) index = [self indexOfTabWithTag:kInstalledTag];
+
+    return [[tabbar_ viewControllers] objectAtIndex:index];
+}
+
+- (void) cancelAndClear:(bool)clear {
+    @synchronized (self) {
+        if (clear) {
+            // Clear all marks.
+            pkgCacheFile &cache([database_ cache]);
+            for (pkgCache::PkgIterator iterator = cache->PkgBegin(); !iterator.end(); ++iterator) {
+                // Unmark method taken from Synaptic Package Manager.
+                // Thanks for being sane, unlike Aptitude.
+                if (!cache[iterator].Keep()) {
+                    cache->MarkKeep(iterator, false);
+                    cache->SetReInstall(iterator, false);
+                }
+            }
+
+            // Stop queuing.
+            Queuing_ = false;
+            [[[self queueBadgeController] tabBarItem] setBadgeValue:nil];
+        } else {
+            // Start queuing.
+            Queuing_ = true;
+            [[[self queueBadgeController] tabBarItem] setBadgeValue:UCLocalize("Q_D")];
+        }
+
+        // Show the changes in the current view.
+        [(CYNavigationController *) [tabbar_ selectedViewController] reloadData];
+        [queueDelegate_ queueStatusDidChange];
+    }
+}
+
+- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button {
+    NSString *context([alert context]);
+
+    if ([context isEqualToString:@"fixhalf"]) {
+        if (button == [alert firstOtherButtonIndex]) {
+            @synchronized (self) {
+                for (Package *broken in broken_) {
+                    [broken remove];
+
+                    NSString *id = [broken id];
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
+                    unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
+                }
+
+                [self resolve];
+                [self perform];
+            }
+        } else if (button == [alert cancelButtonIndex]) {
+            [broken_ removeAllObjects];
+            [self _loaded];
+        }
+
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    } else if ([context isEqualToString:@"upgrade"]) {
+        if (button == [alert firstOtherButtonIndex]) {
+            @synchronized (self) {
+                for (Package *essential in essential_)
+                    [essential install];
+
+                [self resolve];
+                [self perform];
+            }
+        } else if (button == [alert firstOtherButtonIndex] + 1) {
+            [self distUpgrade];
+        } else if (button == [alert cancelButtonIndex]) {
+            Ignored_ = YES;
+        }
+
+        [alert dismissWithClickedButtonIndex:-1 animated:YES];
+    }
+}
+
+- (void) system:(NSString *)command { _pooled
+    system([command UTF8String]);
+}
+
+- (void) applicationWillSuspend {
+    [database_ clean];
+    [super applicationWillSuspend];
+}
+
+- (void) applicationSuspend:(__GSEvent *)event {
+    // FIXME: This needs to be fixed, but we no longer have a progress_.
+    //        What's the best solution?
+    if (hud_ == nil)// && ![progress_ isRunning])
+        [super applicationSuspend:event];
+}
+
+- (void) _animateSuspension:(BOOL)arg0 duration:(double)arg1 startTime:(double)arg2 scale:(float)arg3 {
+    if (hud_ == nil)
+        [super _animateSuspension:arg0 duration:arg1 startTime:arg2 scale:arg3];
+}
+
+- (void) _setSuspended:(BOOL)value {
+    if (hud_ == nil)
+        [super _setSuspended:value];
+}
+
+- (UIProgressHUD *) addProgressHUD {
+    UIProgressHUD *hud([[[UIProgressHUD alloc] initWithWindow:window_] autorelease]);
+    [hud setAutoresizingMask:UIViewAutoresizingFlexibleBoth];
+
+    [window_ setUserInteractionEnabled:NO];
+    [hud show:YES];
+    [[container_ view] addSubview:hud];
+    return hud;
+}
+
+- (void) removeProgressHUD:(UIProgressHUD *)hud {
+    [hud show:NO];
+    [hud removeFromSuperview];
+    [window_ setUserInteractionEnabled:YES];
+}
+
+- (CYViewController *) pageForPackage:(NSString *)name {
+    if (Package *package = [database_ packageWithName:name]) {
+        PackageController *view([self packageController]);
+        [view setPackage:package];
+        return view;
+    } else {
+        NSURL *url([NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"unknown" ofType:@"html"]]);
+        url = [NSURL URLWithString:[[url absoluteString] stringByAppendingString:[NSString stringWithFormat:@"?%@", name]]];
+        return [self _pageForURL:url withClass:[CYBrowserController class]];
+    }
+}
+
+- (CYViewController *) pageForURL:(NSURL *)url hasTag:(int *)tag {
+    if (tag != NULL)
+        *tag = -1;
+
+    NSString *href([url absoluteString]);
+    if ([href hasPrefix:@"apptapp://package/"])
+        return [self pageForPackage:[href substringFromIndex:18]];
+
+    NSString *scheme([[url scheme] lowercaseString]);
+    if (![scheme isEqualToString:@"cydia"])
+        return nil;
+    NSString *path([url absoluteString]);
+    if ([path length] < 8)
+        return nil;
+    path = [path substringFromIndex:8];
+    if (![path hasPrefix:@"/"])
+        path = [@"/" stringByAppendingString:path];
+
+    if ([path isEqualToString:@"/add-source"])
+        return [[[AddSourceController alloc] initWithDatabase:database_] autorelease];
+    else if ([path isEqualToString:@"/storage"])
+        return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[CYBrowserController class]];
+    else if ([path isEqualToString:@"/sources"])
+        return [[[SourceTable alloc] initWithDatabase:database_] autorelease];
+    else if ([path isEqualToString:@"/packages"])
+        return [[[InstalledController alloc] initWithDatabase:database_] autorelease];
+    else if ([path hasPrefix:@"/url/"])
+        return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[CYBrowserController class]];
+    else if ([path hasPrefix:@"/launch/"])
+        [self launchApplicationWithIdentifier:[path substringFromIndex:8] suspended:NO];
+    else if ([path hasPrefix:@"/package-settings/"])
+        return [[[SettingsController alloc] initWithDatabase:database_ package:[path substringFromIndex:18]] autorelease];
+    else if ([path hasPrefix:@"/package-signature/"])
+        return [[[SignatureController alloc] initWithDatabase:database_ package:[path substringFromIndex:19]] autorelease];
+    else if ([path hasPrefix:@"/package/"])
+        return [self pageForPackage:[path substringFromIndex:9]];
+    else if ([path hasPrefix:@"/files/"]) {
+        NSString *name = [path substringFromIndex:7];
+
+        if (Package *package = [database_ packageWithName:name]) {
+            FileTable *files = [[[FileTable alloc] initWithDatabase:database_] autorelease];
+            [files setPackage:package];
+            return files;
+        }
+    }
+
+    return nil;
+}
+
+- (void) applicationOpenURL:(NSURL *)url {
+    [super applicationOpenURL:url];
+    int tag;
+    if (CYViewController *page = [self pageForURL:url hasTag:&tag]) {
+        [self setPage:page];
+        tag_ = tag;
+        [tabbar_ setSelectedViewController:(tag_ == -1 ? nil : [[tabbar_ viewControllers] objectAtIndex:tag_])];
+    }
+}
+
+- (void) applicationWillResignActive:(UIApplication *)application {
+    // Stop refreshing if you get a phone call or lock the device.
+    if ([container_ updating]) [container_ cancelUpdate];
+
+    if ([[self superclass] instancesRespondToSelector:@selector(applicationWillResignActive:)])
+        [super applicationWillResignActive:application];
+}
+
+- (void) applicationDidFinishLaunching:(id)unused {
+    [CYBrowserController _initialize];
+
+    [NSURLProtocol registerClass:[CydiaURLProtocol class]];
+
+    Font12_ = [[UIFont systemFontOfSize:12] retain];
+    Font12Bold_ = [[UIFont boldSystemFontOfSize:12] retain];
+    Font14_ = [[UIFont systemFontOfSize:14] retain];
+    Font18Bold_ = [[UIFont boldSystemFontOfSize:18] retain];
+    Font22Bold_ = [[UIFont boldSystemFontOfSize:22] retain];
+
+    tag_ = 0;
+
+    essential_ = [[NSMutableArray alloc] initWithCapacity:4];
+    broken_ = [[NSMutableArray alloc] initWithCapacity:4];
+
+    UIScreen *screen([UIScreen mainScreen]);
+
+    window_ = [[UIWindow alloc] initWithFrame:[screen bounds]];
+    [window_ orderFront:self];
+    [window_ makeKey:self];
+    [window_ setHidden:NO];
+
+    database_ = [Database sharedInstance];
+
+    if (
+        readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
+        //readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL ||
+        //readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL ||
+        false
+    ) {
+        [self setIdleTimerDisabled:YES];
+
+        hud_ = [self addProgressHUD];
+        [hud_ setText:@"Reorganizing:\n\nWill Automatically\nClose When Done"];
+        [self setStatusBarShowsProgress:YES];
+
+        [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
+
+        [self setStatusBarShowsProgress:NO];
+        [self removeProgressHUD:hud_];
+        hud_ = nil;
+
+        if (ExecFork() == 0) {
+            execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL);
+            perror("launchctl stop");
+        }
+
+        return;
+    }
+
+    _trace();
+
+    NSMutableArray *items([NSMutableArray arrayWithObjects:
+        [[[UITabBarItem alloc] initWithTitle:@"Cydia" image:[UIImage applicationImageNamed:@"home.png"] tag:kCydiaTag] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SECTIONS") image:[UIImage applicationImageNamed:@"install.png"] tag:kSectionsTag] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("CHANGES") image:[UIImage applicationImageNamed:@"changes.png"] tag:kChangesTag] autorelease],
+        [[[UITabBarItem alloc] initWithTitle:UCLocalize("SEARCH") image:[UIImage applicationImageNamed:@"search.png"] tag:kSearchTag] autorelease],
+    nil]);
+
+    if (IsWildcat_) {
+        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("SOURCES") image:[UIImage applicationImageNamed:@"source.png"] tag:kSourcesTag] autorelease] atIndex:3];
+        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("INSTALLED") image:[UIImage applicationImageNamed:@"manage.png"] tag:kInstalledTag] autorelease] atIndex:3];
+    } else {
+        [items insertObject:[[[UITabBarItem alloc] initWithTitle:UCLocalize("MANAGE") image:[UIImage applicationImageNamed:@"manage.png"] tag:kManageTag] autorelease] atIndex:3];
+    }
+
+    NSMutableArray *controllers([NSMutableArray array]);
+
+    for (UITabBarItem *item in items) {
+        CYNavigationController *controller([[[CYNavigationController alloc] initWithDatabase:database_] autorelease]);
+        [controller setTabBarItem:item];
+        [controllers addObject:controller];
+    }
+
+    tabbar_ = [[CYTabBarController alloc] initWithDatabase:database_];
+    [tabbar_ setViewControllers:controllers];
+    [tabbar_ setDelegate:self];
+    [tabbar_ setSelectedIndex:0];
+
+    container_ = [[CYContainer alloc] initWithDatabase:database_];
+    [container_ setUpdateDelegate:self];
+    [container_ setTabBarController:tabbar_];
+    [window_ addSubview:[container_ view]];
+
+    [self performSelector:@selector(loadData) withObject:nil afterDelay:0];
+}
+
+- (void) loadData {
+    if (Role_ == nil) {
+        [self showSettings];
+        return;
+    }
+
+    [UIKeyboard initImplementationNow];
+
+    [self reloadData];
+
+#if RecyclePackageViews
+    details_ = [[NSMutableArray alloc] initWithCapacity:4];
+    [details_ addObject:[self _packageController]];
+    [details_ addObject:[self _packageController]];
+#endif
+
+    PrintTimes();
+
+    _setHomePage(self);
+}
+
+- (void) showActionSheet:(UIActionSheet *)sheet fromItem:(UIBarButtonItem *)item {
+    if (item != nil && IsWildcat_) {
+        [sheet showFromBarButtonItem:item animated:YES];
+    } else {
+        [sheet showInView:window_];
+    }
+}
+
+@end
+
+/*IMP alloc_;
+id Alloc_(id self, SEL selector) {
+    id object = alloc_(self, selector);
+    lprintf("[%s]A-%p\n", self->isa->name, object);
+    return object;
+}*/
+
+/*IMP dealloc_;
+id Dealloc_(id self, SEL selector) {
+    id object = dealloc_(self, selector);
+    lprintf("[%s]D-%p\n", self->isa->name, object);
+    return object;
+}*/
+
+Class $WebDefaultUIKitDelegate;
+
+MSHook(void, UIWebDocumentView$_setUIKitDelegate$, UIWebDocumentView *self, SEL _cmd, id delegate) {
+    if (delegate == nil && $WebDefaultUIKitDelegate != nil)
+        delegate = [$WebDefaultUIKitDelegate sharedUIKitDelegate];
+    return _UIWebDocumentView$_setUIKitDelegate$(self, _cmd, delegate);
+}
+
+static NSNumber *shouldPlayKeyboardSounds;
+
+Class $UIHardware;
+
+MSHook(void, UIHardware$_playSystemSound$, Class self, SEL _cmd, int sound) {
+    switch (sound) {
+        case 1104: // Keyboard Button Clicked
+        case 1105: // Keyboard Delete Repeated
+            if (shouldPlayKeyboardSounds == nil) {
+                NSDictionary *dict([[[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.apple.preferences.sounds.plist"] autorelease]);
+                shouldPlayKeyboardSounds = [([dict objectForKey:@"keyboard"] ?: (id) kCFBooleanTrue) retain];
+            }
+
+            if (![shouldPlayKeyboardSounds boolValue])
+                break;
+
+        default:
+            _UIHardware$_playSystemSound$(self, _cmd, sound);
+    }
+}
+
+int main(int argc, char *argv[]) { _pooled
+    _trace();
+
+    if (Class $UIDevice = objc_getClass("UIDevice")) {
+        UIDevice *device([$UIDevice currentDevice]);
+        IsWildcat_ = [device respondsToSelector:@selector(isWildcat)] && [device isWildcat];
+    } else
+        IsWildcat_ = false;
+
+    PackageName = reinterpret_cast<CYString &(*)(Package *, SEL)>(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname))));
+
+    /* Library Hacks {{{ */
+    class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
+
+    $WebDefaultUIKitDelegate = objc_getClass("WebDefaultUIKitDelegate");
+    Method UIWebDocumentView$_setUIKitDelegate$(class_getInstanceMethod([WebView class], @selector(_setUIKitDelegate:)));
+    if (UIWebDocumentView$_setUIKitDelegate$ != NULL) {
+        _UIWebDocumentView$_setUIKitDelegate$ = reinterpret_cast<void (*)(UIWebDocumentView *, SEL, id)>(method_getImplementation(UIWebDocumentView$_setUIKitDelegate$));
+        method_setImplementation(UIWebDocumentView$_setUIKitDelegate$, reinterpret_cast<IMP>(&$UIWebDocumentView$_setUIKitDelegate$));
+    }
+
+    $UIHardware = objc_getClass("UIHardware");
+    Method UIHardware$_playSystemSound$(class_getClassMethod($UIHardware, @selector(_playSystemSound:)));
+    if (UIHardware$_playSystemSound$ != NULL) {
+        _UIHardware$_playSystemSound$ = reinterpret_cast<void (*)(Class, SEL, int)>(method_getImplementation(UIHardware$_playSystemSound$));
+        method_setImplementation(UIHardware$_playSystemSound$, reinterpret_cast<IMP>(&$UIHardware$_playSystemSound$));
+    }
+    /* }}} */
+    /* Set Locale {{{ */
+    Locale_ = CFLocaleCopyCurrent();
+    Languages_ = [NSLocale preferredLanguages];
+    //CFStringRef locale(CFLocaleGetIdentifier(Locale_));
+    //NSLog(@"%@", [Languages_ description]);
+
+    const char *lang;
+    if (Languages_ == nil || [Languages_ count] == 0)
+        // XXX: consider just setting to C and then falling through?
+        lang = NULL;
+    else {
+        lang = [[Languages_ objectAtIndex:0] UTF8String];
+        setenv("LANG", lang, true);
+    }
+
+    //std::setlocale(LC_ALL, lang);
+    NSLog(@"Setting Language: %s", lang);
+    /* }}} */
+
+    apr_app_initialize(&argc, const_cast<const char * const **>(&argv), NULL);
+
+    /* Parse Arguments {{{ */
+    bool substrate(false);
+
+    if (argc != 0) {
+        char **args(argv);
+        int arge(1);
+
+        for (int argi(1); argi != argc; ++argi)
+            if (strcmp(argv[argi], "--") == 0) {
+                arge = argi;
+                argv[argi] = argv[0];
+                argv += argi;
+                argc -= argi;
+                break;
+            }
+
+        for (int argi(1); argi != arge; ++argi)
+            if (strcmp(args[argi], "--substrate") == 0)
+                substrate = true;
+            else
+                fprintf(stderr, "unknown argument: %s\n", args[argi]);
+    }
+    /* }}} */
+
+    App_ = [[NSBundle mainBundle] bundlePath];
+    Home_ = NSHomeDirectory();
+    Advanced_ = YES;
+
+    setuid(0);
+    setgid(0);
+
+    /*Method alloc = class_getClassMethod([NSObject class], @selector(alloc));
+    alloc_ = alloc->method_imp;
+    alloc->method_imp = (IMP) &Alloc_;*/
+
+    /*Method dealloc = class_getClassMethod([NSObject class], @selector(dealloc));
+    dealloc_ = dealloc->method_imp;
+    dealloc->method_imp = (IMP) &Dealloc_;*/
+
+    /* System Information {{{ */
+    size_t size;
+
+    int maxproc;
+    size = sizeof(maxproc);
+    if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1)
+        perror("sysctlbyname(\"kern.maxproc\", ?)");
+    else if (maxproc < 64) {
+        maxproc = 64;
+        if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc, sizeof(maxproc)) == -1)
+            perror("sysctlbyname(\"kern.maxproc\", #)");
+    }
+
+    sysctlbyname("kern.osversion", NULL, &size, NULL, 0);
+    char *osversion = new char[size];
+    if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) == -1)
+        perror("sysctlbyname(\"kern.osversion\", ?)");
+    else
+        System_ = [NSString stringWithUTF8String:osversion];
+
+    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+    char *machine = new char[size];
+    if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1)
+        perror("sysctlbyname(\"hw.machine\", ?)");
+    else
+        Machine_ = machine;
+
+    if (CFMutableDictionaryRef dict = IOServiceMatching("IOPlatformExpertDevice")) {
+        if (io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, dict)) {
+            if (CFTypeRef serial = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)) {
+                SerialNumber_ = [NSString stringWithString:(NSString *)serial];
+                CFRelease(serial);
+            }
+
+            if (CFTypeRef ecid = IORegistryEntrySearchCFProperty(service, kIODeviceTreePlane, CFSTR("unique-chip-id"), kCFAllocatorDefault, kIORegistryIterateRecursively)) {
+                NSData *data((NSData *) ecid);
+                size_t length([data length]);
+                uint8_t bytes[length];
+                [data getBytes:bytes];
+                char string[length * 2 + 1];
+                for (size_t i(0); i != length; ++i)
+                    sprintf(string + i * 2, "%.2X", bytes[length - i - 1]);
+                ChipID_ = [NSString stringWithUTF8String:string];
+                CFRelease(ecid);
+            }
+
+            IOObjectRelease(service);
+        }
+    }
+
+    UniqueID_ = [[UIDevice currentDevice] uniqueIdentifier];
+
+    if (NSDictionary *system = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"])
+        Build_ = [system objectForKey:@"ProductBuildVersion"];
+    if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:@"/Applications/MobileSafari.app/Info.plist"]) {
+        Product_ = [info objectForKey:@"SafariProductVersion"];
+        Safari_ = [info objectForKey:@"CFBundleVersion"];
+    }
+    /* }}} */
+    /* Load Database {{{ */
+    _trace();
+    Metadata_ = [[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease];
+    _trace();
+    SectionMap_ = [[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Sections" ofType:@"plist"]] autorelease];
+    _trace();
+
+    if (Metadata_ == NULL)
+        Metadata_ = [NSMutableDictionary dictionaryWithCapacity:2];
+    else {
+        Settings_ = [Metadata_ objectForKey:@"Settings"];
+
+        Packages_ = [Metadata_ objectForKey:@"Packages"];
+        Sections_ = [Metadata_ objectForKey:@"Sections"];
+        Sources_ = [Metadata_ objectForKey:@"Sources"];
+
+        Token_ = [Metadata_ objectForKey:@"Token"];
+    }
+
+    if (Settings_ != nil)
+        Role_ = [Settings_ objectForKey:@"Role"];
+
+    if (Packages_ == nil) {
+        Packages_ = [[[NSMutableDictionary alloc] initWithCapacity:128] autorelease];
+        [Metadata_ setObject:Packages_ forKey:@"Packages"];
+    }
+
+    if (Sections_ == nil) {
+        Sections_ = [[[NSMutableDictionary alloc] initWithCapacity:32] autorelease];
+        [Metadata_ setObject:Sections_ forKey:@"Sections"];
+    }
+
+    if (Sources_ == nil) {
+        Sources_ = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
+        [Metadata_ setObject:Sources_ forKey:@"Sources"];
+    }
+    /* }}} */
+
+#if RecycleWebViews
+    Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease];
+#endif
+
+    Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil];
+
+    if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", F_OK) == 0)
+        dlopen("/Library/MobileSubstrate/DynamicLibraries/SimulatedKeyEvents.dylib", RTLD_LAZY | RTLD_GLOBAL);
+    if (substrate && access("/Applications/WinterBoard.app/WinterBoard.dylib", F_OK) == 0)
+        dlopen("/Applications/WinterBoard.app/WinterBoard.dylib", RTLD_LAZY | RTLD_GLOBAL);
+    /*if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0)
+        dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL);*/
+
+    int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]);
+
+    if (access("/tmp/.cydia.fw", F_OK) == 0) {
+        unlink("/tmp/.cydia.fw");
+        goto firmware;
+    } else if (access("/User", F_OK) != 0 || version < 2) {
+      firmware:
+        _trace();
+        system("/usr/libexec/cydia/firmware.sh");
+        _trace();
+    }
+
+    _assert([[NSFileManager defaultManager]
+        createDirectoryAtPath:@"/var/cache/apt/archives/partial"
+        withIntermediateDirectories:YES
+        attributes:nil
+        error:NULL
+    ]);
+
+    if (access("/tmp/cydia.chk", F_OK) == 0) {
+        if (unlink("/var/cache/apt/pkgcache.bin") == -1)
+            _assert(errno == ENOENT);
+        if (unlink("/var/cache/apt/srcpkgcache.bin") == -1)
+            _assert(errno == ENOENT);
+    }
+
+    /* APT Initialization {{{ */
+    _assert(pkgInitConfig(*_config));
+    _assert(pkgInitSystem(*_config, _system));
+
+    if (lang != NULL)
+        _config->Set("APT::Acquire::Translation", lang);
+    _config->Set("Acquire::http::Timeout", 15);
+    _config->Set("Acquire::http::MaxParallel", 3);
+    /* }}} */
+    /* Color Choices {{{ */
+    space_ = CGColorSpaceCreateDeviceRGB();
+
+    Blue_.Set(space_, 0.2, 0.2, 1.0, 1.0);
+    Blueish_.Set(space_, 0x19/255.f, 0x32/255.f, 0x50/255.f, 1.0);
+    Black_.Set(space_, 0.0, 0.0, 0.0, 1.0);
+    Off_.Set(space_, 0.9, 0.9, 0.9, 1.0);
+    White_.Set(space_, 1.0, 1.0, 1.0, 1.0);
+    Gray_.Set(space_, 0.4, 0.4, 0.4, 1.0);
+    Green_.Set(space_, 0.0, 0.5, 0.0, 1.0);
+    Purple_.Set(space_, 0.0, 0.0, 0.7, 1.0);
+    Purplish_.Set(space_, 0.4, 0.4, 0.8, 1.0);
+
+    InstallingColor_ = [UIColor colorWithRed:0.88f green:1.00f blue:0.88f alpha:1.00f];
+    RemovingColor_ = [UIColor colorWithRed:1.00f green:0.88f blue:0.88f alpha:1.00f];
+    /* }}}*/
+    /* UIKit Configuration {{{ */
+    void (*$GSFontSetUseLegacyFontMetrics)(BOOL)(reinterpret_cast<void (*)(BOOL)>(dlsym(RTLD_DEFAULT, "GSFontSetUseLegacyFontMetrics")));
+    if ($GSFontSetUseLegacyFontMetrics != NULL)
+        $GSFontSetUseLegacyFontMetrics(YES);
+
+    // XXX: I have a feeling this was important
+    //UIKeyboardDisableAutomaticAppearance();
+    /* }}} */
+
+    Colon_ = UCLocalize("COLON_DELIMITED");
+    Error_ = UCLocalize("ERROR");
+    Warning_ = UCLocalize("WARNING");
+
+    _trace();
+    int value(UIApplicationMain(argc, argv, @"Cydia", @"Cydia"));
+
+    CGColorSpaceRelease(space_);
+    CFRelease(Locale_);
+
+    return value;
+}
index 3898b49c99a4b49c849f0d6b9e51a50b09a0e93d..52bb5db50fc89d11c08f982a9df7747f32af0ab3 100644 (file)
--- a/makefile
+++ b/makefile
@@ -29,7 +29,6 @@ link += -framework IOKit
 link += -framework JavaScriptCore
 link += -framework QuartzCore
 link += -framework SystemConfiguration
 link += -framework JavaScriptCore
 link += -framework QuartzCore
 link += -framework SystemConfiguration
-link += -framework UIKit
 link += -framework WebCore
 link += -framework WebKit
 
 link += -framework WebCore
 link += -framework WebKit
 
@@ -39,20 +38,29 @@ link += -lpcre
 
 link += -multiply_defined suppress
 
 
 link += -multiply_defined suppress
 
+uikit := 
+uikit += -framework UIKit
+
+backrow := 
+backrow += -FAppleTV -framework BackRow -framework AppleTV
+
 #cycc = cycc -r4.2 -i$(ios) -o$@
 gxx := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-$(gcc)
 cycc = $(gxx) -arch armv6 -o $@ -mcpu=arm1176jzf-s -miphoneos-version-min=$(ios) -isysroot $(sdk) -idirafter /usr/include -F/Library/Frameworks
 
 #cycc = cycc -r4.2 -i$(ios) -o$@
 gxx := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-$(gcc)
 cycc = $(gxx) -arch armv6 -o $@ -mcpu=arm1176jzf-s -miphoneos-version-min=$(ios) -isysroot $(sdk) -idirafter /usr/include -F/Library/Frameworks
 
-all: Cydia
+all: MobileCydia
 
 clean:
 
 clean:
-       rm -f Cydia
+       rm -f MobileCydia
 
 
-Cydia: Cydia.mm UICaboodle/*.mm iPhonePrivate.h
-       $(cycc) $(filter %.mm,$^) $(flags) $(link)
+MobileCydia: MobileCydia.mm UICaboodle/*.mm iPhonePrivate.h
+       $(cycc) $(filter %.mm,$^) $(flags) $(link) $(uikit)
        ldid -Slaunch.xml $@
 
        ldid -Slaunch.xml $@
 
-package: Cydia
+CydiaAppliance: CydiaAppliance.mm
+       $(cycc) $(filter %.mm,$^) $(flags) -bundle $(link) $(backrow)
+
+package: MobileCydia
        sudo rm -rf _
        mkdir -p _/var/lib/cydia
        
        sudo rm -rf _
        mkdir -p _/var/lib/cydia
        
@@ -64,8 +72,12 @@ package: Cydia
        cp -a LaunchDaemons _/System/Library/LaunchDaemons
        
        mkdir -p _/Applications
        cp -a LaunchDaemons _/System/Library/LaunchDaemons
        
        mkdir -p _/Applications
-       cp -a Cydia.app _/Applications/Cydia.app
-       cp -a Cydia _/Applications/Cydia.app/Cydia_
+       cp -a MobileCydia.app _/Applications/Cydia.app
+       cp -a MobileCydia _/Applications/Cydia.app/MobileCydia
+       
+       #mkdir -p _/Applications/Lowtide.app/Appliances
+       #cp -a Cydia.frappliance _/Applications/Lowtide.app/Appliances
+       #cp -a CydiaAppliance _/Applications/Lowtide.app/Appliances/Cydia.frappliance
        
        mkdir -p _/System/Library/PreferenceBundles
        cp -a CydiaSettings.bundle _/System/Library/PreferenceBundles/CydiaSettings.bundle
        
        mkdir -p _/System/Library/PreferenceBundles
        cp -a CydiaSettings.bundle _/System/Library/PreferenceBundles/CydiaSettings.bundle
@@ -75,7 +87,7 @@ package: Cydia
        
        sudo chown -R 0 _
        sudo chgrp -R 0 _
        
        sudo chown -R 0 _
        sudo chgrp -R 0 _
-       sudo chmod 6755 _/Applications/Cydia.app/Cydia_
+       sudo chmod 6755 _/Applications/Cydia.app/MobileCydia
        
        $(dpkg) -b _ $(shell grep ^Package: control | cut -d ' ' -f 2-)_$(shell grep ^Version: control | cut -d ' ' -f 2)_iphoneos-arm.deb
 
        
        $(dpkg) -b _ $(shell grep ^Package: control | cut -d ' ' -f 2-)_$(shell grep ^Version: control | cut -d ' ' -f 2)_iphoneos-arm.deb