]> git.mxchange.org Git - friendica.git/commitdiff
Merge branch 'omigeot-master'
authorFriendika <info@friendika.com>
Sat, 5 Feb 2011 21:01:28 +0000 (13:01 -0800)
committerFriendika <info@friendika.com>
Sat, 5 Feb 2011 21:01:28 +0000 (13:01 -0800)
Conflicts:
view/fr/strings.php

203 files changed:
INSTALL.txt
addon/README
addon/java_upload/java_upload.php [new file with mode: 0644]
addon/java_upload/jumploader_z.jar [new file with mode: 0644]
addon/js_upload/file-uploader/client/demo.htm [new file with mode: 0644]
addon/js_upload/file-uploader/client/do-nothing.htm [new file with mode: 0644]
addon/js_upload/file-uploader/client/fileuploader.css [new file with mode: 0644]
addon/js_upload/file-uploader/client/fileuploader.js [new file with mode: 0644]
addon/js_upload/file-uploader/client/loading.gif [new file with mode: 0644]
addon/js_upload/file-uploader/gpl-2.0.txt [new file with mode: 0644]
addon/js_upload/file-uploader/license.txt [new file with mode: 0644]
addon/js_upload/file-uploader/readme.md [new file with mode: 0644]
addon/js_upload/file-uploader/server/OctetStreamReader.java [new file with mode: 0644]
addon/js_upload/file-uploader/server/coldfusion/coldfusion.cfc [new file with mode: 0644]
addon/js_upload/file-uploader/server/coldfusion/demo.cfm [new file with mode: 0644]
addon/js_upload/file-uploader/server/coldfusion/readme.txt [new file with mode: 0644]
addon/js_upload/file-uploader/server/perl.cgi [new file with mode: 0644]
addon/js_upload/file-uploader/server/php.php [new file with mode: 0644]
addon/js_upload/file-uploader/server/readme.txt [new file with mode: 0644]
addon/js_upload/file-uploader/server/uploads/.gitignore [new file with mode: 0644]
addon/js_upload/file-uploader/tests/action-acceptance.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/action-handler-queue-test.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/action-handler-test.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/action-slow-response.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/browser-bugs/safari-bug1.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/browser-bugs/safari-bug2.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/application-javascript.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/application-json.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/header-404.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/somepage.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/text-html-large.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/text-html.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/text-javascript.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/iframe-content-tests/text-plain.php [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-1.4.2.min.js [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/jquery-ui-1.8.4.custom.min.js [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_flat_10_000000_40x100.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_222222_256x240.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_228ef1_256x240.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ef8c08_256x240.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffd27a_256x240.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffffff_256x240.png [new file with mode: 0644]
addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/package.json [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/qunit/qunit.css [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/qunit/qunit.js [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/test/index.html [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/test/same.js [new file with mode: 0644]
addon/js_upload/file-uploader/tests/qunit/test/test.js [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/1imagelonglonglonglonglonglongname.gif [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/2larger.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/3empty.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/4text.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/5text.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/6text.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/7small.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/sample-files/8text.txt [new file with mode: 0644]
addon/js_upload/file-uploader/tests/separate-file-list.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/test-acceptance.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/test-drop-zone.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/test-handler-queue.htm [new file with mode: 0644]
addon/js_upload/file-uploader/tests/test-upload-handlers.htm [new file with mode: 0644]
addon/js_upload/js_upload.php [new file with mode: 0644]
addon/oembed/oembed.js [new file with mode: 0644]
addon/oembed/oembed.php [new file with mode: 0644]
addon/oembed/oembed.png [new file with mode: 0644]
addon/piwik/piwik.css [new file with mode: 0644]
addon/piwik/piwik.php [new file with mode: 0644]
addon/poormancron/poormancron.php [new file with mode: 0644]
boot.php
database.sql
htconfig.php
images/document.gif [new file with mode: 0644]
images/people.gif [new file with mode: 0644]
include/Contact.php
include/Scrape.php
include/acl_selectors.php
include/bbcode.php
include/directory.php
include/html2bbcode.php
include/items.php
include/main.js
include/notifier.php
include/oembed.php [new file with mode: 0644]
include/poller.php
include/queue.php
include/salmon.php
index.php
jumploader_z.jar [deleted file]
mod/contacts.php
mod/dfrn_confirm.php
mod/dfrn_notify.php
mod/dfrn_poll.php
mod/display.php
mod/follow.php
mod/invite.php
mod/item.php
mod/like.php
mod/lockview.php
mod/message.php
mod/network.php
mod/photos.php
mod/profile.php
mod/profile_photo.php
mod/profiles.php
mod/removeme.php [new file with mode: 0644]
mod/settings.php
mod/viewcontacts.php
tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js
tinymce/jscripts/tiny_mce/themes/advanced/langs/en.js
tinymce/jscripts/tiny_mce/themes/advanced/langs/en_dlg.js
tinymce/jscripts/tiny_mce/themes/advanced/skins/default/content.css
update.php
util/extract.php
util/string_translator.php [new file with mode: 0644]
util/strings.php
view/de/cmnt_received_eml.tpl [new file with mode: 0644]
view/de/contact_edit.tpl [new file with mode: 0644]
view/de/cropbody.tpl [new file with mode: 0644]
view/de/dfrn_req_confirm.tpl [new file with mode: 0644]
view/de/directory_header.tpl [new file with mode: 0644]
view/de/follow_notify_eml.tpl [new file with mode: 0644]
view/de/friend_complete_eml.tpl [new file with mode: 0644]
view/de/group_edit.tpl [new file with mode: 0644]
view/de/group_new.tpl [new file with mode: 0644]
view/de/head.tpl [new file with mode: 0644]
view/de/htconfig.tpl [new file with mode: 0644]
view/de/insecure_net.tpl [new file with mode: 0644]
view/de/install_db.tpl [new file with mode: 0644]
view/de/intro_complete_eml.tpl [new file with mode: 0644]
view/de/intros-top.tpl [new file with mode: 0644]
view/de/jot-header.tpl [new file with mode: 0644]
view/de/jot.tpl [new file with mode: 0644]
view/de/like.tpl [new file with mode: 0644]
view/de/logout.tpl [new file with mode: 0644]
view/de/lostpass.tpl [new file with mode: 0644]
view/de/lostpass_eml.tpl [new file with mode: 0644]
view/de/mail_received_eml.tpl [new file with mode: 0644]
view/de/msg-header.tpl [new file with mode: 0644]
view/de/netfriend.tpl [new file with mode: 0644]
view/de/pagetypes.tpl [new file with mode: 0644]
view/de/passchanged_eml.tpl [new file with mode: 0644]
view/de/profile-hide-friends.tpl [new file with mode: 0644]
view/de/profile-in-directory.tpl [new file with mode: 0644]
view/de/profile-in-netdir.tpl [new file with mode: 0644]
view/de/profile.php [new file with mode: 0644]
view/de/profile_advanced.php [new file with mode: 0644]
view/de/profile_edit.tpl [new file with mode: 0644]
view/de/profile_entry_default.tpl [new file with mode: 0644]
view/de/profile_listing_header.tpl [new file with mode: 0644]
view/de/profile_photo.tpl [new file with mode: 0644]
view/de/profile_tabs.tpl [new file with mode: 0644]
view/de/pwdreset.tpl [new file with mode: 0644]
view/de/register-link.tpl [new file with mode: 0644]
view/de/register_open_eml.tpl [new file with mode: 0644]
view/de/register_verify_eml.tpl [new file with mode: 0644]
view/de/registrations-top.tpl [new file with mode: 0644]
view/de/request_notify_eml.tpl [new file with mode: 0644]
view/de/settings.tpl [new file with mode: 0644]
view/de/settings_nick_set.tpl [new file with mode: 0644]
view/de/settings_nick_subdir.tpl [new file with mode: 0644]
view/de/settings_nick_unset.tpl [new file with mode: 0644]
view/de/strings.php [new file with mode: 0644]
view/de/wall_item_drop.tpl [new file with mode: 0644]
view/de/wall_received_eml.tpl [new file with mode: 0644]
view/de/wallwall_item.tpl [new file with mode: 0644]
view/en/contact_edit.tpl
view/en/htconfig.tpl
view/en/jot-header.tpl
view/en/jot.tpl
view/en/settings.tpl
view/fr/contact_edit.tpl
view/fr/jot-header.tpl
view/fr/jot.tpl
view/fr/profile_advanced.php
view/fr/settings.tpl
view/it/contact_edit.tpl
view/it/jot-header.tpl
view/it/jot.tpl
view/it/profile_photo.tpl
view/it/settings.tpl
view/it/strings.php
view/photo_edit.tpl
view/photos_upload.tpl
view/removeme.tpl [new file with mode: 0644]
view/theme/default/style.css
view/theme/duepuntozero/style.css
view/theme/greenzero/border.jpg [new file with mode: 0644]
view/theme/greenzero/head.jpg [new file with mode: 0644]
view/theme/greenzero/shiny.png [new file with mode: 0644]
view/theme/greenzero/style.css [new file with mode: 0644]
view/theme/purplezero/border.jpg [new file with mode: 0644]
view/theme/purplezero/head.jpg [new file with mode: 0644]
view/theme/purplezero/shiny.png [new file with mode: 0644]
view/theme/purplezero/style.css [new file with mode: 0644]

index 70e4f24efdee8e44259cce5ed37606ebad91d5d2..85114dee50eb0a7987d357d73df7ad1e9539536a 100644 (file)
@@ -12,6 +12,11 @@ blog. Not every PHP/MySQL hosting provider will be able to support Friendika.
 Many will. But please review the requirements and confirm these with your 
 hosting provider prior to installation.
 
+Before you begin: Choose a domain name or subdomain name for your server.
+Put some thought into this - because changing it is currently not-supported.
+Things will break, and some of your friends may have difficulty communicating
+with you. We plan to address this limitation in a future release. 
 
 1. Requirements
        - Apache with mod-rewrite enabled and "Options All" so you can use a 
@@ -29,7 +34,7 @@ php.ini file
        - Mysql 5.x
 
        - ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks
-(Windows)
+(Windows) [Note: other options are presented in Section 7 of this document]
 
        - Installation into a top-level domain or sub-domain (without a 
 directory/path component in the URL) is preferred. Directory paths will
@@ -89,3 +94,18 @@ You can generally find the location of PHP by executing "which php". If you
 have troubles with this section please contact your hosting provider for 
 assistance. Friendika will not work correctly if you cannot perform this step.
   
+Alternative: You may be able to use the 'poormancron' plugin to perform this
+step if you are using a recent Friendika release. To do this, edit the file 
+".htconfig.php" and look for a line describing your plugins. On a fresh 
+installation, it will look like
+
+$a->config['system']['addon'] = 'js_upload';
+
+This indicates the "js_upload" addon module is enabled. You may add additional 
+addons/plugins using this same line in the configuration file. Change it to 
+read
+
+$a->config['system']['addon'] = 'js_upload,poormancron';
+
+and save your changes.
+
index 2e4ed602908512697f011b4feed90653aaf0ae48..fb1c6340a50cf1d4ba1bc3ac0067575840e64a0e 100644 (file)
@@ -156,7 +156,8 @@ Current hooks:
 'page_end' - called after HTML content functions have completed
     $b is (string) HTML of content div
 
-
+'jot_plugin' - add tools to jot toolbar
+  $b is (string) HTML for tool icon
 
 
 *** = subject to change
diff --git a/addon/java_upload/java_upload.php b/addon/java_upload/java_upload.php
new file mode 100644 (file)
index 0000000..8b8a576
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ *
+ * Java photo uploader, uses Jumploader
+ *
+ * WARNING: This module currently has privacy issues.
+ * The java package does not pass the permissions array intact and could lead to
+ * photos being seen by people that were excluded from seeing them.
+ *
+ */
+
+
+function java_upload_install() {
+       register_hook('photo_upload_form', 'addon/java_upload/java_upload.php', 'java_upload_form');
+       register_hook('photo_post_init',   'addon/java_upload/java_upload.php', 'java_upload_post_init');
+       register_hook('photo_post_end',    'addon/java_upload/java_upload.php', 'java_upload_post_end');
+}
+
+
+function java_upload_uninstall() {
+       unregister_hook('photo_upload_form', 'addon/java_upload/java_upload.php', 'java_upload_form');
+       unregister_hook('photo_post_init',   'addon/java_upload/java_upload.php', 'java_upload_post_init');
+       unregister_hook('photo_post_end',    'addon/java_upload/java_upload.php', 'java_upload_post_end');
+}
+
+
+function java_upload_form(&$a,&$b) {
+
+       $uploadurl = $b['post_url'];
+       $sessid = session_id();
+       $archive = $a->get_baseurl() . '/addon/java_upload/jumploader_z.jar';
+       $filestext = t('Select files to upload: ');
+
+       $nojava = t('Use the following controls only if the Java uploader [above] fails to launch.');
+
+       $b['default_upload'] = true;
+
+
+$b['addon_text'] .= <<< EOT
+
+       <div id="photos-upload-select-files-text">$filestext</div>
+
+       <div id="photos_upload_applet_wrapper">
+               <applet name="jumpLoaderApplet"
+                       code="jmaster.jumploader.app.JumpLoaderApplet.class"
+                       archive="$archive"
+                       width="700"
+                       height="600"
+                       mayscript >
+                       <param name="uc_uploadUrl" value="$uploadurl" />
+                       <param name="uc_uploadFormName" value="photos-upload-form" />
+                       <param name="gc_loggingLeveL" value="FATAL" />
+                       <param name="uc_fileParameterName" value="userfile" />
+                       <param name="uc_cookie" value="PHPSESSID=$sessid; path=/;" />
+                       <param name="vc_disableLocalFileSystem" value="false" />
+                       <param name="vc_uploadViewMenuBarVisible" value="false" />
+                       <param name="vc_mainViewFileListViewVisible" value="true" />
+                       <param name="vc_mainViewFileListViewHeightPercent" value="50" />
+                       <param name="vc_mainViewFileTreeViewVisible" value="true" />
+                       <param name="vc_mainViewFileTreeViewWidthPercent" value="35" />
+                       <param name="vc_lookAndFeel" value="system" />
+       
+               </applet>
+               
+       </div>
+
+       <div id="photos-upload-no-java-message" >
+       $nojava
+       </div>  
+
+EOT;
+
+}
+
+
+
+
+
+function java_upload_photo_post_init(&$a,&$b) {
+
+       if($_POST['partitionCount'])
+               $a->data['java_upload'] = true;
+       else
+               $a->data['java_upload'] = false;
+
+
+}
+
+
+function java_upload_photo_post_end(&$a,&$b) {
+
+       if(x($a->data,'java_upload') && $a->data['java_upload'])
+               killme();
+
+}
\ No newline at end of file
diff --git a/addon/java_upload/jumploader_z.jar b/addon/java_upload/jumploader_z.jar
new file mode 100644 (file)
index 0000000..30a85a3
Binary files /dev/null and b/addon/java_upload/jumploader_z.jar differ
diff --git a/addon/js_upload/file-uploader/client/demo.htm b/addon/js_upload/file-uploader/client/demo.htm
new file mode 100644 (file)
index 0000000..2a0cd6d
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+       <link href="fileuploader.css" rel="stylesheet" type="text/css"> 
+    <style>            
+               body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}
+    </style>   
+</head>
+<body>         
+    <p><a href="http://github.com/valums/file-uploader">Back to project page</a></p>
+    
+       <p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>
+       <p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>
+       
+       <div id="file-uploader-demo1">          
+               <noscript>                      
+                       <p>Please enable JavaScript to use file uploader.</p>
+                       <!-- or put a simple form for upload here -->
+               </noscript>         
+       </div>
+    
+    <script src="fileuploader.js" type="text/javascript"></script>
+    <script>        
+        function createUploader(){            
+            var uploader = new qq.FileUploader({
+                element: document.getElementById('file-uploader-demo1'),
+                action: 'do-nothing.htm',
+                debug: true
+            });           
+        }
+        
+        // in your app create uploader as soon as the DOM is ready
+        // don't wait for the window to load  
+        window.onload = createUploader;     
+    </script>    
+</body>
+</html>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/client/do-nothing.htm b/addon/js_upload/file-uploader/client/do-nothing.htm
new file mode 100644 (file)
index 0000000..0da1905
--- /dev/null
@@ -0,0 +1 @@
+{success:true}
diff --git a/addon/js_upload/file-uploader/client/fileuploader.css b/addon/js_upload/file-uploader/client/fileuploader.css
new file mode 100644 (file)
index 0000000..0e3f111
--- /dev/null
@@ -0,0 +1,31 @@
+.qq-uploader { position:relative; width: 100%;}
+
+.qq-upload-button {
+    display:block; /* or inline-block */
+    width: 105px; padding: 7px 0; text-align:center;    
+    background:#880000; border-bottom:1px solid #ddd;color:#fff;
+}
+.qq-upload-button-hover {background:#cc0000;}
+.qq-upload-button-focus {outline:1px dotted black;}
+
+.qq-upload-drop-area {
+    position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
+    background:#FF9797; text-align:center; 
+}
+.qq-upload-drop-area span {
+    display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
+}
+.qq-upload-drop-area-active {background:#FF7171;}
+
+.qq-upload-list {margin:15px 35px; padding:0; list-style:disc;}
+.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px;}
+.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
+    margin-right: 7px;
+}
+
+.qq-upload-file {}
+.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
+.qq-upload-size,.qq-upload-cancel {font-size:11px;}
+
+.qq-upload-failed-text {display:none;}
+.qq-upload-fail .qq-upload-failed-text {display:inline;}
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/client/fileuploader.js b/addon/js_upload/file-uploader/client/fileuploader.js
new file mode 100644 (file)
index 0000000..89c09eb
--- /dev/null
@@ -0,0 +1,1247 @@
+/**
+ * http://github.com/valums/file-uploader
+ * 
+ * Multiple file upload component with progress-bar, drag-and-drop. 
+ * © 2010 Andrew Valums ( andrew(at)valums.com ) 
+ * 
+ * Licensed under GNU GPL 2 or later, see license.txt.
+ */    
+
+//
+// Helper functions
+//
+
+var qq = qq || {};
+
+/**
+ * Adds all missing properties from second obj to first obj
+ */ 
+qq.extend = function(first, second){
+    for (var prop in second){
+        first[prop] = second[prop];
+    }
+};  
+
+/**
+ * Searches for a given element in the array, returns -1 if it is not present.
+ * @param {Number} [from] The index at which to begin the search
+ */
+qq.indexOf = function(arr, elt, from){
+    if (arr.indexOf) return arr.indexOf(elt, from);
+    
+    from = from || 0;
+    var len = arr.length;    
+    
+    if (from < 0) from += len;  
+
+    for (; from < len; from++){  
+        if (from in arr && arr[from] === elt){  
+            return from;
+        }
+    }  
+    return -1;  
+}; 
+    
+qq.getUniqueId = (function(){
+    var id = 0;
+    return function(){ return id++; };
+})();
+
+//
+// Events
+
+qq.attach = function(element, type, fn){
+    if (element.addEventListener){
+        element.addEventListener(type, fn, false);
+    } else if (element.attachEvent){
+        element.attachEvent('on' + type, fn);
+    }
+};
+qq.detach = function(element, type, fn){
+    if (element.removeEventListener){
+        element.removeEventListener(type, fn, false);
+    } else if (element.attachEvent){
+        element.detachEvent('on' + type, fn);
+    }
+};
+
+qq.preventDefault = function(e){
+    if (e.preventDefault){
+        e.preventDefault();
+    } else{
+        e.returnValue = false;
+    }
+};
+
+//
+// Node manipulations
+
+/**
+ * Insert node a before node b.
+ */
+qq.insertBefore = function(a, b){
+    b.parentNode.insertBefore(a, b);
+};
+qq.remove = function(element){
+    element.parentNode.removeChild(element);
+};
+
+qq.contains = function(parent, descendant){       
+    // compareposition returns false in this case
+    if (parent == descendant) return true;
+    
+    if (parent.contains){
+        return parent.contains(descendant);
+    } else {
+        return !!(descendant.compareDocumentPosition(parent) & 8);
+    }
+};
+
+/**
+ * Creates and returns element from html string
+ * Uses innerHTML to create an element
+ */
+qq.toElement = (function(){
+    var div = document.createElement('div');
+    return function(html){
+        div.innerHTML = html;
+        var element = div.firstChild;
+        div.removeChild(element);
+        return element;
+    };
+})();
+
+//
+// Node properties and attributes
+
+/**
+ * Sets styles for an element.
+ * Fixes opacity in IE6-8.
+ */
+qq.css = function(element, styles){
+    if (styles.opacity != null){
+        if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
+            styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
+        }
+    }
+    qq.extend(element.style, styles);
+};
+qq.hasClass = function(element, name){
+    var re = new RegExp('(^| )' + name + '( |$)');
+    return re.test(element.className);
+};
+qq.addClass = function(element, name){
+    if (!qq.hasClass(element, name)){
+        element.className += ' ' + name;
+    }
+};
+qq.removeClass = function(element, name){
+    var re = new RegExp('(^| )' + name + '( |$)');
+    element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
+};
+qq.setText = function(element, text){
+    element.innerText = text;
+    element.textContent = text;
+};
+
+//
+// Selecting elements
+
+qq.children = function(element){
+    var children = [],
+    child = element.firstChild;
+
+    while (child){
+        if (child.nodeType == 1){
+            children.push(child);
+        }
+        child = child.nextSibling;
+    }
+
+    return children;
+};
+
+qq.getByClass = function(element, className){
+    if (element.querySelectorAll){
+        return element.querySelectorAll('.' + className);
+    }
+
+    var result = [];
+    var candidates = element.getElementsByTagName("*");
+    var len = candidates.length;
+
+    for (var i = 0; i < len; i++){
+        if (qq.hasClass(candidates[i], className)){
+            result.push(candidates[i]);
+        }
+    }
+    return result;
+};
+
+/**
+ * obj2url() takes a json-object as argument and generates
+ * a querystring. pretty much like jQuery.param()
+ * 
+ * how to use:
+ *
+ *    `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
+ *
+ * will result in:
+ *
+ *    `http://any.url/upload?otherParam=value&a=b&c=d`
+ *
+ * @param  Object JSON-Object
+ * @param  String current querystring-part
+ * @return String encoded querystring
+ */
+qq.obj2url = function(obj, temp, prefixDone){
+    var uristrings = [],
+        prefix = '&',
+        add = function(nextObj, i){
+            var nextTemp = temp 
+                ? (/\[\]$/.test(temp)) // prevent double-encoding
+                   ? temp
+                   : temp+'['+i+']'
+                : i;
+            if ((nextTemp != 'undefined') && (i != 'undefined')) {  
+                uristrings.push(
+                    (typeof nextObj === 'object') 
+                        ? qq.obj2url(nextObj, nextTemp, true)
+                        : (Object.prototype.toString.call(nextObj) === '[object Function]')
+                            ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
+                            : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)                                                          
+                );
+            }
+        }; 
+
+    if (!prefixDone && temp) {
+      prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
+      uristrings.push(temp);
+      uristrings.push(qq.obj2url(obj));
+    } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
+        // we wont use a for-in-loop on an array (performance)
+        for (var i = 0, len = obj.length; i < len; ++i){
+            add(obj[i], i);
+        }
+    } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
+        // for anything else but a scalar, we will use for-in-loop
+        for (var i in obj){
+            add(obj[i], i);
+        }
+    } else {
+        uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
+    }
+
+    return uristrings.join(prefix)
+                     .replace(/^&/, '')
+                     .replace(/%20/g, '+'); 
+};
+
+//
+//
+// Uploader Classes
+//
+//
+
+var qq = qq || {};
+    
+/**
+ * Creates upload button, validates upload, but doesn't create file list or dd. 
+ */
+qq.FileUploaderBasic = function(o){
+    this._options = {
+        // set to true to see the server response
+        debug: false,
+        action: '/server/upload',
+        params: {},
+        button: null,
+        multiple: true,
+        maxConnections: 3,
+        // validation        
+        allowedExtensions: [],               
+        sizeLimit: 0,   
+        minSizeLimit: 0,                             
+        // events
+        // return false to cancel submit
+        onSubmit: function(id, fileName){},
+        onProgress: function(id, fileName, loaded, total){},
+        onComplete: function(id, fileName, responseJSON){},
+        onCancel: function(id, fileName){},
+        // messages                
+        messages: {
+            typeError: "{file} has invalid extension. Only {extensions} are allowed.",
+            sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
+            minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
+            emptyError: "{file} is empty, please select files again without it.",
+            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."            
+        },
+        showMessage: function(message){
+            alert(message);
+        }               
+    };
+    qq.extend(this._options, o);
+        
+    // number of files being uploaded
+    this._filesInProgress = 0;
+    this._handler = this._createUploadHandler(); 
+    
+    if (this._options.button){ 
+        this._button = this._createUploadButton(this._options.button);
+    }
+                        
+    this._preventLeaveInProgress();         
+};
+   
+qq.FileUploaderBasic.prototype = {
+    setParams: function(params){
+        this._options.params = params;
+    },
+    getInProgress: function(){
+        return this._filesInProgress;         
+    },
+    _createUploadButton: function(element){
+        var self = this;
+        
+        return new qq.UploadButton({
+            element: element,
+            multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
+            onChange: function(input){
+                self._onInputChange(input);
+            }        
+        });           
+    },    
+    _createUploadHandler: function(){
+        var self = this,
+            handlerClass;        
+        
+        if(qq.UploadHandlerXhr.isSupported()){           
+            handlerClass = 'UploadHandlerXhr';                        
+        } else {
+            handlerClass = 'UploadHandlerForm';
+        }
+
+        var handler = new qq[handlerClass]({
+            debug: this._options.debug,
+            action: this._options.action,         
+            maxConnections: this._options.maxConnections,   
+            onProgress: function(id, fileName, loaded, total){                
+                self._onProgress(id, fileName, loaded, total);
+                self._options.onProgress(id, fileName, loaded, total);                    
+            },            
+            onComplete: function(id, fileName, result){
+                self._onComplete(id, fileName, result);
+                self._options.onComplete(id, fileName, result);
+            },
+            onCancel: function(id, fileName){
+                self._onCancel(id, fileName);
+                self._options.onCancel(id, fileName);
+            }
+        });
+
+        return handler;
+    },    
+    _preventLeaveInProgress: function(){
+        var self = this;
+        
+        qq.attach(window, 'beforeunload', function(e){
+            if (!self._filesInProgress){return;}
+            
+            var e = e || window.event;
+            // for ie, ff
+            e.returnValue = self._options.messages.onLeave;
+            // for webkit
+            return self._options.messages.onLeave;             
+        });        
+    },    
+    _onSubmit: function(id, fileName){
+        this._filesInProgress++;  
+    },
+    _onProgress: function(id, fileName, loaded, total){        
+    },
+    _onComplete: function(id, fileName, result){
+        this._filesInProgress--;                 
+        if (result.error){
+            this._options.showMessage(result.error);
+        }             
+    },
+    _onCancel: function(id, fileName){
+        this._filesInProgress--;        
+    },
+    _onInputChange: function(input){
+        if (this._handler instanceof qq.UploadHandlerXhr){                
+            this._uploadFileList(input.files);                   
+        } else {             
+            if (this._validateFile(input)){                
+                this._uploadFile(input);                                    
+            }                      
+        }               
+        this._button.reset();   
+    },  
+    _uploadFileList: function(files){
+        for (var i=0; i<files.length; i++){
+            if ( !this._validateFile(files[i])){
+                return;
+            }            
+        }
+        
+        for (var i=0; i<files.length; i++){
+            this._uploadFile(files[i]);        
+        }        
+    },       
+    _uploadFile: function(fileContainer){      
+        var id = this._handler.add(fileContainer);
+        var fileName = this._handler.getName(id);
+        
+        if (this._options.onSubmit(id, fileName) !== false){
+            this._onSubmit(id, fileName);
+            this._handler.upload(id, this._options.params);
+        }
+    },      
+    _validateFile: function(file){
+        var name, size;
+        
+        if (file.value){
+            // it is a file input            
+            // get input value and remove path to normalize
+            name = file.value.replace(/.*(\/|\\)/, "");
+        } else {
+            // fix missing properties in Safari
+            name = file.fileName != null ? file.fileName : file.name;
+            size = file.fileSize != null ? file.fileSize : file.size;
+        }
+                    
+        if (! this._isAllowedExtension(name)){            
+            this._error('typeError', name);
+            return false;
+            
+        } else if (size === 0){            
+            this._error('emptyError', name);
+            return false;
+                                                     
+        } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){            
+            this._error('sizeError', name);
+            return false;
+                        
+        } else if (size && size < this._options.minSizeLimit){
+            this._error('minSizeError', name);
+            return false;            
+        }
+        
+        return true;                
+    },
+    _error: function(code, fileName){
+        var message = this._options.messages[code];        
+        function r(name, replacement){ message = message.replace(name, replacement); }
+        
+        r('{file}', this._formatFileName(fileName));        
+        r('{extensions}', this._options.allowedExtensions.join(', '));
+        r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
+        r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
+        
+        this._options.showMessage(message);                
+    },
+    _formatFileName: function(name){
+        if (name.length > 33){
+            name = name.slice(0, 19) + '...' + name.slice(-13);    
+        }
+        return name;
+    },
+    _isAllowedExtension: function(fileName){
+        var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
+        var allowed = this._options.allowedExtensions;
+        
+        if (!allowed.length){return true;}        
+        
+        for (var i=0; i<allowed.length; i++){
+            if (allowed[i].toLowerCase() == ext){ return true;}    
+        }
+        
+        return false;
+    },    
+    _formatSize: function(bytes){
+        var i = -1;                                    
+        do {
+            bytes = bytes / 1024;
+            i++;  
+        } while (bytes > 99);
+        
+        return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];          
+    }
+};
+    
+       
+/**
+ * Class that creates upload widget with drag-and-drop and file list
+ * @inherits qq.FileUploaderBasic
+ */
+qq.FileUploader = function(o){
+    // call parent constructor
+    qq.FileUploaderBasic.apply(this, arguments);
+    
+    // additional options    
+    qq.extend(this._options, {
+        element: null,
+        // if set, will be used instead of qq-upload-list in template
+        listElement: null,
+                
+        template: '<div class="qq-uploader">' + 
+                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
+                '<div class="qq-upload-button">Upload a file</div>' +
+                '<ul class="qq-upload-list"></ul>' + 
+             '</div>',
+
+        // template for one item in file list
+        fileTemplate: '<li>' +
+                '<span class="qq-upload-file"></span>' +
+                '<span class="qq-upload-spinner"></span>' +
+                '<span class="qq-upload-size"></span>' +
+                '<a class="qq-upload-cancel" href="#">Cancel</a>' +
+                '<span class="qq-upload-failed-text">Failed</span>' +
+            '</li>',        
+        
+        classes: {
+            // used to get elements from templates
+            button: 'qq-upload-button',
+            drop: 'qq-upload-drop-area',
+            dropActive: 'qq-upload-drop-area-active',
+            list: 'qq-upload-list',
+                        
+            file: 'qq-upload-file',
+            spinner: 'qq-upload-spinner',
+            size: 'qq-upload-size',
+            cancel: 'qq-upload-cancel',
+
+            // added to list item when upload completes
+            // used in css to hide progress spinner
+            success: 'qq-upload-success',
+            fail: 'qq-upload-fail'
+        }
+    });
+    // overwrite options with user supplied    
+    qq.extend(this._options, o);       
+
+    this._element = this._options.element;
+    this._element.innerHTML = this._options.template;        
+    this._listElement = this._options.listElement || this._find(this._element, 'list');
+    
+    this._classes = this._options.classes;
+        
+    this._button = this._createUploadButton(this._find(this._element, 'button'));        
+    
+    this._bindCancelEvent();
+    this._setupDragDrop();
+};
+
+// inherit from Basic Uploader
+qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
+
+qq.extend(qq.FileUploader.prototype, {
+    /**
+     * Gets one of the elements listed in this._options.classes
+     **/
+    _find: function(parent, type){                                
+        var element = qq.getByClass(parent, this._options.classes[type])[0];        
+        if (!element){
+            throw new Error('element not found ' + type);
+        }
+        
+        return element;
+    },
+    _setupDragDrop: function(){
+        var self = this,
+            dropArea = this._find(this._element, 'drop');                        
+
+        var dz = new qq.UploadDropZone({
+            element: dropArea,
+            onEnter: function(e){
+                qq.addClass(dropArea, self._classes.dropActive);
+                e.stopPropagation();
+            },
+            onLeave: function(e){
+                e.stopPropagation();
+            },
+            onLeaveNotDescendants: function(e){
+                qq.removeClass(dropArea, self._classes.dropActive);  
+            },
+            onDrop: function(e){
+                dropArea.style.display = 'none';
+                qq.removeClass(dropArea, self._classes.dropActive);
+                self._uploadFileList(e.dataTransfer.files);    
+            }
+        });
+                
+        dropArea.style.display = 'none';
+
+        qq.attach(document, 'dragenter', function(e){     
+            if (!dz._isValidFileDrag(e)) return; 
+            
+            dropArea.style.display = 'block';            
+        });                 
+        qq.attach(document, 'dragleave', function(e){
+            if (!dz._isValidFileDrag(e)) return;            
+            
+            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
+            // only fire when leaving document out
+            if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){               
+                dropArea.style.display = 'none';                                            
+            }
+        });                
+    },
+    _onSubmit: function(id, fileName){
+        qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
+        this._addToList(id, fileName);  
+    },
+    _onProgress: function(id, fileName, loaded, total){
+        qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
+
+        var item = this._getItemByFileId(id);
+        var size = this._find(item, 'size');
+        size.style.display = 'inline';
+        
+        var text; 
+        if (loaded != total){
+            text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
+        } else {                                   
+            text = this._formatSize(total);
+        }          
+        
+        qq.setText(size, text);         
+    },
+    _onComplete: function(id, fileName, result){
+        qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
+
+        // mark completed
+        var item = this._getItemByFileId(id);                
+        qq.remove(this._find(item, 'cancel'));
+        qq.remove(this._find(item, 'spinner'));
+        
+        if (result.success){
+            qq.addClass(item, this._classes.success);    
+        } else {
+            qq.addClass(item, this._classes.fail);
+        }         
+    },
+    _addToList: function(id, fileName){
+        var item = qq.toElement(this._options.fileTemplate);                
+        item.qqFileId = id;
+
+        var fileElement = this._find(item, 'file');        
+        qq.setText(fileElement, this._formatFileName(fileName));
+        this._find(item, 'size').style.display = 'none';        
+
+        this._listElement.appendChild(item);
+    },
+    _getItemByFileId: function(id){
+        var item = this._listElement.firstChild;        
+        
+        // there can't be txt nodes in dynamically created list
+        // and we can  use nextSibling
+        while (item){            
+            if (item.qqFileId == id) return item;            
+            item = item.nextSibling;
+        }          
+    },
+    /**
+     * delegate click event for cancel link 
+     **/
+    _bindCancelEvent: function(){
+        var self = this,
+            list = this._listElement;            
+        
+        qq.attach(list, 'click', function(e){            
+            e = e || window.event;
+            var target = e.target || e.srcElement;
+            
+            if (qq.hasClass(target, self._classes.cancel)){                
+                qq.preventDefault(e);
+               
+                var item = target.parentNode;
+                self._handler.cancel(item.qqFileId);
+                qq.remove(item);
+            }
+        });
+    }    
+});
+    
+qq.UploadDropZone = function(o){
+    this._options = {
+        element: null,  
+        onEnter: function(e){},
+        onLeave: function(e){},  
+        // is not fired when leaving element by hovering descendants   
+        onLeaveNotDescendants: function(e){},   
+        onDrop: function(e){}                       
+    };
+    qq.extend(this._options, o); 
+    
+    this._element = this._options.element;
+    
+    this._disableDropOutside();
+    this._attachEvents();   
+};
+
+qq.UploadDropZone.prototype = {
+    _disableDropOutside: function(e){
+        // run only once for all instances
+        if (!qq.UploadDropZone.dropOutsideDisabled ){
+
+            qq.attach(document, 'dragover', function(e){
+                if (e.dataTransfer){
+                    e.dataTransfer.dropEffect = 'none';
+                    e.preventDefault(); 
+                }           
+            });
+            
+            qq.UploadDropZone.dropOutsideDisabled = true; 
+        }        
+    },
+    _attachEvents: function(){
+        var self = this;              
+                  
+        qq.attach(self._element, 'dragover', function(e){
+            if (!self._isValidFileDrag(e)) return;
+            
+            var effect = e.dataTransfer.effectAllowed;
+            if (effect == 'move' || effect == 'linkMove'){
+                e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)    
+            } else {                    
+                e.dataTransfer.dropEffect = 'copy'; // for Chrome
+            }
+                                                     
+            e.stopPropagation();
+            e.preventDefault();                                                                    
+        });
+        
+        qq.attach(self._element, 'dragenter', function(e){
+            if (!self._isValidFileDrag(e)) return;
+                        
+            self._options.onEnter(e);
+        });
+        
+        qq.attach(self._element, 'dragleave', function(e){
+            if (!self._isValidFileDrag(e)) return;
+            
+            self._options.onLeave(e);
+            
+            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);                      
+            // do not fire when moving a mouse over a descendant
+            if (qq.contains(this, relatedTarget)) return;
+                        
+            self._options.onLeaveNotDescendants(e); 
+        });
+                
+        qq.attach(self._element, 'drop', function(e){
+            if (!self._isValidFileDrag(e)) return;
+            
+            e.preventDefault();
+            self._options.onDrop(e);
+        });          
+    },
+    _isValidFileDrag: function(e){
+        var dt = e.dataTransfer,
+            // do not check dt.types.contains in webkit, because it crashes safari 4            
+            isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;                        
+
+        // dt.effectAllowed is none in Safari 5
+        // dt.types.contains check is for firefox            
+        return dt && dt.effectAllowed != 'none' && 
+            (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
+        
+    }        
+}; 
+
+qq.UploadButton = function(o){
+    this._options = {
+        element: null,  
+        // if set to true adds multiple attribute to file input      
+        multiple: false,
+        // name attribute of file input
+        name: 'file',
+        onChange: function(input){},
+        hoverClass: 'qq-upload-button-hover',
+        focusClass: 'qq-upload-button-focus'                       
+    };
+    
+    qq.extend(this._options, o);
+        
+    this._element = this._options.element;
+    
+    // make button suitable container for input
+    qq.css(this._element, {
+        position: 'relative',
+        overflow: 'hidden',
+        // Make sure browse button is in the right side
+        // in Internet Explorer
+        direction: 'ltr'
+    });   
+    
+    this._input = this._createInput();
+};
+
+qq.UploadButton.prototype = {
+    /* returns file input element */    
+    getInput: function(){
+        return this._input;
+    },
+    /* cleans/recreates the file input */
+    reset: function(){
+        if (this._input.parentNode){
+            qq.remove(this._input);    
+        }                
+        
+        qq.removeClass(this._element, this._options.focusClass);
+        this._input = this._createInput();
+    },    
+    _createInput: function(){                
+        var input = document.createElement("input");
+        
+        if (this._options.multiple){
+            input.setAttribute("multiple", "multiple");
+        }
+                
+        input.setAttribute("type", "file");
+        input.setAttribute("name", this._options.name);
+        
+        qq.css(input, {
+            position: 'absolute',
+            // in Opera only 'browse' button
+            // is clickable and it is located at
+            // the right side of the input
+            right: 0,
+            top: 0,
+            fontFamily: 'Arial',
+            // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
+            fontSize: '118px',
+            margin: 0,
+            padding: 0,
+            cursor: 'pointer',
+            opacity: 0
+        });
+        
+        this._element.appendChild(input);
+
+        var self = this;
+        qq.attach(input, 'change', function(){
+            self._options.onChange(input);
+        });
+                
+        qq.attach(input, 'mouseover', function(){
+            qq.addClass(self._element, self._options.hoverClass);
+        });
+        qq.attach(input, 'mouseout', function(){
+            qq.removeClass(self._element, self._options.hoverClass);
+        });
+        qq.attach(input, 'focus', function(){
+            qq.addClass(self._element, self._options.focusClass);
+        });
+        qq.attach(input, 'blur', function(){
+            qq.removeClass(self._element, self._options.focusClass);
+        });
+
+        // IE and Opera, unfortunately have 2 tab stops on file input
+        // which is unacceptable in our case, disable keyboard access
+        if (window.attachEvent){
+            // it is IE or Opera
+            input.setAttribute('tabIndex', "-1");
+        }
+
+        return input;            
+    }        
+};
+
+/**
+ * Class for uploading files, uploading itself is handled by child classes
+ */
+qq.UploadHandlerAbstract = function(o){
+    this._options = {
+        debug: false,
+        action: '/upload.php',
+        // maximum number of concurrent uploads        
+        maxConnections: 999,
+        onProgress: function(id, fileName, loaded, total){},
+        onComplete: function(id, fileName, response){},
+        onCancel: function(id, fileName){}
+    };
+    qq.extend(this._options, o);    
+    
+    this._queue = [];
+    // params for files in queue
+    this._params = [];
+};
+qq.UploadHandlerAbstract.prototype = {
+    log: function(str){
+        if (this._options.debug && window.console) console.log('[uploader] ' + str);        
+    },
+    /**
+     * Adds file or file input to the queue
+     * @returns id
+     **/    
+    add: function(file){},
+    /**
+     * Sends the file identified by id and additional query params to the server
+     */
+    upload: function(id, params){
+        var len = this._queue.push(id);
+
+        var copy = {};        
+        qq.extend(copy, params);
+        this._params[id] = copy;        
+                
+        // if too many active uploads, wait...
+        if (len <= this._options.maxConnections){               
+            this._upload(id, this._params[id]);
+        }
+    },
+    /**
+     * Cancels file upload by id
+     */
+    cancel: function(id){
+        this._cancel(id);
+        this._dequeue(id);
+    },
+    /**
+     * Cancells all uploads
+     */
+    cancelAll: function(){
+        for (var i=0; i<this._queue.length; i++){
+            this._cancel(this._queue[i]);
+        }
+        this._queue = [];
+    },
+    /**
+     * Returns name of the file identified by id
+     */
+    getName: function(id){},
+    /**
+     * Returns size of the file identified by id
+     */          
+    getSize: function(id){},
+    /**
+     * Returns id of files being uploaded or
+     * waiting for their turn
+     */
+    getQueue: function(){
+        return this._queue;
+    },
+    /**
+     * Actual upload method
+     */
+    _upload: function(id){},
+    /**
+     * Actual cancel method
+     */
+    _cancel: function(id){},     
+    /**
+     * Removes element from queue, starts upload of next
+     */
+    _dequeue: function(id){
+        var i = qq.indexOf(this._queue, id);
+        this._queue.splice(i, 1);
+                
+        var max = this._options.maxConnections;
+        
+        if (this._queue.length >= max){
+            var nextId = this._queue[max-1];
+            this._upload(nextId, this._params[nextId]);
+        }
+    }        
+};
+
+/**
+ * Class for uploading files using form and iframe
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerForm = function(o){
+    qq.UploadHandlerAbstract.apply(this, arguments);
+       
+    this._inputs = {};
+};
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+    add: function(fileInput){
+        fileInput.setAttribute('name', 'qqfile');
+        var id = 'qq-upload-handler-iframe' + qq.getUniqueId();       
+        
+        this._inputs[id] = fileInput;
+        
+        // remove file input from DOM
+        if (fileInput.parentNode){
+            qq.remove(fileInput);
+        }
+                
+        return id;
+    },
+    getName: function(id){
+        // get input value and remove path to normalize
+        return this._inputs[id].value.replace(/.*(\/|\\)/, "");
+    },    
+    _cancel: function(id){
+        this._options.onCancel(id, this.getName(id));
+        
+        delete this._inputs[id];        
+
+        var iframe = document.getElementById(id);
+        if (iframe){
+            // to cancel request set src to something else
+            // we use src="javascript:false;" because it doesn't
+            // trigger ie6 prompt on https
+            iframe.setAttribute('src', 'javascript:false;');
+
+            qq.remove(iframe);
+        }
+    },     
+    _upload: function(id, params){                        
+        var input = this._inputs[id];
+        
+        if (!input){
+            throw new Error('file with passed id was not added, or already uploaded or cancelled');
+        }                
+
+        var fileName = this.getName(id);
+                
+        var iframe = this._createIframe(id);
+        var form = this._createForm(iframe, params);
+        form.appendChild(input);
+
+        var self = this;
+        this._attachLoadEvent(iframe, function(){                                 
+            self.log('iframe loaded');
+            
+            var response = self._getIframeContentJSON(iframe);
+
+            self._options.onComplete(id, fileName, response);
+            self._dequeue(id);
+            
+            delete self._inputs[id];
+            // timeout added to fix busy state in FF3.6
+            setTimeout(function(){
+                qq.remove(iframe);
+            }, 1);
+        });
+
+        form.submit();        
+        qq.remove(form);        
+        
+        return id;
+    }, 
+    _attachLoadEvent: function(iframe, callback){
+        qq.attach(iframe, 'load', function(){
+            // when we remove iframe from dom
+            // the request stops, but in IE load
+            // event fires
+            if (!iframe.parentNode){
+                return;
+            }
+
+            // fixing Opera 10.53
+            if (iframe.contentDocument &&
+                iframe.contentDocument.body &&
+                iframe.contentDocument.body.innerHTML == "false"){
+                // In Opera event is fired second time
+                // when body.innerHTML changed from false
+                // to server response approx. after 1 sec
+                // when we upload file with iframe
+                return;
+            }
+
+            callback();
+        });
+    },
+    /**
+     * Returns json object received by iframe from server.
+     */
+    _getIframeContentJSON: function(iframe){
+        // iframe.contentWindow.document - for IE<7
+        var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
+            response;
+        
+        this.log("converting iframe's innerHTML to JSON");
+        this.log("innerHTML = " + doc.body.innerHTML);
+                        
+        try {
+            response = eval("(" + doc.body.innerHTML + ")");
+        } catch(err){
+            response = {};
+        }        
+
+        return response;
+    },
+    /**
+     * Creates iframe with unique name
+     */
+    _createIframe: function(id){
+        // We can't use following code as the name attribute
+        // won't be properly registered in IE6, and new window
+        // on form submit will open
+        // var iframe = document.createElement('iframe');
+        // iframe.setAttribute('name', id);
+
+        var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
+        // src="javascript:false;" removes ie6 prompt on https
+
+        iframe.setAttribute('id', id);
+
+        iframe.style.display = 'none';
+        document.body.appendChild(iframe);
+
+        return iframe;
+    },
+    /**
+     * Creates form, that will be submitted to iframe
+     */
+    _createForm: function(iframe, params){
+        // We can't use the following code in IE6
+        // var form = document.createElement('form');
+        // form.setAttribute('method', 'post');
+        // form.setAttribute('enctype', 'multipart/form-data');
+        // Because in this case file won't be attached to request
+        var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
+
+        var queryString = qq.obj2url(params, this._options.action);
+
+        form.setAttribute('action', queryString);
+        form.setAttribute('target', iframe.name);
+        form.style.display = 'none';
+        document.body.appendChild(form);
+
+        return form;
+    }
+});
+
+/**
+ * Class for uploading files using xhr
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerXhr = function(o){
+    qq.UploadHandlerAbstract.apply(this, arguments);
+
+    this._files = [];
+    this._xhrs = [];
+    
+    // current loaded size in bytes for each file 
+    this._loaded = [];
+};
+
+// static method
+qq.UploadHandlerXhr.isSupported = function(){
+    var input = document.createElement('input');
+    input.type = 'file';        
+    
+    return (
+        'multiple' in input &&
+        typeof File != "undefined" &&
+        typeof (new XMLHttpRequest()).upload != "undefined" );       
+};
+
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+    /**
+     * Adds file to the queue
+     * Returns id to use with upload, cancel
+     **/    
+    add: function(file){
+        if (!(file instanceof File)){
+            throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
+        }
+                
+        return this._files.push(file) - 1;        
+    },
+    getName: function(id){        
+        var file = this._files[id];
+        // fix missing name in Safari 4
+        return file.fileName != null ? file.fileName : file.name;       
+    },
+    getSize: function(id){
+        var file = this._files[id];
+        return file.fileSize != null ? file.fileSize : file.size;
+    },    
+    /**
+     * Returns uploaded bytes for file identified by id 
+     */    
+    getLoaded: function(id){
+        return this._loaded[id] || 0; 
+    },
+    /**
+     * Sends the file identified by id and additional query params to the server
+     * @param {Object} params name-value string pairs
+     */    
+    _upload: function(id, params){
+        var file = this._files[id],
+            name = this.getName(id),
+            size = this.getSize(id);
+                
+        this._loaded[id] = 0;
+                                
+        var xhr = this._xhrs[id] = new XMLHttpRequest();
+        var self = this;
+                                        
+        xhr.upload.onprogress = function(e){
+            if (e.lengthComputable){
+                self._loaded[id] = e.loaded;
+                self._options.onProgress(id, name, e.loaded, e.total);
+            }
+        };
+
+        xhr.onreadystatechange = function(){            
+            if (xhr.readyState == 4){
+                self._onComplete(id, xhr);                    
+            }
+        };
+
+        // build query string
+        params = params || {};
+        params['qqfile'] = name;
+        var queryString = qq.obj2url(params, this._options.action);
+
+        xhr.open("POST", queryString, true);
+        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+        xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+        xhr.setRequestHeader("Content-Type", "application/octet-stream");
+        xhr.send(file);
+    },
+    _onComplete: function(id, xhr){
+        // the request was aborted/cancelled
+        if (!this._files[id]) return;
+        
+        var name = this.getName(id);
+        var size = this.getSize(id);
+        
+        this._options.onProgress(id, name, size, size);
+                
+        if (xhr.status == 200){
+            this.log("xhr - server response received");
+            this.log("responseText = " + xhr.responseText);
+                        
+            var response;
+                    
+            try {
+                response = eval("(" + xhr.responseText + ")");
+            } catch(err){
+                response = {};
+            }
+            
+            this._options.onComplete(id, name, response);
+                        
+        } else {                   
+            this._options.onComplete(id, name, {});
+        }
+                
+        this._files[id] = null;
+        this._xhrs[id] = null;    
+        this._dequeue(id);                    
+    },
+    _cancel: function(id){
+        this._options.onCancel(id, this.getName(id));
+        
+        this._files[id] = null;
+        
+        if (this._xhrs[id]){
+            this._xhrs[id].abort();
+            this._xhrs[id] = null;                                   
+        }
+    }
+});
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/client/loading.gif b/addon/js_upload/file-uploader/client/loading.gif
new file mode 100644 (file)
index 0000000..6fba776
Binary files /dev/null and b/addon/js_upload/file-uploader/client/loading.gif differ
diff --git a/addon/js_upload/file-uploader/gpl-2.0.txt b/addon/js_upload/file-uploader/gpl-2.0.txt
new file mode 100644 (file)
index 0000000..ecbc059
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/license.txt b/addon/js_upload/file-uploader/license.txt
new file mode 100644 (file)
index 0000000..25cdd3d
--- /dev/null
@@ -0,0 +1,24 @@
+File uploader component is licensed under GNU GPL 2 or later, see gpl-2.0.txt.
+© 2010 Andrew Valums
+
+This distribution also includes:
+
+    server/OctetStreamReader.java    
+    Dual Licensed under the MIT and GPL v.2        
+    
+    jQuery JavaScript Library
+    http://jquery.com/    
+    Copyright 2010, John Resig
+    Dual licensed under the MIT or GPL Version 2 licenses.
+    http://jquery.org/license
+    
+    Sizzle.js - CSS selector engine used by jQuery
+    http://sizzlejs.com/
+    Copyright 2010, The Dojo Foundation
+    Released under the MIT, BSD, and GPL Licenses.
+        
+    QUnit - A JavaScript Unit Testing Framework
+    http://docs.jquery.com/QUnit
+    Copyright (c) 2009 John Resig, Jörn Zaefferer
+    Dual licensed under the MIT (MIT-LICENSE.txt)
+    and GPL (GPL-LICENSE.txt) licenses.
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/readme.md b/addon/js_upload/file-uploader/readme.md
new file mode 100644 (file)
index 0000000..c107bf1
--- /dev/null
@@ -0,0 +1,152 @@
+[donation_link]: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=3PMY37SL9L888&lc=US&item_name=JavaScript%20file%20uploader&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
+
+This plugin uses XHR for uploading multiple files with progress-bar in FF3.6+, Safari4+,
+Chrome and falls back to hidden iframe based upload in other browsers,
+providing good user experience everywhere.
+
+### <a href="http://valums.com/files/2010/file-uploader/demo.htm">Demo</a> [Donate][donation_link] ###
+
+### Features ###
+* multiple file select, progress-bar in FF, Chrome, Safari
+* drag-and-drop file select in FF, Chrome 
+* uploads are cancellable
+* no external dependencies
+* doesn't use Flash
+* fully working with https
+* keyboard support in FF, Chrome, Safari
+* tested in IE7,8; Firefox 3,3.6,4; Safari4,5; Chrome; Opera10.60;
+
+### License ###
+This plugin is open sourced under <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPL 2</a> or later.
+If this license doesn't suit you mail me at andrew (at) valums.com.
+
+Please [donate][donation_link] if you are willing to support the further development of file upload plugin.  
+
+### Known Issues ###
+Plugin breaks back button functionality in Opera.
+       
+### Getting started ###
+The fileuploader.js contains two classes that are meant to be used directly.
+If you need a complete upload widget (from demo) to quickly drop
+into your current design, use qq.FileUploader.
+
+If you want to customize uploader, by using a different looking file list
+or change the behaviour or functionality use qq.FileUploaderBasic.
+
+The difference between them is that qq.FileUploader provides a list of files,
+drag-and-drop, but qq.FileUploaderBasic only creates button and handles validation.
+Basic uploader is easier extendable, and doesn't limit possible customization.
+
+qq.FileUploader extends qq.FileUploaderBasic, so that all the options present
+in the basic uploader also exist in the full widget.  
+
+### qq.FileUploader - Setting up full upload widget ###
+
+Include fileuploader.js and fileuploader.css into your page.
+Create container element.
+
+    <div id="file-uploader">       
+        <noscript>          
+            <p>Please enable JavaScript to use file uploader.</p>
+            <!-- or put a simple form for upload here -->
+        </noscript>         
+    </div>
+    
+Initialize uploader when the DOM is ready. Change the action option.
+For example ../server/php.php for the default folder structure.
+In the server folder you will find examples for different platforms.
+If you can't find the one you need, check the readme.txt in the same folder. 
+
+    var uploader = new qq.FileUploader({
+        // pass the dom node (ex. $(selector)[0] for jQuery users)
+        element: document.getElementById('file-uploader'),
+        // path to server-side upload script
+        action: '/server/upload'
+    }); 
+
+### Options of both classes ###
+    
+    // url of the server-side upload script, should be on the same domain
+    action: '/server/upload',
+    // additional data to send, name-value pairs
+    params: {},
+    
+    // validation    
+    // ex. ['jpg', 'jpeg', 'png', 'gif'] or []
+    allowedExtensions: [],        
+    // each file size limit in bytes
+    // this option isn't supported in all browsers
+    sizeLimit: 0, // max size   
+    minSizeLimit: 0, // min size
+    
+    // set to true to output server response to console
+    debug: false,
+    
+    // events         
+    // you can return false to abort submit
+    onSubmit: function(id, fileName){},
+    onProgress: function(id, fileName, loaded, total){},
+    onComplete: function(id, fileName, responseJSON){},
+    onCancel: function(id, fileName){},
+    
+    messages: {
+        // error messages, see qq.FileUploaderBasic for content            
+    },
+    showMessage: function(message){ alert(message); }        
+
+Instance methods
+
+* setParams(newParams)         
+
+#### Changing alert/messages to something more user friendly ####
+
+If you limited file types and max size, you will probably want to change the default alert and
+messages as you see fit, this is possible using showMessage callback and messages option.
+
+#### Sending additional params ####
+
+To add a parameter that will be passed as a query string with each upload use params option. 
+
+    var uploader = new qq.FileUploader({
+        element: document.getElementById('file-uploader'),
+        action: '/server-side.upload',
+        // additional data to send, name-value pairs
+        params: {
+            param1: 'value1',
+            param2: 'value2'
+        }
+    });
+
+To change params based on the state of your app, use 
+    
+    uploader.setParams({
+       anotherParam: 'value' 
+    });
+
+It can be nicely used in onSubmit callback.      
+
+#### Troubleshooting ####
+
+If you can't get the uploader to work, please try the following steps
+before asking for help.
+
+If the upload doesn't complete, saying failed.
+
+* Set the debug option of the FileUploader to true.
+* Open the page where you have a FileUploader.
+* Open developer console in your browser.
+* Try to upload the file. You should see a server serponse.
+
+It should be {success:true} for completed requests. If it's not,
+then you have a problem with your server-side script.
+
+#### Contributors ####
+
+Thanks to everybody who contributed, either by sending bug reports or donating. And special thanks to:
+
+John Yeary  
+Sidney Maestre  
+Patrick Pfeiffer  
+Sean Sandy (SeanJA)  
+Andy Newby     
+Ivan Valles  
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/OctetStreamReader.java b/addon/js_upload/file-uploader/server/OctetStreamReader.java
new file mode 100644 (file)
index 0000000..23f02be
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  Copyright 2010 Blue Lotus Software, LLC.
+ *  Copyright 2010 John Yeary <jyeary@bluelotussoftware.com>.
+ *  Copyright 2010 Allan O'Driscoll
+ *
+ * Dual Licensed MIT and GPL v.2 
+ *
+ * The MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *
+ * The GNU General Public License (GPL) Version 2, June 1991
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; version 2 of the License.
+
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package com.bluelotussoftware.apache.commons.fileupload.example;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Reads an <code>application/octet-stream</code> and writes it to a file.
+ * @author John Yeary <jyeary@bluelotussoftware.com>
+ * @author Allan O'Driscoll
+ * @version 1.0
+ */
+public class OctetStreamReader extends HttpServlet {
+
+    private static final long serialVersionUID = 6748857432950840322L;
+    private static final String DESTINATION_DIR_PATH = "files";
+    private static String realPath;
+
+    /**
+     * {@inheritDoc}
+     * @param config
+     * @throws ServletException
+     */
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH) + "/";
+    }
+
+    /** 
+     * Handles the HTTP <code>POST</code> method.
+     * @param request servlet request
+     * @param response servlet response
+     * @throws ServletException if a servlet-specific error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    protected void doPost(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException {
+
+        PrintWriter writer = null;
+        InputStream is = null;
+        FileOutputStream fos = null;
+
+        try {
+            writer = response.getWriter();
+        } catch (IOException ex) {
+            log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
+        }
+
+        String filename = request.getHeader("X-File-Name");
+        try {
+            is = request.getInputStream();
+            fos = new FileOutputStream(new File(realPath + filename));
+            IOUtils.copy(is, fos);
+            response.setStatus(response.SC_OK);
+            writer.print("{success: true}");
+        } catch (FileNotFoundException ex) {
+            response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
+            writer.print("{success: false}");
+            log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
+        } catch (IOException ex) {
+            response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
+            writer.print("{success: false}");
+            log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
+        } finally {
+            try {
+                fos.close();
+                is.close();
+            } catch (IOException ignored) {
+            }
+        }
+
+        writer.flush();
+        writer.close();
+    }
+}
diff --git a/addon/js_upload/file-uploader/server/coldfusion/coldfusion.cfc b/addon/js_upload/file-uploader/server/coldfusion/coldfusion.cfc
new file mode 100644 (file)
index 0000000..4e07270
--- /dev/null
@@ -0,0 +1 @@
+<!---\rAJAX FileUploader for ColdFusion\rversion: 1.1.1\rfeedback:  sid.maestre@designovermatter.com\r\r-----------update history----------------\r1.1.1 on 9/30/2010 by Martin Webb <martin[at]cubicstate.com>\r- Change function for Upload to returnformat equals JSON\r- local var scoping.\r1.1 on 9/9/2010 by Sid Maestre\r- Split Upload function to handle fallback uploads for browsers that don't support XHR data transfer\r--->\r<cfcomponent hint="I handle AJAX File Uploads from Valum's AJAX file uploader library">\r      \r    <cffunction name="Upload" access="remote" output="false" returntype="any" returnformat="JSON">\r            <cfargument name="qqfile" type="string" required="true">\r\r              <cfset var local = structNew()>\r                <cfset local.response = structNew()>\r           <cfset local.requestData = GetHttpRequestData()>\r               \r               <!--- check if XHR data exists --->\r        <cfif len(local.requestData.content) GT 0>\r                 <cfset local.response = UploadFileXhr(arguments.qqfile, local.requestData.content)>       \r             <cfelse>\r               <!--- no XHR data process as standard form submission --->\r                     <cffile action="upload" fileField="arguments.qqfile" destination="#ExpandPath('.')#" nameConflict="makeunique">\r                <cfset local.response['success'] = true>\r               <cfset local.response['type'] = 'form'>\r                </cfif>\r                \r               <cfreturn local.response>\r      </cffunction>\r    \r    \r    <cffunction name="UploadFileXhr" access="private" output="false" returntype="struct">\r              <cfargument name="qqfile" type="string" required="true">\r               <cfargument name="content" type="any" required="true">\r\r                <cfset var local = structNew()>\r                <cfset local.response = structNew()>\r\r        <!--- write the contents of the http request to a file.  \r                The filename is passed with the qqfile variable --->\r           <cffile action="write" file="#ExpandPath('.')#/#arguments.qqfile#" output="#arguments.content#">\r       \r               <!--- if you want to return some JSON you can do it here.  \r            I'm just passing a success message      --->\r           <cfset local.response['success'] = true>\r       <cfset local.response['type'] = 'xhr'>\r         \r               <cfreturn local.response>\r    </cffunction>\r    \r</cfcomponent>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/coldfusion/demo.cfm b/addon/js_upload/file-uploader/server/coldfusion/demo.cfm
new file mode 100644 (file)
index 0000000..98ab800
--- /dev/null
@@ -0,0 +1 @@
+<!DOCTYPE html>\r<html>\r<head>\r    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r       <link href="fileuploader.css" rel="stylesheet" type="text/css"> \r    <style>            \r               body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}\r    </style>      \r       \r</head>\r<body >                \r       <h1>ColdFusion File Uploader Demo</h1>\r    <p><a href="http://github.com/valums/file-uploader">Back to project page</a></p>\r    \r       <p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>\r  <p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>\r \r       <div id="file-uploader-demo1">          \r               <noscript>                      \r                       <p>Please enable JavaScript to use file uploader.</p>\r                  <!-- or put a simple form for upload here -->\r          </noscript>         \r   </div>\r    \r    <script src="fileuploader.js" type="text/javascript"></script>\r    <script>        \r        function createUploader(){            \r            var uploader = new qq.FileUploader({\r                element: document.getElementById('file-uploader-demo1'),\r                action: '/valums/server/coldfusion.cfc',\r                          params: {method: 'Upload'}\r            });           \r        }\r        \r        // in your app create uploader as soon as the DOM is ready\r        // don't wait for the window to load  \r        window.onload = createUploader;     \r    </script>    \r</body>\r</html>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/coldfusion/readme.txt b/addon/js_upload/file-uploader/server/coldfusion/readme.txt
new file mode 100644 (file)
index 0000000..c974689
--- /dev/null
@@ -0,0 +1,9 @@
+Coldfusion example by Sidney Maestre
+http://www.designovermatter.com/post.cfm/ajax-file-uploader-for-coldfusion
+
+    1.  Unzip Andrew's AJAX Uploader into your web root.
+    2.  Replace the demo.htm with demo.cfm in the "client" folder
+    3.  Place coldfusion.cfc in the "server" folder 
+    4.  Browse to the demo.cfm file and try it out. The file should be written to the "server" folder.
+
+Questions? You can contact Sidney Maestreme by mail (sid.maestre(at)designovermatter.com) or Twitter @SidneyAllen
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/perl.cgi b/addon/js_upload/file-uploader/server/perl.cgi
new file mode 100644 (file)
index 0000000..c66f1aa
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+
+    use strict;
+    use CGI::Carp qw(fatalsToBrowser);
+
+    use Digest::MD5;
+
+    my $uploaddir = '/folder/to/save/in/ajax_upload/tmp_uploads';
+
+    my $maxFileSize = 0.5 * 1024 * 1024; # 1/2mb max file size...
+
+    use CGI;
+    my $IN = new CGI;
+
+    my $file = $IN->param('POSTDATA');
+    my $temp_id = $IN->param('temp_id');
+
+       # make a random filename, and we guess the file type later on...
+    my $name = Digest::MD5::md5_base64( rand );
+       $name =~ s/\+/_/g;
+       $name =~ s/\//_/g;
+
+    my $type;
+    if ($file =~ /^GIF/) {
+        $type = "gif";
+    } elsif ($file =~ /PNG/) {
+        $type = "png";
+    } elsif ($file =~ /JFIF/) {
+        $type = "jpg";
+    }
+
+    if (!$type) {
+        print qq|{ "success": false, "error": "Invalid file type..." }|;
+        print STDERR "file has been NOT been uploaded... \n";
+    }
+
+    print STDERR "Making dir: $uploaddir/$temp_id \n";
+
+    mkdir("$uploaddir/$temp_id");
+
+    open(WRITEIT, ">$uploaddir/$name.$type") or die "Cant write to $uploaddir/$name.$type. Reason: $!";
+        print WRITEIT $file;
+    close(WRITEIT);
+
+    my $check_size = -s "$uploaddir/$name.$type";
+
+    print STDERR qq|Main filesize: $check_size  Max Filesize: $maxFileSize \n\n|;
+
+    print $IN->header();
+    if ($check_size < 1) {
+        print STDERR "ooops, its empty - gonna get rid of it!\n";
+        print qq|{ "success": false, "error": "File is empty..." }|;
+        print STDERR "file has been NOT been uploaded... \n";
+    } elsif ($check_size > $maxFileSize) {
+        print STDERR "ooops, its too large - gonna get rid of it!\n";
+        print qq|{ "success": false, "error": "File is too large..." }|;
+        print STDERR "file has been NOT been uploaded... \n";
+    } else  {
+        print qq|{ "success": true }|;
+
+        print STDERR "file has been successfully uploaded... thank you.\n";
+    }
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/php.php b/addon/js_upload/file-uploader/server/php.php
new file mode 100644 (file)
index 0000000..915c86c
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+/**
+ * Handle file uploads via XMLHttpRequest
+ */
+class qqUploadedFileXhr {
+    /**
+     * Save the file to the specified path
+     * @return boolean TRUE on success
+     */
+    function save($path) {    
+        $input = fopen("php://input", "r");
+        $temp = tmpfile();
+        $realSize = stream_copy_to_stream($input, $temp);
+        fclose($input);
+        
+        if ($realSize != $this->getSize()){            
+            return false;
+        }
+        
+        $target = fopen($path, "w");        
+        fseek($temp, 0, SEEK_SET);
+        stream_copy_to_stream($temp, $target);
+        fclose($target);
+        
+        return true;
+    }
+    function getName() {
+        return $_GET['qqfile'];
+    }
+    function getSize() {
+        if (isset($_SERVER["CONTENT_LENGTH"])){
+            return (int)$_SERVER["CONTENT_LENGTH"];            
+        } else {
+            throw new Exception('Getting content length is not supported.');
+        }      
+    }   
+}
+
+/**
+ * Handle file uploads via regular form post (uses the $_FILES array)
+ */
+class qqUploadedFileForm {  
+    /**
+     * Save the file to the specified path
+     * @return boolean TRUE on success
+     */
+    function save($path) {
+        if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
+            return false;
+        }
+        return true;
+    }
+    function getName() {
+        return $_FILES['qqfile']['name'];
+    }
+    function getSize() {
+        return $_FILES['qqfile']['size'];
+    }
+}
+
+class qqFileUploader {
+    private $allowedExtensions = array();
+    private $sizeLimit = 10485760;
+    private $file;
+
+    function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){        
+        $allowedExtensions = array_map("strtolower", $allowedExtensions);
+            
+        $this->allowedExtensions = $allowedExtensions;        
+        $this->sizeLimit = $sizeLimit;
+        
+        $this->checkServerSettings();       
+
+        if (isset($_GET['qqfile'])) {
+            $this->file = new qqUploadedFileXhr();
+        } elseif (isset($_FILES['qqfile'])) {
+            $this->file = new qqUploadedFileForm();
+        } else {
+            $this->file = false; 
+        }
+    }
+    
+    private function checkServerSettings(){        
+        $postSize = $this->toBytes(ini_get('post_max_size'));
+        $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));        
+        
+        if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
+            $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';             
+            die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
+        }        
+    }
+    
+    private function toBytes($str){
+        $val = trim($str);
+        $last = strtolower($str[strlen($str)-1]);
+        switch($last) {
+            case 'g': $val *= 1024;
+            case 'm': $val *= 1024;
+            case 'k': $val *= 1024;        
+        }
+        return $val;
+    }
+    
+    /**
+     * Returns array('success'=>true) or array('error'=>'error message')
+     */
+    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
+        if (!is_writable($uploadDirectory)){
+            return array('error' => "Server error. Upload directory isn't writable.");
+        }
+        
+        if (!$this->file){
+            return array('error' => 'No files were uploaded.');
+        }
+        
+        $size = $this->file->getSize();
+        
+        if ($size == 0) {
+            return array('error' => 'File is empty');
+        }
+        
+        if ($size > $this->sizeLimit) {
+            return array('error' => 'File is too large');
+        }
+        
+        $pathinfo = pathinfo($this->file->getName());
+        $filename = $pathinfo['filename'];
+        //$filename = md5(uniqid());
+        $ext = $pathinfo['extension'];
+
+        if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
+            $these = implode(', ', $this->allowedExtensions);
+            return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
+        }
+        
+        if(!$replaceOldFile){
+            /// don't overwrite previous files that were uploaded
+            while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
+                $filename .= rand(10, 99);
+            }
+        }
+        
+        if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
+            return array('success'=>true);
+        } else {
+            return array('error'=> 'Could not save uploaded file.' .
+                'The upload was cancelled, or server error encountered');
+        }
+        
+    }    
+}
+
+// list of valid extensions, ex. array("jpeg", "xml", "bmp")
+$allowedExtensions = array();
+// max file size in bytes
+$sizeLimit = 10 * 1024 * 1024;
+
+$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
+$result = $uploader->handleUpload('uploads/');
+// to pass data through iframe you will need to encode all html tags
+echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
diff --git a/addon/js_upload/file-uploader/server/readme.txt b/addon/js_upload/file-uploader/server/readme.txt
new file mode 100644 (file)
index 0000000..8363c0b
--- /dev/null
@@ -0,0 +1,18 @@
+The server-side code should consist of two parts.
+
+1. For IE6-8, Opera, older versions of other browsers you get the file as
+you normally do with regular form-base uploads.
+
+2. For browsers which upload file with progress bar, you will need to get the raw
+post data and write it to the file.
+
+## Return values ##
+
+You should return json as a text/html, and escape all
+'<' as '&lt;', '>' as '&gt;', and '&' as '&amp;'.
+
+Return
+{"success":true} when upload was successful
+{"error":"error message to display"} in case of error
+
+Send me a mail to andrew (at) valums.com, if you will have any questions.
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/server/uploads/.gitignore b/addon/js_upload/file-uploader/server/uploads/.gitignore
new file mode 100644 (file)
index 0000000..c96a04f
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/action-acceptance.php b/addon/js_upload/file-uploader/tests/action-acceptance.php
new file mode 100644 (file)
index 0000000..fc9583f
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+usleep(100000);
+
+$fileName;
+$fileSize;
+
+if (isset($_GET['qqfile'])){
+    $fileName = $_GET['qqfile'];
+    
+       // xhr request
+       $headers = apache_request_headers();
+       $fileSize = (int)$headers['Content-Length'];
+} elseif (isset($_FILES['qqfile'])){
+    $fileName = basename($_FILES['qqfile']['name']);
+    $fileSize = $_FILES['qqfile']['size'];
+} else {
+       die ('{error: "server-error file not passed"}');
+}
+
+if ($fileName == '4text.txt'){
+    die ('jsgkdfgu4eyij');
+}
+
+if ($fileSize == 0){
+    die ('{error: "server-error file size is zero"}');
+}
+
+if ($fileSize < 10){
+    die ('{error: "server-error file size is smaller than 10 bytes"}');
+}
+
+if ($fileSize > 9 * 1024){
+    die ('{error: "server-error file size is bigger than 9kB"}');
+}
+
+if (count($_GET)){     
+    array_merge($_GET, array('fileName'=>$fileName));
+    
+    $response = array_merge($_GET, array('success'=>true, 'fileName'=>$fileName));
+    
+    // to pass data through iframe you will need to encode all html tags               
+       echo htmlspecialchars(json_encode($response), ENT_NOQUOTES);    
+} else {
+       die ('{error: "server-error  query params not passed"}');
+}
diff --git a/addon/js_upload/file-uploader/tests/action-handler-queue-test.php b/addon/js_upload/file-uploader/tests/action-handler-queue-test.php
new file mode 100644 (file)
index 0000000..ff13576
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+sleep(4);
+
+$fileName;
+
+if (isset($_GET['qqfile'])){
+    $fileName = $_GET['qqfile'];
+    
+       // xhr request
+       $headers = apache_request_headers();
+       if ((int)$headers['Content-Length'] == 0){
+               die ('{error: "content length is zero"}');
+       }
+} elseif (isset($_FILES['qqfile'])){
+    $fileName = basename($_FILES['qqfile']['name']);
+    
+       // form request
+       if ($_FILES['qqfile']['size'] == 0){
+               die ('{error: "file size is zero"}');
+       }
+} else {
+       die ('{error: "file not passed"}');
+}
+
+if (count($_GET)){
+    $_GET['success'] = true;
+       echo json_encode(array_merge($_GET));   
+} else {
+       die ('{error: "query params not passed"}');
+}
diff --git a/addon/js_upload/file-uploader/tests/action-handler-test.php b/addon/js_upload/file-uploader/tests/action-handler-test.php
new file mode 100644 (file)
index 0000000..24466b1
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+usleep(300);
+
+$fileName;
+
+if (isset($_GET['qqfile'])){
+    $fileName = $_GET['qqfile'];
+    
+       // xhr request
+       $headers = apache_request_headers();
+       if ((int)$headers['Content-Length'] == 0){
+               die ('{error: "content length is zero"}');
+       }
+} elseif (isset($_FILES['qqfile'])){
+    $fileName = basename($_FILES['qqfile']['name']);
+    
+       // form request
+       if ($_FILES['qqfile']['size'] == 0){
+               die ('{error: "file size is zero"}');
+       }
+} else {
+       die ('{error: "file not passed"}');
+}
+
+if (count($_GET)){
+       //return query params
+       echo json_encode(array_merge($_GET, array('fileName'=>$fileName)));     
+} else {
+       die ('{error: "query params not passed"}');
+}
diff --git a/addon/js_upload/file-uploader/tests/action-slow-response.php b/addon/js_upload/file-uploader/tests/action-slow-response.php
new file mode 100644 (file)
index 0000000..15c38d8
--- /dev/null
@@ -0,0 +1,2 @@
+<?php
+sleep(9);
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/browser-bugs/safari-bug1.htm b/addon/js_upload/file-uploader/tests/browser-bugs/safari-bug1.htm
new file mode 100644 (file)
index 0000000..ef0eb0b
--- /dev/null
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>      
+    <p>Drag multiple files into input field. (Win7)</p>
+    <p>Result: One file is selected multiple times. Expected: Multiple files are selected.</p>
+    <input type="file" multiple></body>
+</html>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/browser-bugs/safari-bug2.htm b/addon/js_upload/file-uploader/tests/browser-bugs/safari-bug2.htm
new file mode 100644 (file)
index 0000000..57f7bc0
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>      
+
+<script>
+window.addEventListener('load', function(){
+    document.addEventListener('dragenter', function(e){
+        e.preventDefault();
+    },false);
+    document.addEventListener('dragover', function(e){
+        e.preventDefault();        
+        // e.dataTransfer.effectAllowed is none
+        e.dataTransfer.dropEffect = 'copy';
+    },false);    
+},false);
+</script>
+</html>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/application-javascript.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/application-javascript.php
new file mode 100644 (file)
index 0000000..a91c75f
--- /dev/null
@@ -0,0 +1 @@
+<?php header('Content-type: application/javascript'); ?>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/application-json.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/application-json.php
new file mode 100644 (file)
index 0000000..c116125
--- /dev/null
@@ -0,0 +1 @@
+<?php header('Content-type: application/json'); ?>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/header-404.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/header-404.php
new file mode 100644 (file)
index 0000000..17d8075
--- /dev/null
@@ -0,0 +1,2 @@
+<?php header("HTTP/1.0 404 Not Found"); ?>
+Not found!
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/somepage.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/somepage.php
new file mode 100644 (file)
index 0000000..f0a2575
--- /dev/null
@@ -0,0 +1 @@
+I'm a page.
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/text-html-large.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/text-html-large.php
new file mode 100644 (file)
index 0000000..ac9682b
--- /dev/null
@@ -0,0 +1,6 @@
+<?php 
+       header('Content-type: text/html');
+       
+       $data = str_repeat("a", 5000);
+        
+       echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/text-html.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/text-html.php
new file mode 100644 (file)
index 0000000..b69a1c7
--- /dev/null
@@ -0,0 +1,7 @@
+<?php 
+       header('Content-type: text/html');
+       $data = array(
+               'example' => "&a<computer networks>, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
+               'sub' => array('arr'=>array(10,20,30), 'boo'=>false)             
+       ); 
+       echo htmlspecialchars(json_encode($data), ENT_NOQUOTES);
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/text-javascript.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/text-javascript.php
new file mode 100644 (file)
index 0000000..ee930d0
--- /dev/null
@@ -0,0 +1 @@
+<?php header('Content-type: text/javascript'); ?>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/iframe-content-tests/text-plain.php b/addon/js_upload/file-uploader/tests/iframe-content-tests/text-plain.php
new file mode 100644 (file)
index 0000000..90c1af0
--- /dev/null
@@ -0,0 +1,2 @@
+<?php header('Content-type: text/plain'); ?>
+text<p>P tag</p>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/jquery-1.4.2.min.js b/addon/js_upload/file-uploader/tests/jquery-1.4.2.min.js
new file mode 100644 (file)
index 0000000..7c24308
--- /dev/null
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/jquery-ui-1.8.4.custom.min.js b/addon/js_upload/file-uploader/tests/jquery-ui/jquery-ui-1.8.4.custom.min.js
new file mode 100644 (file)
index 0000000..891dcdd
--- /dev/null
@@ -0,0 +1,200 @@
+/*!
+ * jQuery UI 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.4",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,
+b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,
+CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable",
+"off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
+"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=
+parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+
+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==
+b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
+;/*!
+ * jQuery UI Widget 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,j){var k=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return k.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);
+b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):
+this.each(function(){var g=b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});
+this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}b.each(d,function(f,
+h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=
+b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
+;/*!
+ * jQuery UI Mouse 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ *     jquery.ui.widget.js
+ */
+(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
+this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
+return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
+this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
+a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+;/*
+ * jQuery UI Position 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h=
+0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+=
+g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k,
+elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"?
+-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position=
+"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery);
+;/*
+ * jQuery UI Draggable 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
+"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
+this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-
+this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();
+d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||
+this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,
+b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==
+a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
+0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
+this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-
+(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment==
+"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&
+a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),
+10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
+this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():
+f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])e=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+
+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;e=this.originalPageX+
+Math.round((e-this.originalPageX)/b.grid[0])*b.grid[0];e=this.containment?!(e-this.offset.click.left<this.containment[0]||e-this.offset.click.left>this.containment[2])?e:!(e-this.offset.click.left<this.containment[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-
+this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=
+this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.4"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var g=d.data(this,"sortable");
+if(g&&!g.options.disabled){c.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",a,e)}})},stop:function(a,b){var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;
+c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=
+1;this.instance.currentItem=d(f).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;
+this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=
+this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}});d.ui.plugin.add("draggable","iframeFix",{start:function(){var a=
+d(this).data("draggable").options;d(a.iframeFix===true?"iframe":a.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;
+if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!=
+"HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-
+b.overflowOffset.left<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
+c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
+width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,g=b.offset.left,n=g+c.helperProportions.width,m=b.offset.top,o=m+c.helperProportions.height,h=c.snapElements.length-1;h>=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e<g&&g<k+e&&j-e<m&&m<l+e||i-e<g&&g<k+e&&j-e<o&&o<l+e||i-e<n&&n<k+e&&j-e<m&&m<l+e||i-e<n&&n<k+e&&j-e<o&&
+o<l+e){if(f.snapMode!="inner"){var p=Math.abs(j-o)<=e,q=Math.abs(l-m)<=e,r=Math.abs(i-n)<=e,s=Math.abs(k-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k}).left-c.margins.left}var t=
+p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(j-m)<=e;q=Math.abs(l-o)<=e;r=Math.abs(i-g)<=e;s=Math.abs(k-n)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:j,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:l-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:i}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:k-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[h].snapping&&
+(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=p||q||r||s||t}else{c.snapElements[h].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[h].item}));c.snapElements[h].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
+10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
+;/*
+ * jQuery UI Resizable 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.widget.js
+ */
+(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
+_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
+top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
+this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
+nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
+String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),k=0;k=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,k);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){e(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};
+if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),
+d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=
+this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:
+this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",
+b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;
+f={width:c.size.width-(f?0:c.sizeDiff.width),height:c.size.height-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",
+b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(l(b.left))this.position.left=b.left;if(l(b.top))this.position.top=b.top;if(l(b.height))this.size.height=b.height;if(l(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=
+a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,d=l(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=l(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=l(b.width)&&a.minWidth&&a.minWidth>b.width,h=l(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,
+k=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&k)b.left=i-a.minWidth;if(d&&k)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),
+c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=
+this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+
+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,
+arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,
+{version:"1.8.4"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,
+function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var k=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:k.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=
+(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(k.css("position"))){c._revertToRelativePosition=true;k.css({position:"absolute",top:"auto",left:"auto"})}k.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=
+false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-
+a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",
+b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top",
+"Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,
+f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=
+a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+
+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&
+e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",
+height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=
+d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},l=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
+;/*
+ * jQuery UI Dialog 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ *  jquery.ui.button.js
+ *     jquery.ui.draggable.js
+ *     jquery.ui.mouse.js
+ *     jquery.ui.position.js
+ *     jquery.ui.resizable.js
+ */
+(function(c,j){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");
+if(typeof this.originalTitle!=="string")this.originalTitle="";var a=this,b=a.options,d=b.title||a.originalTitle||"&#160;",f=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(i){a.moveToTop(false,
+i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var e=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);
+return false}).appendTo(e);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",f).html(d).prependTo(e);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;e.find("*").add(e).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&
+g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");
+b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,f=d.options;if(f.modal&&!a||!f.stack&&!f.modal)return d._trigger("focus",b);if(f.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=
+f.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);
+a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(f){if(f.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),e=g.filter(":first");g=g.filter(":last");if(f.target===g[0]&&!f.shiftKey){e.focus(1);return false}else if(f.target===e[0]&&f.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,
+f=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a,function(e,h){e=c('<button type="button"></button>').text(e).click(function(){h.apply(b.element[0],arguments)}).appendTo(g);c.fn.button&&e.button()});f.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(e){return{position:e.position,
+offset:e.offset}}var b=this,d=b.options,f=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(e,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",e,a(h))},drag:function(e,h){b._trigger("drag",e,a(h))},stop:function(e,h){d.position=[h.position.left-f.scrollLeft(),h.position.top-f.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);
+b._trigger("dragStop",e,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}a=a===j?this.options.resizable:a;var d=this,f=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:d._minHeight(),
+handles:a,start:function(e,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",e,b(h))},resize:function(e,h){d._trigger("resize",e,b(h))},stop:function(e,h){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();d._trigger("resizeStop",e,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,
+a.height)},_position:function(a){var b=[],d=[0,0],f;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,e){if(+b[g]===b[g]){d[g]=b[g];b[g]=e}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a);
+f||this.uiDialog.hide()},_setOption:function(a,b){var d=this,f=d.uiDialog,g=f.is(":data(resizable)"),e=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);e=true;break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":f.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case "draggable":b?
+d._makeDraggable():f.draggable("destroy");break;case "height":e=true;break;case "maxHeight":g&&f.resizable("option","maxHeight",b);e=true;break;case "maxWidth":g&&f.resizable("option","maxWidth",b);e=true;break;case "minHeight":g&&f.resizable("option","minHeight",b);e=true;break;case "minWidth":g&&f.resizable("option","minWidth",b);e=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&f.resizable("destroy");g&&typeof b==="string"&&f.resizable("option","handles",b);!g&&b!==false&&
+d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break;case "width":e=true;break}c.Widget.prototype._setOption.apply(d,arguments);e&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-
+b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.4",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
+create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
+height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
+b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,
+function(){a=a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+;
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
new file mode 100644 (file)
index 0000000..954e22d
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
new file mode 100644 (file)
index 0000000..64ece57
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_flat_10_000000_40x100.png
new file mode 100644 (file)
index 0000000..abdc010
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_flat_10_000000_40x100.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png
new file mode 100644 (file)
index 0000000..9b383f4
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png
new file mode 100644 (file)
index 0000000..a23baad
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644 (file)
index 0000000..42ccba2
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png
new file mode 100644 (file)
index 0000000..1b1972b
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
new file mode 100644 (file)
index 0000000..f127367
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
new file mode 100644 (file)
index 0000000..359397a
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_222222_256x240.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_222222_256x240.png
new file mode 100644 (file)
index 0000000..b273ff1
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_222222_256x240.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_228ef1_256x240.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_228ef1_256x240.png
new file mode 100644 (file)
index 0000000..a641a37
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_228ef1_256x240.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ef8c08_256x240.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ef8c08_256x240.png
new file mode 100644 (file)
index 0000000..85e63e9
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ef8c08_256x240.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffd27a_256x240.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffd27a_256x240.png
new file mode 100644 (file)
index 0000000..e117eff
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffd27a_256x240.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffffff_256x240.png b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffffff_256x240.png
new file mode 100644 (file)
index 0000000..42f8f99
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/images/ui-icons_ffffff_256x240.png differ
diff --git a/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css b/addon/js_upload/file-uploader/tests/jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css
new file mode 100644 (file)
index 0000000..39bc7be
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
+.ui-widget-content a { color: #333333; }
+.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-right {  -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
+.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
+ * jQuery UI Resizable @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Dialog @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative;  }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } 
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
diff --git a/addon/js_upload/file-uploader/tests/qunit/package.json b/addon/js_upload/file-uploader/tests/qunit/package.json
new file mode 100644 (file)
index 0000000..b6044c8
--- /dev/null
@@ -0,0 +1,21 @@
+{
+       "name": "qunit",
+       "author": {
+               "name": "John Resig",
+               "email": "jeresig@gmail.com",
+               "url": "http://ejohn.org/"
+       },
+       "maintainer": {
+               "name": "Jörn Zaefferer",
+               "email": "joern.zaefferer@googlemail.com",
+               "url": "http://bassistance.de/"
+       },
+       "url": "http://docs.jquery.com/QUnit",
+       "license": {
+               "name": "MIT",
+               "url": "http://www.opensource.org/licenses/mit-license.php"
+       },
+       "description": "An easy-to-use JavaScript Unit Testing framework.",
+       "keywords": [ "testing", "unit", "jquery" ],
+       "lib": "qunit"
+}
diff --git a/addon/js_upload/file-uploader/tests/qunit/qunit/qunit.css b/addon/js_upload/file-uploader/tests/qunit/qunit/qunit.css
new file mode 100644 (file)
index 0000000..5714bf4
--- /dev/null
@@ -0,0 +1,119 @@
+
+ol#qunit-tests {
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       margin:0;
+       padding:0;
+       list-style-position:inside;
+
+       font-size: smaller;
+}
+ol#qunit-tests li{
+       padding:0.4em 0.5em 0.4em 2.5em;
+       border-bottom:1px solid #fff;
+       font-size:small;
+       list-style-position:inside;
+}
+ol#qunit-tests li ol{
+       box-shadow: inset 0px 2px 13px #999;
+       -moz-box-shadow: inset 0px 2px 13px #999;
+       -webkit-box-shadow: inset 0px 2px 13px #999;
+       margin-top:0.5em;
+       margin-left:0;
+       padding:0.5em;
+       background-color:#fff;
+       border-radius:15px;
+       -moz-border-radius: 15px;
+       -webkit-border-radius: 15px;
+}
+ol#qunit-tests li li{
+       border-bottom:none;
+       margin:0.5em;
+       background-color:#fff;
+       list-style-position: inside;
+       padding:0.4em 0.5em 0.4em 0.5em;
+}
+
+ol#qunit-tests li li.pass{
+       border-left:26px solid #C6E746;
+       background-color:#fff;
+       color:#5E740B;
+       }
+ol#qunit-tests li li.fail{
+       border-left:26px solid #EE5757;
+       background-color:#fff;
+       color:#710909;
+}
+ol#qunit-tests li.pass{
+       background-color:#D2E0E6;
+       color:#528CE0;
+}
+ol#qunit-tests li.fail{
+       background-color:#EE5757;
+       color:#000;
+}
+ol#qunit-tests li strong {
+       cursor:pointer;
+}
+h1#qunit-header{
+       background-color:#0d3349;
+       margin:0;
+       padding:0.5em 0 0.5em 1em;
+       color:#fff;
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       border-top-right-radius:15px;
+       border-top-left-radius:15px;
+       -moz-border-radius-topright:15px;
+       -moz-border-radius-topleft:15px;
+       -webkit-border-top-right-radius:15px;
+       -webkit-border-top-left-radius:15px;
+       text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
+}
+h2#qunit-banner{
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       height:5px;
+       margin:0;
+       padding:0;
+}
+h2#qunit-banner.qunit-pass{
+       background-color:#C6E746;
+}
+h2#qunit-banner.qunit-fail, #qunit-testrunner-toolbar {
+       background-color:#EE5757;
+}
+#qunit-testrunner-toolbar {
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       padding:0;
+       /*width:80%;*/
+       padding:0em 0 0.5em 2em;
+       font-size: small;
+}
+h2#qunit-userAgent {
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       background-color:#2b81af;
+       margin:0;
+       padding:0;
+       color:#fff;
+       font-size: small;
+       padding:0.5em 0 0.5em 2.5em;
+       text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+p#qunit-testresult{
+       font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
+       margin:0;
+       font-size: small;
+       color:#2b81af;
+       border-bottom-right-radius:15px;
+       border-bottom-left-radius:15px;
+       -moz-border-radius-bottomright:15px;
+       -moz-border-radius-bottomleft:15px;
+       -webkit-border-bottom-right-radius:15px;
+       -webkit-border-bottom-left-radius:15px;
+       background-color:#D2E0E6;
+       padding:0.5em 0.5em 0.5em 2.5em;
+}
+strong b.fail{
+       color:#710909;
+       }
+strong b.pass{
+       color:#5E740B;
+       }
diff --git a/addon/js_upload/file-uploader/tests/qunit/qunit/qunit.js b/addon/js_upload/file-uploader/tests/qunit/qunit/qunit.js
new file mode 100644 (file)
index 0000000..9ef5f8d
--- /dev/null
@@ -0,0 +1,1069 @@
+/*
+ * QUnit - A JavaScript Unit Testing Framework
+ * 
+ * http://docs.jquery.com/QUnit
+ *
+ * Copyright (c) 2009 John Resig, Jörn Zaefferer
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ */
+
+(function(window) {
+
+var QUnit = {
+
+       // Initialize the configuration options
+       init: function() {
+               config = {
+                       stats: { all: 0, bad: 0 },
+                       moduleStats: { all: 0, bad: 0 },
+                       started: +new Date,
+                       updateRate: 1000,
+                       blocking: false,
+                       autorun: false,
+                       assertions: [],
+                       filters: [],
+                       queue: []
+               };
+
+               var tests = id("qunit-tests"),
+                       banner = id("qunit-banner"),
+                       result = id("qunit-testresult");
+
+               if ( tests ) {
+                       tests.innerHTML = "";
+               }
+
+               if ( banner ) {
+                       banner.className = "";
+               }
+
+               if ( result ) {
+                       result.parentNode.removeChild( result );
+               }
+       },
+       
+       // call on start of module test to prepend name to all tests
+       module: function(name, testEnvironment) {
+               config.currentModule = name;
+
+               synchronize(function() {
+                       if ( config.currentModule ) {
+                               QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
+                       }
+
+                       config.currentModule = name;
+                       config.moduleTestEnvironment = testEnvironment;
+                       config.moduleStats = { all: 0, bad: 0 };
+
+                       QUnit.moduleStart( name, testEnvironment );
+               });
+       },
+
+       asyncTest: function(testName, expected, callback) {
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = 0;
+               }
+
+               QUnit.test(testName, expected, callback, true);
+       },
+       
+       test: function(testName, expected, callback, async) {
+               var name = testName, testEnvironment, testEnvironmentArg;
+
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = null;
+               }
+               // is 2nd argument a testEnvironment?
+               if ( expected && typeof expected === 'object') {
+                       testEnvironmentArg =  expected;
+                       expected = null;
+               }
+
+               if ( config.currentModule ) {
+                       name = config.currentModule + " module: " + name;
+               }
+
+               if ( !validTest(name) ) {
+                       return;
+               }
+
+               synchronize(function() {
+                       QUnit.testStart( testName );
+
+                       testEnvironment = extend({
+                               setup: function() {},
+                               teardown: function() {}
+                       }, config.moduleTestEnvironment);
+                       if (testEnvironmentArg) {
+                               extend(testEnvironment,testEnvironmentArg);
+                       }
+
+                       // allow utility functions to access the current test environment
+                       QUnit.current_testEnvironment = testEnvironment;
+                       
+                       config.assertions = [];
+                       config.expected = expected;
+
+                       try {
+                               if ( !config.pollution ) {
+                                       saveGlobal();
+                               }
+
+                               testEnvironment.setup.call(testEnvironment);
+                       } catch(e) {
+                               QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
+                       }
+
+                       if ( async ) {
+                               QUnit.stop();
+                       }
+
+                       try {
+                               callback.call(testEnvironment);
+                       } catch(e) {
+                               fail("Test " + name + " died, exception and test follows", e, callback);
+                               QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
+                               // else next test will carry the responsibility
+                               saveGlobal();
+
+                               // Restart the tests if they're blocking
+                               if ( config.blocking ) {
+                                       start();
+                               }
+                       }
+               });
+
+               synchronize(function() {
+                       try {
+                               checkPollution();
+                               testEnvironment.teardown.call(testEnvironment);
+                       } catch(e) {
+                               QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
+                       }
+
+                       try {
+                               QUnit.reset();
+                       } catch(e) {
+                               fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
+                       }
+
+                       if ( config.expected && config.expected != config.assertions.length ) {
+                               QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
+                       }
+
+                       var good = 0, bad = 0,
+                               tests = id("qunit-tests");
+
+                       config.stats.all += config.assertions.length;
+                       config.moduleStats.all += config.assertions.length;
+
+                       if ( tests ) {
+                               var ol  = document.createElement("ol");
+                               ol.style.display = "none";
+
+                               for ( var i = 0; i < config.assertions.length; i++ ) {
+                                       var assertion = config.assertions[i];
+
+                                       var li = document.createElement("li");
+                                       li.className = assertion.result ? "pass" : "fail";
+                                       li.appendChild(document.createTextNode(assertion.message || "(no message)"));
+                                       ol.appendChild( li );
+
+                                       if ( assertion.result ) {
+                                               good++;
+                                       } else {
+                                               bad++;
+                                               config.stats.bad++;
+                                               config.moduleStats.bad++;
+                                       }
+                               }
+
+                               var b = document.createElement("strong");
+                               b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>";
+                               
+                               addEvent(b, "click", function() {
+                                       var next = b.nextSibling, display = next.style.display;
+                                       next.style.display = display === "none" ? "block" : "none";
+                               });
+                               
+                               addEvent(b, "dblclick", function(e) {
+                                       var target = e && e.target ? e.target : window.event.srcElement;
+                                       if ( target.nodeName.toLowerCase() === "strong" ) {
+                                               var text = "", node = target.firstChild;
+
+                                               while ( node.nodeType === 3 ) {
+                                                       text += node.nodeValue;
+                                                       node = node.nextSibling;
+                                               }
+
+                                               text = text.replace(/(^\s*|\s*$)/g, "");
+
+                                               if ( window.location ) {
+                                                       window.location.href = window.location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent(text);
+                                               }
+                                       }
+                               });
+
+                               var li = document.createElement("li");
+                               li.className = bad ? "fail" : "pass";
+                               li.appendChild( b );
+                               li.appendChild( ol );
+                               tests.appendChild( li );
+
+                               if ( bad ) {
+                                       var toolbar = id("qunit-testrunner-toolbar");
+                                       if ( toolbar ) {
+                                               toolbar.style.display = "block";
+                                               id("qunit-filter-pass").disabled = null;
+                                               id("qunit-filter-missing").disabled = null;
+                                       }
+                               }
+
+                       } else {
+                               for ( var i = 0; i < config.assertions.length; i++ ) {
+                                       if ( !config.assertions[i].result ) {
+                                               bad++;
+                                               config.stats.bad++;
+                                               config.moduleStats.bad++;
+                                       }
+                               }
+                       }
+
+                       QUnit.testDone( testName, bad, config.assertions.length );
+
+                       if ( !window.setTimeout && !config.queue.length ) {
+                               done();
+                       }
+               });
+
+               if ( window.setTimeout && !config.doneTimer ) {
+                       config.doneTimer = window.setTimeout(function(){
+                               if ( !config.queue.length ) {
+                                       done();
+                               } else {
+                                       synchronize( done );
+                               }
+                       }, 13);
+               }
+       },
+       
+       /**
+        * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
+        */
+       expect: function(asserts) {
+               config.expected = asserts;
+       },
+
+       /**
+        * Asserts true.
+        * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+        */
+       ok: function(a, msg) {
+               QUnit.log(a, msg);
+
+               config.assertions.push({
+                       result: !!a,
+                       message: msg
+               });
+       },
+
+       /**
+        * Checks that the first two arguments are equal, with an optional message.
+        * Prints out both actual and expected values.
+        *
+        * Prefered to ok( actual == expected, message )
+        *
+        * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
+        *
+        * @param Object actual
+        * @param Object expected
+        * @param String message (optional)
+        */
+       equal: function(actual, expected, message) {
+               push(expected == actual, actual, expected, message);
+       },
+
+       notEqual: function(actual, expected, message) {
+               push(expected != actual, actual, expected, message);
+       },
+       
+       deepEqual: function(a, b, message) {
+               push(QUnit.equiv(a, b), a, b, message);
+       },
+
+       notDeepEqual: function(a, b, message) {
+               push(!QUnit.equiv(a, b), a, b, message);
+       },
+
+       strictEqual: function(actual, expected, message) {
+               push(expected === actual, actual, expected, message);
+       },
+
+       notStrictEqual: function(actual, expected, message) {
+               push(expected !== actual, actual, expected, message);
+       },
+       
+       start: function() {
+               // A slight delay, to avoid any current callbacks
+               if ( window.setTimeout ) {
+                       window.setTimeout(function() {
+                               if ( config.timeout ) {
+                                       clearTimeout(config.timeout);
+                               }
+
+                               config.blocking = false;
+                               process();
+                       }, 13);
+               } else {
+                       config.blocking = false;
+                       process();
+               }
+       },
+       
+       stop: function(timeout) {
+               config.blocking = true;
+
+               if ( timeout && window.setTimeout ) {
+                       config.timeout = window.setTimeout(function() {
+                               QUnit.ok( false, "Test timed out" );
+                               QUnit.start();
+                       }, timeout);
+               }
+       },
+       
+       /**
+        * Resets the test setup. Useful for tests that modify the DOM.
+        */
+       reset: function() {
+               if ( window.jQuery ) {
+                       jQuery("#main").html( config.fixture );
+                       jQuery.event.global = {};
+                       jQuery.ajaxSettings = extend({}, config.ajaxSettings);
+               }
+       },
+       
+       /**
+        * Trigger an event on an element.
+        *
+        * @example triggerEvent( document.body, "click" );
+        *
+        * @param DOMElement elem
+        * @param String type
+        */
+       triggerEvent: function( elem, type, event ) {
+               if ( document.createEvent ) {
+                       event = document.createEvent("MouseEvents");
+                       event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+                               0, 0, 0, 0, 0, false, false, false, false, 0, null);
+                       elem.dispatchEvent( event );
+
+               } else if ( elem.fireEvent ) {
+                       elem.fireEvent("on"+type);
+               }
+       },
+       
+       // Safe object type checking
+       is: function( type, obj ) {
+               return Object.prototype.toString.call( obj ) === "[object "+ type +"]";
+       },
+       
+       // Logging callbacks
+       done: function(failures, total) {},
+       log: function(result, message) {},
+       testStart: function(name) {},
+       testDone: function(name, failures, total) {},
+       moduleStart: function(name, testEnvironment) {},
+       moduleDone: function(name, failures, total) {}
+};
+
+// Backwards compatibility, deprecated
+QUnit.equals = QUnit.equal;
+QUnit.same = QUnit.deepEqual;
+
+// Maintain internal state
+var config = {
+       // The queue of tests to run
+       queue: [],
+
+       // block until document ready
+       blocking: true
+};
+
+// Load paramaters
+(function() {
+       var location = window.location || { search: "", protocol: "file:" },
+               GETParams = location.search.slice(1).split('&');
+
+       for ( var i = 0; i < GETParams.length; i++ ) {
+               GETParams[i] = decodeURIComponent( GETParams[i] );
+               if ( GETParams[i] === "noglobals" ) {
+                       GETParams.splice( i, 1 );
+                       i--;
+                       config.noglobals = true;
+               } else if ( GETParams[i].search('=') > -1 ) {
+                       GETParams.splice( i, 1 );
+                       i--;
+               }
+       }
+       
+       // restrict modules/tests by get parameters
+       config.filters = GETParams;
+       
+       // Figure out if we're running the tests from a server or not
+       QUnit.isLocal = !!(location.protocol === 'file:');
+})();
+
+// Expose the API as global variables, unless an 'exports'
+// object exists, in that case we assume we're in CommonJS
+if ( typeof exports === "undefined" || typeof require === "undefined" ) {
+       extend(window, QUnit);
+       window.QUnit = QUnit;
+} else {
+       extend(exports, QUnit);
+       exports.QUnit = QUnit;
+}
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+       config.autorun = true;
+}
+
+addEvent(window, "load", function() {
+       // Initialize the config, saving the execution queue
+       var oldconfig = extend({}, config);
+       QUnit.init();
+       extend(config, oldconfig);
+
+       config.blocking = false;
+
+       var userAgent = id("qunit-userAgent");
+       if ( userAgent ) {
+               userAgent.innerHTML = navigator.userAgent;
+       }
+       
+       var toolbar = id("qunit-testrunner-toolbar");
+       if ( toolbar ) {
+               toolbar.style.display = "none";
+               
+               var filter = document.createElement("input");
+               filter.type = "checkbox";
+               filter.id = "qunit-filter-pass";
+               filter.disabled = true;
+               addEvent( filter, "click", function() {
+                       var li = document.getElementsByTagName("li");
+                       for ( var i = 0; i < li.length; i++ ) {
+                               if ( li[i].className.indexOf("pass") > -1 ) {
+                                       li[i].style.display = filter.checked ? "none" : "";
+                               }
+                       }
+               });
+               toolbar.appendChild( filter );
+
+               var label = document.createElement("label");
+               label.setAttribute("for", "qunit-filter-pass");
+               label.innerHTML = "Hide passed tests";
+               toolbar.appendChild( label );
+
+               var missing = document.createElement("input");
+               missing.type = "checkbox";
+               missing.id = "qunit-filter-missing";
+               missing.disabled = true;
+               addEvent( missing, "click", function() {
+                       var li = document.getElementsByTagName("li");
+                       for ( var i = 0; i < li.length; i++ ) {
+                               if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
+                                       li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
+                               }
+                       }
+               });
+               toolbar.appendChild( missing );
+
+               label = document.createElement("label");
+               label.setAttribute("for", "qunit-filter-missing");
+               label.innerHTML = "Hide missing tests (untested code is broken code)";
+               toolbar.appendChild( label );
+       }
+
+       var main = id('main');
+       if ( main ) {
+               config.fixture = main.innerHTML;
+       }
+
+       if ( window.jQuery ) {
+               config.ajaxSettings = window.jQuery.ajaxSettings;
+       }
+
+       QUnit.start();
+});
+
+function done() {
+       if ( config.doneTimer && window.clearTimeout ) {
+               window.clearTimeout( config.doneTimer );
+               config.doneTimer = null;
+       }
+
+       if ( config.queue.length ) {
+               config.doneTimer = window.setTimeout(function(){
+                       if ( !config.queue.length ) {
+                               done();
+                       } else {
+                               synchronize( done );
+                       }
+               }, 13);
+
+               return;
+       }
+
+       config.autorun = true;
+
+       // Log the last module results
+       if ( config.currentModule ) {
+               QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
+       }
+
+       var banner = id("qunit-banner"),
+               tests = id("qunit-tests"),
+               html = ['Tests completed in ',
+               +new Date - config.started, ' milliseconds.<br/>',
+               '<span class="passed">', config.stats.all - config.stats.bad, '</span> tests of <span class="total">', config.stats.all, '</span> passed, <span class="failed">', config.stats.bad,'</span> failed.'].join('');
+
+       if ( banner ) {
+               banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
+       }
+
+       if ( tests ) {  
+               var result = id("qunit-testresult");
+
+               if ( !result ) {
+                       result = document.createElement("p");
+                       result.id = "qunit-testresult";
+                       result.className = "result";
+                       tests.parentNode.insertBefore( result, tests.nextSibling );
+               }
+
+               result.innerHTML = html;
+       }
+
+       QUnit.done( config.stats.bad, config.stats.all );
+}
+
+function validTest( name ) {
+       var i = config.filters.length,
+               run = false;
+
+       if ( !i ) {
+               return true;
+       }
+       
+       while ( i-- ) {
+               var filter = config.filters[i],
+                       not = filter.charAt(0) == '!';
+
+               if ( not ) {
+                       filter = filter.slice(1);
+               }
+
+               if ( name.indexOf(filter) !== -1 ) {
+                       return !not;
+               }
+
+               if ( not ) {
+                       run = true;
+               }
+       }
+
+       return run;
+}
+
+function push(result, actual, expected, message) {
+       message = message || (result ? "okay" : "failed");
+       QUnit.ok( result, result ? message + ": " + QUnit.jsDump.parse(expected) : message + ", expected: " + QUnit.jsDump.parse(expected) + " result: " + QUnit.jsDump.parse(actual) );
+}
+
+function synchronize( callback ) {
+       config.queue.push( callback );
+
+       if ( config.autorun && !config.blocking ) {
+               process();
+       }
+}
+
+function process() {
+       var start = (new Date()).getTime();
+
+       while ( config.queue.length && !config.blocking ) {
+               if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
+                       config.queue.shift()();
+
+               } else {
+                       setTimeout( process, 13 );
+                       break;
+               }
+       }
+}
+
+function saveGlobal() {
+       config.pollution = [];
+       
+       if ( config.noglobals ) {
+               for ( var key in window ) {
+                       config.pollution.push( key );
+               }
+       }
+}
+
+function checkPollution( name ) {
+       var old = config.pollution;
+       saveGlobal();
+       
+       var newGlobals = diff( old, config.pollution );
+       if ( newGlobals.length > 0 ) {
+               ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
+               config.expected++;
+       }
+
+       var deletedGlobals = diff( config.pollution, old );
+       if ( deletedGlobals.length > 0 ) {
+               ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
+               config.expected++;
+       }
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+       var result = a.slice();
+       for ( var i = 0; i < result.length; i++ ) {
+               for ( var j = 0; j < b.length; j++ ) {
+                       if ( result[i] === b[j] ) {
+                               result.splice(i, 1);
+                               i--;
+                               break;
+                       }
+               }
+       }
+       return result;
+}
+
+function fail(message, exception, callback) {
+       if ( typeof console !== "undefined" && console.error && console.warn ) {
+               console.error(message);
+               console.error(exception);
+               console.warn(callback.toString());
+
+       } else if ( window.opera && opera.postError ) {
+               opera.postError(message, exception, callback.toString);
+       }
+}
+
+function extend(a, b) {
+       for ( var prop in b ) {
+               a[prop] = b[prop];
+       }
+
+       return a;
+}
+
+function addEvent(elem, type, fn) {
+       if ( elem.addEventListener ) {
+               elem.addEventListener( type, fn, false );
+       } else if ( elem.attachEvent ) {
+               elem.attachEvent( "on" + type, fn );
+       } else {
+               fn();
+       }
+}
+
+function id(name) {
+       return !!(typeof document !== "undefined" && document && document.getElementById) &&
+               document.getElementById( name );
+}
+
+// Test for equality any JavaScript type.
+// Discussions and reference: http://philrathe.com/articles/equiv
+// Test suites: http://philrathe.com/tests/equiv
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = function () {
+
+    var innerEquiv; // the real equiv function
+    var callers = []; // stack to decide between skip/abort functions
+    var parents = []; // stack to avoiding loops from circular referencing
+
+
+    // Determine what is o.
+    function hoozit(o) {
+        if (QUnit.is("String", o)) {
+            return "string";
+            
+        } else if (QUnit.is("Boolean", o)) {
+            return "boolean";
+
+        } else if (QUnit.is("Number", o)) {
+
+            if (isNaN(o)) {
+                return "nan";
+            } else {
+                return "number";
+            }
+
+        } else if (typeof o === "undefined") {
+            return "undefined";
+
+        // consider: typeof null === object
+        } else if (o === null) {
+            return "null";
+
+        // consider: typeof [] === object
+        } else if (QUnit.is( "Array", o)) {
+            return "array";
+        
+        // consider: typeof new Date() === object
+        } else if (QUnit.is( "Date", o)) {
+            return "date";
+
+        // consider: /./ instanceof Object;
+        //           /./ instanceof RegExp;
+        //          typeof /./ === "function"; // => false in IE and Opera,
+        //                                          true in FF and Safari
+        } else if (QUnit.is( "RegExp", o)) {
+            return "regexp";
+
+        } else if (typeof o === "object") {
+            return "object";
+
+        } else if (QUnit.is( "Function", o)) {
+            return "function";
+        } else {
+            return undefined;
+        }
+    }
+
+    // Call the o related callback with the given arguments.
+    function bindCallbacks(o, callbacks, args) {
+        var prop = hoozit(o);
+        if (prop) {
+            if (hoozit(callbacks[prop]) === "function") {
+                return callbacks[prop].apply(callbacks, args);
+            } else {
+                return callbacks[prop]; // or undefined
+            }
+        }
+    }
+    
+    var callbacks = function () {
+
+        // for string, boolean, number and null
+        function useStrictEquality(b, a) {
+            if (b instanceof a.constructor || a instanceof b.constructor) {
+                // to catch short annotaion VS 'new' annotation of a declaration
+                // e.g. var i = 1;
+                //      var j = new Number(1);
+                return a == b;
+            } else {
+                return a === b;
+            }
+        }
+
+        return {
+            "string": useStrictEquality,
+            "boolean": useStrictEquality,
+            "number": useStrictEquality,
+            "null": useStrictEquality,
+            "undefined": useStrictEquality,
+
+            "nan": function (b) {
+                return isNaN(b);
+            },
+
+            "date": function (b, a) {
+                return hoozit(b) === "date" && a.valueOf() === b.valueOf();
+            },
+
+            "regexp": function (b, a) {
+                return hoozit(b) === "regexp" &&
+                    a.source === b.source && // the regex itself
+                    a.global === b.global && // and its modifers (gmi) ...
+                    a.ignoreCase === b.ignoreCase &&
+                    a.multiline === b.multiline;
+            },
+
+            // - skip when the property is a method of an instance (OOP)
+            // - abort otherwise,
+            //   initial === would have catch identical references anyway
+            "function": function () {
+                var caller = callers[callers.length - 1];
+                return caller !== Object &&
+                        typeof caller !== "undefined";
+            },
+
+            "array": function (b, a) {
+                var i, j, loop;
+                var len;
+
+                // b could be an object literal here
+                if ( ! (hoozit(b) === "array")) {
+                    return false;
+                }   
+                
+                len = a.length;
+                if (len !== b.length) { // safe and faster
+                    return false;
+                }
+                
+                //track reference to avoid circular references
+                parents.push(a);
+                for (i = 0; i < len; i++) {
+                    loop = false;
+                    for(j=0;j<parents.length;j++){
+                        if(parents[j] === a[i]){
+                            loop = true;//dont rewalk array
+                        }
+                    }
+                    if (!loop && ! innerEquiv(a[i], b[i])) {
+                        parents.pop();
+                        return false;
+                    }
+                }
+                parents.pop();
+                return true;
+            },
+
+            "object": function (b, a) {
+                var i, j, loop;
+                var eq = true; // unless we can proove it
+                var aProperties = [], bProperties = []; // collection of strings
+
+                // comparing constructors is more strict than using instanceof
+                if ( a.constructor !== b.constructor) {
+                    return false;
+                }
+
+                // stack constructor before traversing properties
+                callers.push(a.constructor);
+                //track reference to avoid circular references
+                parents.push(a);
+                
+                for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
+                    loop = false;
+                    for(j=0;j<parents.length;j++){
+                        if(parents[j] === a[i])
+                            loop = true; //don't go down the same path twice
+                    }
+                    aProperties.push(i); // collect a's properties
+
+                    if (!loop && ! innerEquiv(a[i], b[i])) {
+                        eq = false;
+                        break;
+                    }
+                }
+
+                callers.pop(); // unstack, we are done
+                parents.pop();
+
+                for (i in b) {
+                    bProperties.push(i); // collect b's properties
+                }
+
+                // Ensures identical properties name
+                return eq && innerEquiv(aProperties.sort(), bProperties.sort());
+            }
+        };
+    }();
+
+    innerEquiv = function () { // can take multiple arguments
+        var args = Array.prototype.slice.apply(arguments);
+        if (args.length < 2) {
+            return true; // end transition
+        }
+
+        return (function (a, b) {
+            if (a === b) {
+                return true; // catch the most you can
+            } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
+                return false; // don't lose time with error prone cases
+            } else {
+                return bindCallbacks(a, callbacks, [b, a]);
+            }
+
+        // apply transition with (1..n) arguments
+        })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
+    };
+
+    return innerEquiv;
+
+}();
+
+/**
+ * jsDump
+ * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
+ * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
+ * Date: 5/15/2008
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+       function quote( str ) {
+               return '"' + str.toString().replace(/"/g, '\\"') + '"';
+       };
+       function literal( o ) {
+               return o + '';  
+       };
+       function join( pre, arr, post ) {
+               var s = jsDump.separator(),
+                       base = jsDump.indent(),
+                       inner = jsDump.indent(1);
+               if ( arr.join )
+                       arr = arr.join( ',' + s + inner );
+               if ( !arr )
+                       return pre + post;
+               return [ pre, inner + arr, base + post ].join(s);
+       };
+       function array( arr ) {
+               var i = arr.length,     ret = Array(i);                                 
+               this.up();
+               while ( i-- )
+                       ret[i] = this.parse( arr[i] );                          
+               this.down();
+               return join( '[', ret, ']' );
+       };
+       
+       var reName = /^function (\w+)/;
+       
+       var jsDump = {
+               parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance
+                       var     parser = this.parsers[ type || this.typeOf(obj) ];
+                       type = typeof parser;                   
+                       
+                       return type == 'function' ? parser.call( this, obj ) :
+                                  type == 'string' ? parser :
+                                  this.parsers.error;
+               },
+               typeOf:function( obj ) {
+                       var type;
+                       if ( obj === null ) {
+                               type = "null";
+                       } else if (typeof obj === "undefined") {
+                               type = "undefined";
+                       } else if (QUnit.is("RegExp", obj)) {
+                               type = "regexp";
+                       } else if (QUnit.is("Date", obj)) {
+                               type = "date";
+                       } else if (QUnit.is("Function", obj)) {
+                               type = "function";
+                       } else if (obj.setInterval && obj.document && !obj.nodeType) {
+                               type = "window";
+                       } else if (obj.nodeType === 9) {
+                               type = "document";
+                       } else if (obj.nodeType) {
+                               type = "node";
+                       } else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) {
+                               type = "array";
+                       } else {
+                               type = typeof obj;
+                       }
+                       return type;
+               },
+               separator:function() {
+                       return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
+               },
+               indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
+                       if ( !this.multiline )
+                               return '';
+                       var chr = this.indentChar;
+                       if ( this.HTML )
+                               chr = chr.replace(/\t/g,'   ').replace(/ /g,'&nbsp;');
+                       return Array( this._depth_ + (extra||0) ).join(chr);
+               },
+               up:function( a ) {
+                       this._depth_ += a || 1;
+               },
+               down:function( a ) {
+                       this._depth_ -= a || 1;
+               },
+               setParser:function( name, parser ) {
+                       this.parsers[name] = parser;
+               },
+               // The next 3 are exposed so you can use them
+               quote:quote, 
+               literal:literal,
+               join:join,
+               //
+               _depth_: 1,
+               // This is the list of parsers, to modify them, use jsDump.setParser
+               parsers:{
+                       window: '[Window]',
+                       document: '[Document]',
+                       error:'[ERROR]', //when no parser is found, shouldn't happen
+                       unknown: '[Unknown]',
+                       'null':'null',
+                       undefined:'undefined',
+                       'function':function( fn ) {
+                               var ret = 'function',
+                                       name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
+                               if ( name )
+                                       ret += ' ' + name;
+                               ret += '(';
+                               
+                               ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
+                               return join( ret, this.parse(fn,'functionCode'), '}' );
+                       },
+                       array: array,
+                       nodelist: array,
+                       arguments: array,
+                       object:function( map ) {
+                               var ret = [ ];
+                               this.up();
+                               for ( var key in map )
+                                       ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
+                               this.down();
+                               return join( '{', ret, '}' );
+                       },
+                       node:function( node ) {
+                               var open = this.HTML ? '&lt;' : '<',
+                                       close = this.HTML ? '&gt;' : '>';
+                                       
+                               var tag = node.nodeName.toLowerCase(),
+                                       ret = open + tag;
+                                       
+                               for ( var a in this.DOMAttrs ) {
+                                       var val = node[this.DOMAttrs[a]];
+                                       if ( val )
+                                               ret += ' ' + a + '=' + this.parse( val, 'attribute' );
+                               }
+                               return ret + close + open + '/' + tag + close;
+                       },
+                       functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
+                               var l = fn.length;
+                               if ( !l ) return '';                            
+                               
+                               var args = Array(l);
+                               while ( l-- )
+                                       args[l] = String.fromCharCode(97+l);//97 is 'a'
+                               return ' ' + args.join(', ') + ' ';
+                       },
+                       key:quote, //object calls it internally, the key part of an item in a map
+                       functionCode:'[code]', //function calls it internally, it's the content of the function
+                       attribute:quote, //node calls it internally, it's an html attribute value
+                       string:quote,
+                       date:quote,
+                       regexp:literal, //regex
+                       number:literal,
+                       'boolean':literal
+               },
+               DOMAttrs:{//attributes to dump from nodes, name=>realName
+                       id:'id',
+                       name:'name',
+                       'class':'className'
+               },
+               HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
+               indentChar:'   ',//indentation unit
+               multiline:false //if true, items in a collection, are separated by a \n, else just a space.
+       };
+
+       return jsDump;
+})();
+
+})(this);
diff --git a/addon/js_upload/file-uploader/tests/qunit/test/index.html b/addon/js_upload/file-uploader/tests/qunit/test/index.html
new file mode 100644 (file)
index 0000000..8a9f865
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+       <title>QUnit Test Suite</title>
+       <link rel="stylesheet" href="../qunit/qunit.css" type="text/css" media="screen">
+       <script type="text/javascript" src="../qunit/qunit.js"></script>
+       <script type="text/javascript" src="test.js"></script>
+       <script type="text/javascript" src="same.js"></script>
+</head>
+<body>
+       <h1 id="qunit-header">QUnit Test Suite</h1>
+       <h2 id="qunit-banner"></h2>
+       <div id="qunit-testrunner-toolbar"></div>
+       <h2 id="qunit-userAgent"></h2>
+       <ol id="qunit-tests"></ol>
+</body>
+</html>
diff --git a/addon/js_upload/file-uploader/tests/qunit/test/same.js b/addon/js_upload/file-uploader/tests/qunit/test/same.js
new file mode 100644 (file)
index 0000000..8f1b563
--- /dev/null
@@ -0,0 +1,1423 @@
+module("equiv");
+
+
+test("Primitive types and constants", function () {
+    equals(QUnit.equiv(null, null), true, "null");
+    equals(QUnit.equiv(null, {}), false, "null");
+    equals(QUnit.equiv(null, undefined), false, "null");
+    equals(QUnit.equiv(null, 0), false, "null");
+    equals(QUnit.equiv(null, false), false, "null");
+    equals(QUnit.equiv(null, ''), false, "null");
+    equals(QUnit.equiv(null, []), false, "null");
+
+    equals(QUnit.equiv(undefined, undefined), true, "undefined");
+    equals(QUnit.equiv(undefined, null), false, "undefined");
+    equals(QUnit.equiv(undefined, 0), false, "undefined");
+    equals(QUnit.equiv(undefined, false), false, "undefined");
+    equals(QUnit.equiv(undefined, {}), false, "undefined");
+    equals(QUnit.equiv(undefined, []), false, "undefined");
+    equals(QUnit.equiv(undefined, ""), false, "undefined");
+
+    // Nan usually doest not equal to Nan using the '==' operator.
+    // Only isNaN() is able to do it.
+    equals(QUnit.equiv(0/0, 0/0), true, "NaN"); // NaN VS NaN
+    equals(QUnit.equiv(1/0, 2/0), true, "Infinity"); // Infinity VS Infinity
+    equals(QUnit.equiv(-1/0, 2/0), false, "-Infinity, Infinity"); // -Infinity VS Infinity
+    equals(QUnit.equiv(-1/0, -2/0), true, "-Infinity, -Infinity"); // -Infinity VS -Infinity
+    equals(QUnit.equiv(0/0, 1/0), false, "NaN, Infinity"); // Nan VS Infinity
+    equals(QUnit.equiv(1/0, 0/0), false, "NaN, Infinity"); // Nan VS Infinity
+    equals(QUnit.equiv(0/0, null), false, "NaN");
+    equals(QUnit.equiv(0/0, undefined), false, "NaN");
+    equals(QUnit.equiv(0/0, 0), false, "NaN");
+    equals(QUnit.equiv(0/0, false), false, "NaN");
+    equals(QUnit.equiv(0/0, function () {}), false, "NaN");
+    equals(QUnit.equiv(1/0, null), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, undefined), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, 0), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, 1), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, false), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, true), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, function () {}), false, "NaN, Infinity");
+
+    equals(QUnit.equiv(0, 0), true, "number");
+    equals(QUnit.equiv(0, 1), false, "number");
+    equals(QUnit.equiv(1, 0), false, "number");
+    equals(QUnit.equiv(1, 1), true, "number");
+    equals(QUnit.equiv(1.1, 1.1), true, "number");
+    equals(QUnit.equiv(0.0000005, 0.0000005), true, "number");
+    equals(QUnit.equiv(0, ''), false, "number");
+    equals(QUnit.equiv(0, '0'), false, "number");
+    equals(QUnit.equiv(1, '1'), false, "number");
+    equals(QUnit.equiv(0, false), false, "number");
+    equals(QUnit.equiv(1, true), false, "number");
+
+    equals(QUnit.equiv(true, true), true, "boolean");
+    equals(QUnit.equiv(true, false), false, "boolean");
+    equals(QUnit.equiv(false, true), false, "boolean");
+    equals(QUnit.equiv(false, 0), false, "boolean");
+    equals(QUnit.equiv(false, null), false, "boolean");
+    equals(QUnit.equiv(false, undefined), false, "boolean");
+    equals(QUnit.equiv(true, 1), false, "boolean");
+    equals(QUnit.equiv(true, null), false, "boolean");
+    equals(QUnit.equiv(true, undefined), false, "boolean");
+
+    equals(QUnit.equiv('', ''), true, "string");
+    equals(QUnit.equiv('a', 'a'), true, "string");
+    equals(QUnit.equiv("foobar", "foobar"), true, "string");
+    equals(QUnit.equiv("foobar", "foo"), false, "string");
+    equals(QUnit.equiv('', 0), false, "string");
+    equals(QUnit.equiv('', false), false, "string");
+    equals(QUnit.equiv('', null), false, "string");
+    equals(QUnit.equiv('', undefined), false, "string");
+    
+    // Short annotation VS new annotation
+    equals(QUnit.equiv(0, new Number()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(), 0), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(1, new Number(1)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(1), 1), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(0), 1), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(0, new Number(1)), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(new String(), ""), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("", new String()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new String("My String"), "My String"), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("My String", new String("My String")), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("Bad String", new String("My String")), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new String("Bad String"), "My String"), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(false, new Boolean()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(), false), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(true)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(true), true), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(1)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(false, new Boolean(false)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(false), false), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(false, new Boolean(0)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(false)), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(false), true), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(new Object(), {}), true, "short annotation VS new annotation");
+    equals(QUnit.equiv({}, new Object()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Object(), {a:1}), false, "short annotation VS new annotation");
+    equals(QUnit.equiv({a:1}, new Object()), false, "short annotation VS new annotation");
+    equals(QUnit.equiv({a:undefined}, new Object()), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Object(), {a:undefined}), false, "short annotation VS new annotation");
+});
+
+test("Objects Basics.", function() {
+    equals(QUnit.equiv({}, {}), true);
+    equals(QUnit.equiv({}, null), false);
+    equals(QUnit.equiv({}, undefined), false);
+    equals(QUnit.equiv({}, 0), false);
+    equals(QUnit.equiv({}, false), false);
+
+    // This test is a hard one, it is very important
+    // REASONS:
+    //      1) They are of the same type "object"
+    //      2) [] instanceof Object is true
+    //      3) Their properties are the same (doesn't exists)
+    equals(QUnit.equiv({}, []), false);
+
+    equals(QUnit.equiv({a:1}, {a:1}), true);
+    equals(QUnit.equiv({a:1}, {a:"1"}), false);
+    equals(QUnit.equiv({a:[]}, {a:[]}), true);
+    equals(QUnit.equiv({a:{}}, {a:null}), false);
+    equals(QUnit.equiv({a:1}, {}), false);
+    equals(QUnit.equiv({}, {a:1}), false);
+
+    // Hard ones
+    equals(QUnit.equiv({a:undefined}, {}), false);
+    equals(QUnit.equiv({}, {a:undefined}), false);
+    equals(QUnit.equiv(
+        {
+            a: [{ bar: undefined }]
+        },
+        {
+            a: [{ bat: undefined }]
+        }
+    ), false);
+});
+
+
+test("Arrays Basics.", function() {
+
+    equals(QUnit.equiv([], []), true);
+
+    // May be a hard one, can invoke a crash at execution.
+    // because their types are both "object" but null isn't
+    // like a true object, it doesn't have any property at all.
+    equals(QUnit.equiv([], null), false);
+
+    equals(QUnit.equiv([], undefined), false);
+    equals(QUnit.equiv([], false), false);
+    equals(QUnit.equiv([], 0), false);
+    equals(QUnit.equiv([], ""), false);
+
+    // May be a hard one, but less hard
+    // than {} with [] (note the order)
+    equals(QUnit.equiv([], {}), false);
+
+    equals(QUnit.equiv([null],[]), false);
+    equals(QUnit.equiv([undefined],[]), false);
+    equals(QUnit.equiv([],[null]), false);
+    equals(QUnit.equiv([],[undefined]), false);
+    equals(QUnit.equiv([null],[undefined]), false);
+    equals(QUnit.equiv([[]],[[]]), true);
+    equals(QUnit.equiv([[],[],[]],[[],[],[]]), true);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]),
+                            true);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // shorter
+                            false);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // deepest element not an array
+                            false);
+
+    // same multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            true, "Multidimensional");
+
+    // different multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            '1',2,3,4,[                 // string instead of number
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            false, "Multidimensional");
+
+    // different multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,[                   // missing an element (4)
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            false, "Multidimensional");
+});
+
+test("Functions.", function() {
+    var f0 = function () {};
+    var f1 = function () {};
+
+    // f2 and f3 have the same code, formatted differently
+    var f2 = function () {var i = 0;};
+    var f3 = function () {
+        var i = 0 // this comment and no semicoma as difference
+    };
+
+    equals(QUnit.equiv(function() {}, function() {}), false, "Anonymous functions"); // exact source code
+    equals(QUnit.equiv(function() {}, function() {return true;}), false, "Anonymous functions");
+
+    equals(QUnit.equiv(f0, f0), true, "Function references"); // same references
+    equals(QUnit.equiv(f0, f1), false, "Function references"); // exact source code, different references
+    equals(QUnit.equiv(f2, f3), false, "Function references"); // equivalent source code, different references
+    equals(QUnit.equiv(f1, f2), false, "Function references"); // different source code, different references
+    equals(QUnit.equiv(function() {}, true), false);
+    equals(QUnit.equiv(function() {}, undefined), false);
+    equals(QUnit.equiv(function() {}, null), false);
+    equals(QUnit.equiv(function() {}, {}), false);
+});
+
+
+test("Date instances.", function() {
+    // Date, we don't need to test Date.parse() because it returns a number.
+    // Only test the Date instances by setting them a fix date.
+    // The date use is midnight January 1, 1970
+    
+    var d1 = new Date();
+    d1.setTime(0); // fix the date
+
+    var d2 = new Date();
+    d2.setTime(0); // fix the date
+
+    var d3 = new Date(); // The very now
+
+    // Anyway their types differs, just in case the code fails in the order in which it deals with date
+    equals(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 are different
+    // test same values date and different instances equality
+    equals(QUnit.equiv(d1, d2), true);
+    // test different date and different instances difference
+    equals(QUnit.equiv(d1, d3), false);
+});
+
+
+test("RegExp.", function() {
+    // Must test cases that imply those traps:
+    // var a = /./;
+    // a instanceof Object;        // Oops
+    // a instanceof RegExp;        // Oops
+    // typeof a === "function";    // Oops, false in IE and Opera, true in FF and Safari ("object")
+
+    // Tests same regex with same modifiers in different order
+    var r = /foo/;
+    var r5 = /foo/gim;
+    var r6 = /foo/gmi;
+    var r7 = /foo/igm;
+    var r8 = /foo/img;
+    var r9 = /foo/mig;
+    var r10 = /foo/mgi;
+    var ri1 = /foo/i;
+    var ri2 = /foo/i;
+    var rm1 = /foo/m;
+    var rm2 = /foo/m;
+    var rg1 = /foo/g;
+    var rg2 = /foo/g;
+
+    equals(QUnit.equiv(r5, r6), true, "Modifier order");
+    equals(QUnit.equiv(r5, r7), true, "Modifier order");
+    equals(QUnit.equiv(r5, r8), true, "Modifier order");
+    equals(QUnit.equiv(r5, r9), true, "Modifier order");
+    equals(QUnit.equiv(r5, r10), true, "Modifier order");
+    equals(QUnit.equiv(r, r5), false, "Modifier");
+
+    equals(QUnit.equiv(ri1, ri2), true, "Modifier");
+    equals(QUnit.equiv(r, ri1), false, "Modifier");
+    equals(QUnit.equiv(ri1, rm1), false, "Modifier");
+    equals(QUnit.equiv(r, rm1), false, "Modifier");
+    equals(QUnit.equiv(rm1, ri1), false, "Modifier");
+    equals(QUnit.equiv(rm1, rm2), true, "Modifier");
+    equals(QUnit.equiv(rg1, rm1), false, "Modifier");
+    equals(QUnit.equiv(rm1, rg1), false, "Modifier");
+    equals(QUnit.equiv(rg1, rg2), true, "Modifier");
+
+    // Different regex, same modifiers
+    var r11 = /[a-z]/gi;
+    var r13 = /[0-9]/gi; // oops! different
+    equals(QUnit.equiv(r11, r13), false, "Regex pattern");
+
+    var r14 = /0/ig;
+    var r15 = /"0"/ig; // oops! different
+    equals(QUnit.equiv(r14, r15), false, "Regex pattern");
+
+    var r1 = /[\n\r\u2028\u2029]/g;
+    var r2 = /[\n\r\u2028\u2029]/g;
+    var r3 = /[\n\r\u2028\u2028]/g; // differs from r1
+    var r4 = /[\n\r\u2028\u2029]/;  // differs from r1
+
+    equals(QUnit.equiv(r1, r2), true, "Regex pattern");
+    equals(QUnit.equiv(r1, r3), false, "Regex pattern");
+    equals(QUnit.equiv(r1, r4), false, "Regex pattern");
+
+    // More complex regex
+    var regex1 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+    var regex2 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+    // regex 3 is different: '.' not escaped
+    var regex3 = "^[-_.a-z0-9]+@([-_a-z0-9]+.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+
+    var r21 = new RegExp(regex1);
+    var r22 = new RegExp(regex2);
+    var r23 = new RegExp(regex3); // diff from r21, not same pattern
+    var r23a = new RegExp(regex3, "gi"); // diff from r23, not same modifier
+    var r24a = new RegExp(regex3, "ig"); // same as r23a
+
+    equals(QUnit.equiv(r21, r22), true, "Complex Regex");
+    equals(QUnit.equiv(r21, r23), false, "Complex Regex");
+    equals(QUnit.equiv(r23, r23a), false, "Complex Regex");
+    equals(QUnit.equiv(r23a, r24a), true, "Complex Regex");
+
+    // typeof r1 is "function" in some browsers and "object" in others so we must cover this test
+    var re = / /;
+    equals(QUnit.equiv(re, function () {}), false, "Regex internal");
+    equals(QUnit.equiv(re, {}), false, "Regex internal");
+});
+
+
+test("Complex Objects.", function() {
+
+    function fn1() {
+        return "fn1";
+    }
+    function fn2() {
+        return "fn2";
+    }
+    
+    // Try to invert the order of some properties to make sure it is covered.
+    // It can failed when properties are compared between unsorted arrays.
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                q: [],
+                                p: 1/0,
+                                o: 99
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    d: 0,
+                    i: true,
+                    h: "false"
+                }
+            },
+            e: undefined,
+            g: "",
+            h: "h",
+            f: {},
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                b: false,
+                a: 3.14159,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    t: undefined,
+                                    u: 0,
+                                    s: [1,2,3],
+                                    v: {
+                                        w: {
+                                            x: {
+                                                z: null,
+                                                y: "Yahoo!"
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    i: true,
+                    h: "false"
+                }
+            },
+            e: undefined,
+            g: "",
+            f: {},
+            h: "h",
+            i: []
+        }
+    ), true);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    //r: "r",   // different: missing a property
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    //t: undefined,                 // different: missing a property with an undefined value
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: {}           // different was []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    var same1 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var same2 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff1 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3,4]], // different: 4 was add to the array
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff2 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                newprop: undefined, // different: newprop was added
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff3 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ α" // different: missing last char
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff4 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,undefined,{}, [], [1,2,3]], // different: undefined instead of null
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff5 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bat: undefined // different: property name not "bar"
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    equals(QUnit.equiv(same1, same2), true);
+    equals(QUnit.equiv(same2, same1), true);
+    equals(QUnit.equiv(same2, diff1), false);
+    equals(QUnit.equiv(diff1, same2), false);
+
+    equals(QUnit.equiv(same1, diff1), false);
+    equals(QUnit.equiv(same1, diff2), false);
+    equals(QUnit.equiv(same1, diff3), false);
+    equals(QUnit.equiv(same1, diff3), false);
+    equals(QUnit.equiv(same1, diff4), false);
+    equals(QUnit.equiv(same1, diff5), false);
+    equals(QUnit.equiv(diff5, diff1), false);
+});
+
+
+test("Complex Arrays.", function() {
+
+    function fn() {
+    }
+
+    equals(QUnit.equiv(
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"],
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"]),
+            true);
+
+    equals(QUnit.equiv(
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"],
+                [1, 2, 3, true, {}, null, [
+                    {
+                        b: ["", '1', 0]         // not same property name
+                    },
+                    5, 6, 7
+                ], "foo"]),
+            false);
+
+    var a = [{
+        b: fn,
+        c: false,
+        "do": "reserved word",
+        "for": {
+            ar: [3,5,9,"hey!", [], {
+                ar: [1,[
+                    3,4,6,9, null, [], []
+                ]],
+                e: fn,
+                f: undefined
+            }]
+        },
+        e: 0.43445
+    }, 5, "string", 0, fn, false, null, undefined, 0, [
+        4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+    ], [], [[[], "foo", null, {
+        n: 1/0,
+        z: {
+            a: [3,4,5,6,"yep!", undefined, undefined],
+            b: {}
+        }
+    }, {}]]];
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), true);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[2]]]], "3"], {}, 1/0    // different: [[[[[2]]]]] instead of [[[[[3]]]]]
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: -1/0,                                                                // different, -Infinity instead of Infinity
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", {                                                       // different: null is missing
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn
+                                                                                // different: missing property f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+});
+
+
+test("Prototypal inheritance", function() {
+    function Gizmo(id) {
+        this.id = id;
+    }
+
+    function Hoozit(id) {
+        this.id = id;
+    }
+    Hoozit.prototype = new Gizmo();
+
+    var gizmo = new Gizmo("ok");
+    var hoozit = new Hoozit("ok");
+
+    // Try this test many times after test on instances that hold function
+    // to make sure that our code does not mess with last object constructor memoization.
+    equals(QUnit.equiv(function () {}, function () {}), false);
+
+    // Hoozit inherit from Gizmo
+    // hoozit instanceof Hoozit; // true
+    // hoozit instanceof Gizmo; // true
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    Gizmo.prototype.bar = true; // not a function just in case we skip them
+
+    // Hoozit inherit from Gizmo
+    // They are equivalent
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    // Make sure this is still true !important
+    // The reason for this is that I forgot to reset the last
+    // caller to where it were called from.
+    equals(QUnit.equiv(function () {}, function () {}), false);
+
+    // Make sure this is still true !important
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    Hoozit.prototype.foo = true; // not a function just in case we skip them
+
+    // Gizmo does not inherit from Hoozit
+    // gizmo instanceof Gizmo; // true
+    // gizmo instanceof Hoozit; // false
+    // They are not equivalent
+    equals(QUnit.equiv(hoozit, gizmo), false);
+
+    // Make sure this is still true !important
+    equals(QUnit.equiv(function () {}, function () {}), false);
+});
+
+
+test("Instances", function() {
+    function A() {} 
+    var a1 = new A(); 
+    var a2 = new A(); 
+
+    function B() {
+        this.fn = function () {};
+    } 
+    var b1 = new B(); 
+    var b2 = new B(); 
+
+    equals(QUnit.equiv(a1, a2), true, "Same property, same constructor");
+
+    // b1.fn and b2.fn are functions but they are different references
+    // But we decided to skip function for instances.
+    equals(QUnit.equiv(b1, b2), true, "Same property, same constructor");
+    equals(QUnit.equiv(a1, b1), false, "Same properties but different constructor"); // failed
+
+    function Car(year) {
+        var privateVar = 0;
+        this.year = year;
+        this.isOld = function() {
+            return year > 10;
+        };
+    }
+
+    function Human(year) {
+        var privateVar = 1;
+        this.year = year;
+        this.isOld = function() {
+            return year > 80;
+        };
+    }
+
+    var car = new Car(30);
+    var carSame = new Car(30);
+    var carDiff = new Car(10);
+    var human = new Human(30);
+
+    var diff = {
+        year: 30
+    };
+
+    var same = {
+        year: 30,
+        isOld: function () {}
+    };
+
+    equals(QUnit.equiv(car, car), true);
+    equals(QUnit.equiv(car, carDiff), false);
+    equals(QUnit.equiv(car, carSame), true);
+    equals(QUnit.equiv(car, human), false);
+});
+
+
+test("Complex Instances Nesting (with function value in literals and/or in nested instances)", function() {
+    function A(fn) {
+        this.a = {};
+        this.fn = fn;
+        this.b = {a: []};
+        this.o = {};
+        this.fn1 = fn;
+    }
+    function B(fn) {
+        this.fn = fn;
+        this.fn1 = function () {};
+        this.a = new A(function () {});
+    }
+
+    function fnOutside() {
+    }
+
+    function C(fn) {
+        function fnInside() {
+        }
+        this.x = 10;
+        this.fn = fn;
+        this.fn1 = function () {};
+        this.fn2 = fnInside;
+        this.fn3 = {
+            a: true,
+            b: fnOutside // ok make reference to a function in all instances scope
+        };
+        this.o1 = {};
+
+        // This function will be ignored.
+        // Even if it is not visible for all instances (e.g. locked in a closures),
+        // it is from a  property that makes part of an instance (e.g. from the C constructor)
+        this.b1 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b2: new B(function() {})
+            }
+        });
+    }
+
+    function D(fn) {
+        function fnInside() {
+        }
+        this.x = 10;
+        this.fn = fn;
+        this.fn1 = function () {};
+        this.fn2 = fnInside;
+        this.fn3 = {
+            a: true,
+            b: fnOutside, // ok make reference to a function in all instances scope
+
+            // This function won't be ingored.
+            // It isn't visible for all C insances
+            // and it is not in a property of an instance. (in an Object instances e.g. the object literal)
+            c: fnInside
+        };
+        this.o1 = {};
+
+        // This function will be ignored.
+        // Even if it is not visible for all instances (e.g. locked in a closures),
+        // it is from a  property that makes part of an instance (e.g. from the C constructor)
+        this.b1 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b2: new B(function() {})
+            }
+        });
+    }
+
+    function E(fn) {
+        function fnInside() {
+        }
+        this.x = 10;
+        this.fn = fn;
+        this.fn1 = function () {};
+        this.fn2 = fnInside;
+        this.fn3 = {
+            a: true,
+            b: fnOutside // ok make reference to a function in all instances scope
+        };
+        this.o1 = {};
+
+        // This function will be ignored.
+        // Even if it is not visible for all instances (e.g. locked in a closures),
+        // it is from a  property that makes part of an instance (e.g. from the C constructor)
+        this.b1 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b1: new B({a: function() {}}),
+                b2: new B(function() {})
+            }
+        });
+    }
+
+
+    var a1 = new A(function () {});
+    var a2 = new A(function () {});
+    equals(QUnit.equiv(a1, a2), true);
+
+    equals(QUnit.equiv(a1, a2), true); // different instances
+
+    var b1 = new B(function () {});
+    var b2 = new B(function () {});
+    equals(QUnit.equiv(a1, a2), true);
+
+    var c1 = new C(function () {});
+    var c2 = new C(function () {});
+    equals(QUnit.equiv(c1, c2), true);
+
+    var d1 = new D(function () {});
+    var d2 = new D(function () {});
+    equals(QUnit.equiv(d1, d2), false);
+
+    var e1 = new E(function () {});
+    var e2 = new E(function () {});
+    equals(QUnit.equiv(e1, e2), false);
+
+});
+
+
+test('object with references to self wont loop', function(){
+    var circularA = {
+        abc:null
+    }, circularB = {
+        abc:null
+    };
+    circularA.abc = circularA;
+    circularB.abc = circularB;
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
+    
+    circularA.def = 1;
+    circularB.def = 1;
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
+    
+    circularA.def = 1;
+    circularB.def = 0;
+    equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object (unambigous test)");
+});
+
+test('array with references to self wont loop', function(){
+    var circularA = [], 
+        circularB = [];
+    circularA.push(circularA);
+    circularB.push(circularB);
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
+    
+    circularA.push( 'abc' );
+    circularB.push( 'abc' );
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
+    
+    circularA.push( 'hello' );
+    circularB.push( 'goodbye' );
+    equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on array (unambigous test)");
+});
+
+test('mixed object/array with references to self wont loop', function(){
+    var circularA = [{abc:null}], 
+        circularB = [{abc:null}];
+    circularA[0].abc = circularA;
+    circularB[0].abc = circularB;
+    
+    circularA.push(circularA);
+    circularB.push(circularB);
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
+    
+    circularA[0].def = 1;
+    circularB[0].def = 1;
+    equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
+    
+    circularA[0].def = 1;
+    circularB[0].def = 0;
+    equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object/array (unambigous test)");
+});
+
+
+test("Test that must be done at the end because they extend some primitive's prototype", function() {
+    // Try that a function looks like our regular expression.
+    // This tests if we check that a and b are really both instance of RegExp
+    Function.prototype.global = true;
+    Function.prototype.multiline = true;
+    Function.prototype.ignoreCase = false;
+    Function.prototype.source = "my regex";
+    var re = /my regex/gm;
+    equals(QUnit.equiv(re, function () {}), false, "A function that looks that a regex isn't a regex");
+    // This test will ensures it works in both ways, and ALSO especially that we can make differences
+    // between RegExp and Function constructor because typeof on a RegExpt instance is "function"
+    equals(QUnit.equiv(function () {}, re), false, "Same conversely, but ensures that function and regexp are distinct because their constructor are different");
+});
+
diff --git a/addon/js_upload/file-uploader/tests/qunit/test/test.js b/addon/js_upload/file-uploader/tests/qunit/test/test.js
new file mode 100644 (file)
index 0000000..8eb5213
--- /dev/null
@@ -0,0 +1,171 @@
+test("module without setup/teardown (default)", function() {
+       expect(1);
+       ok(true);
+});
+
+test("expect in test", 3, function() {
+       ok(true);
+       ok(true);
+       ok(true);
+});
+
+test("expect in test", 1, function() {
+       ok(true);
+});
+
+module("setup test", {
+       setup: function() {
+               ok(true);
+       }
+});
+
+test("module with setup", function() {
+       expect(2);
+       ok(true);
+});
+
+var state;
+
+module("setup/teardown test", {
+       setup: function() {
+               state = true;
+               ok(true);
+       },
+       teardown: function() {
+               ok(true);
+       }
+});
+
+test("module with setup/teardown", function() {
+       expect(3);
+       ok(true);
+});
+
+module("setup/teardown test 2");
+
+test("module without setup/teardown", function() {
+       expect(1);
+       ok(true);
+});
+
+if (typeof setTimeout !== 'undefined') {
+state = 'fail';
+
+module("teardown and stop", {
+       teardown: function() {
+               equals(state, "done", "Test teardown.");
+       }
+});
+
+test("teardown must be called after test ended", function() {
+       expect(1);
+       stop();
+       setTimeout(function() {
+               state = "done";
+               start();
+       }, 13);
+});
+} // end setTimeout tests
+
+if (typeof asyncTest !== 'undefined') {
+module("asyncTest");
+
+asyncTest("asyncTest", function() {
+       expect(2);
+       ok(true);
+       setTimeout(function() {
+               state = "done";
+               ok(true);
+               start();
+       }, 13);
+});
+
+asyncTest("asyncTest", 2, function() {
+       ok(true);
+       setTimeout(function() {
+               state = "done";
+               ok(true);
+               start();
+       }, 13);
+});
+} // end asyncTest tests
+
+module("save scope", {
+       setup: function() {
+               this.foo = "bar";
+       },
+       teardown: function() {
+               same(this.foo, "bar");
+       }
+});
+test("scope check", function() {
+       expect(2);
+       same(this.foo, "bar");
+});
+
+module("simple testEnvironment setup", {
+       foo: "bar",
+       bugid: "#5311" // example of meta-data
+});
+test("scope check", function() {
+       same(this.foo, "bar");
+});
+test("modify testEnvironment",function() {
+       this.foo="hamster";
+});
+test("testEnvironment reset for next test",function() {
+       same(this.foo, "bar");
+});
+
+module("testEnvironment with object", {
+       options:{
+               recipe:"soup",
+               ingredients:["hamster","onions"]
+       }
+});
+test("scope check", function() {
+       same(this.options, {recipe:"soup",ingredients:["hamster","onions"]}) ;
+});
+test("modify testEnvironment",function() {
+       // since we do a shallow copy, the testEnvironment can be modified
+       this.options.ingredients.push("carrots");
+});
+test("testEnvironment reset for next test",function() {
+       same(this.options, {recipe:"soup",ingredients:["hamster","onions","carrots"]}, "Is this a bug or a feature? Could do a deep copy") ;
+});
+
+
+module("testEnvironment tests");
+
+function makeurl() {
+  var testEnv = QUnit.current_testEnvironment;
+  var url = testEnv.url || 'http://example.com/search';
+  var q   = testEnv.q   || 'a search test';
+  return url + '?q='+encodeURIComponent(q);
+}
+
+test("makeurl working",function() {
+       equals( QUnit.current_testEnvironment, this, 'The current testEnvironment is global');
+  equals( makeurl(), 'http://example.com/search?q=a%20search%20test', 'makeurl returns a default url if nothing specified in the testEnvironment');
+});
+
+module("testEnvironment with makeurl settings",{
+  url:'http://google.com/',
+  q:'another_search_test'
+});
+test("makeurl working with settings from testEnvironment",function() {
+  equals( makeurl(), 'http://google.com/?q=another_search_test', 'rather than passing arguments, we use test metadata to form the url');
+});
+test("each test can extend the module testEnvironment", {
+       q:'hamstersoup'
+}, function() {
+       equals( makeurl(), 'http://google.com/?q=hamstersoup', 'url from module, q from test'); 
+});
+
+module("jsDump");
+test("jsDump output", function() {
+       equals( QUnit.jsDump.parse([1, 2]), "[ 1, 2 ]" );
+       equals( QUnit.jsDump.parse({top: 5, left: 0}), "{ \"top\": 5, \"left\": 0 }" );
+       equals( QUnit.jsDump.parse(document.getElementById("qunit-header")), "<h1 id=\"qunit-header\"></h1>" );
+       equals( QUnit.jsDump.parse(document.getElementsByTagName("h1")), "[ <h1 id=\"qunit-header\"></h1> ]" );
+})
diff --git a/addon/js_upload/file-uploader/tests/sample-files/1imagelonglonglonglonglonglongname.gif b/addon/js_upload/file-uploader/tests/sample-files/1imagelonglonglonglonglonglongname.gif
new file mode 100644 (file)
index 0000000..6fba776
Binary files /dev/null and b/addon/js_upload/file-uploader/tests/sample-files/1imagelonglonglonglonglonglongname.gif differ
diff --git a/addon/js_upload/file-uploader/tests/sample-files/2larger.txt b/addon/js_upload/file-uploader/tests/sample-files/2larger.txt
new file mode 100644 (file)
index 0000000..bb54dd7
--- /dev/null
@@ -0,0 +1 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/sample-files/3empty.txt b/addon/js_upload/file-uploader/tests/sample-files/3empty.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/addon/js_upload/file-uploader/tests/sample-files/4text.txt b/addon/js_upload/file-uploader/tests/sample-files/4text.txt
new file mode 100644 (file)
index 0000000..ea7ada1
--- /dev/null
@@ -0,0 +1 @@
+satastastast
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/sample-files/5text.txt b/addon/js_upload/file-uploader/tests/sample-files/5text.txt
new file mode 100644 (file)
index 0000000..ea7ada1
--- /dev/null
@@ -0,0 +1 @@
+satastastast
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/sample-files/6text.txt b/addon/js_upload/file-uploader/tests/sample-files/6text.txt
new file mode 100644 (file)
index 0000000..ea7ada1
--- /dev/null
@@ -0,0 +1 @@
+satastastast
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/sample-files/7small.txt b/addon/js_upload/file-uploader/tests/sample-files/7small.txt
new file mode 100644 (file)
index 0000000..2f259b7
--- /dev/null
@@ -0,0 +1 @@
+s
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/sample-files/8text.txt b/addon/js_upload/file-uploader/tests/sample-files/8text.txt
new file mode 100644 (file)
index 0000000..ea7ada1
--- /dev/null
@@ -0,0 +1 @@
+satastastast
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/separate-file-list.htm b/addon/js_upload/file-uploader/tests/separate-file-list.htm
new file mode 100644 (file)
index 0000000..4241429
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+       <link href="../client/fileuploader.css" rel="stylesheet" type="text/css">       
+</head>
+<body>         
+       
+       <div id="demo"></div>
+       <ul id="separate-list"></ul>
+    
+    <script src="../client/fileuploader.js" type="text/javascript"></script>
+    <script>        
+        function createUploader(){            
+            var uploader = new qq.FileUploader({
+                element: document.getElementById('demo'),
+                listElement: document.getElementById('separate-list'),
+                action: '../client/do-nothing.htm'
+            });           
+        }        
+        window.onload = createUploader;     
+    </script>    
+</body>
+</html>
\ No newline at end of file
diff --git a/addon/js_upload/file-uploader/tests/test-acceptance.htm b/addon/js_upload/file-uploader/tests/test-acceptance.htm
new file mode 100644 (file)
index 0000000..985c20b
--- /dev/null
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML>
+<html>
+<head>  
+    <script src="jquery-1.4.2.min.js" type="text/javascript"></script>
+    
+    <!-- test iwth jquery ui dialog -->
+    <link href="jquery-ui/ui-lightness/jquery-ui-1.8.4.custom.css" rel="stylesheet" type="text/css" media="screen" />
+    <script src="jquery-ui/jquery-ui-1.8.4.custom.min.js" type="text/javascript"></script>
+
+    <link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
+    <script src="qunit/qunit/qunit.js" type="text/javascript"></script>
+    
+    <link href="../client/fileuploader.css" rel="stylesheet" type="text/css"> 
+    <script src="../client/fileuploader.js" type="text/javascript" ></script>
+    <script>
+
+jQuery(function(){    
+    $("#dialog").dialog();
+        
+    asyncTest("qq.FileUploader", function() {
+        expect(10);
+        
+        var submitFileName, submitId;
+               
+        var uploader = new qq.FileUploader({
+            element: document.getElementById('file-uploader'),
+            action: 'action-acceptance.php',
+            params: {
+                one: 'value1',
+                two: 'value2'
+            },
+            allowedExtensions: ['txt', 'val', 'webm'], 
+            sizeLimit: 9 * 1024, 
+            minSizeLimit: 10,
+            onSubmit: function(id, fileName){
+                if (fileName == '5text.txt'){
+                    submitId = id;
+                    submitFileName = fileName; 
+                } else if (fileName == '6text.txt'){
+                    uploader.setParams({'new':'newvalue'});  
+                    
+                    same(uploader.getInProgress(), 0, 'getFilesInProgress');                    
+                    
+                    setTimeout(function(){
+                        same(uploader.getInProgress(), 1, 'getFilesInProgress');
+                    }, 1);                                                                                                                   
+                } else if (fileName == '8text.txt'){
+                    
+                    setTimeout(function(){
+                        same(uploader.getInProgress(), 0, 'all uploads should have finished');
+                        start(); // check test results    
+                    }, 1000);
+                    
+                    return false;
+                }
+            },
+            onComplete: function(id, fileName, responseJSON){
+
+                if (fileName == '4text.txt'){
+                    same(responseJSON, {}, 'should be empty if server returned malformed json');
+                } else if (fileName == '5text.txt'){
+                    same(submitId, id, "id in both callbacks match");
+                    same(submitFileName, fileName, "filename in both callbacks match");    
+                    ok(responseJSON.one === 'value1' && responseJSON.two === 'value2', "server received default params");
+                    same(responseJSON.fileName, fileName, "filename in onComplete correct");
+                } else if (fileName == '6text.txt'){                    
+                    ok(responseJSON['new'] === 'newvalue' && responseJSON.one == null, "server received new params");                    
+                    same(uploader.getInProgress(), 0, 'upload should have finished');                                                            
+                } else if (fileName == '8text.txt'){
+                    ok(false, "upload should be cancelled by returning false in onSubmit");                    
+                }                                                                                
+            }
+        });           
+    });
+});
+    </script>  
+</head>
+<body> 
+    <h1 id="qunit-header">File uploader tests</h1> 
+    <h2 id="qunit-banner"></h2> 
+    <h2 id="qunit-userAgent"></h2> 
+    <ol id="qunit-tests"></ol>
+
+    <p>select files in sample-files dir, following order</p>
+    <ol>
+        <li>select 1imagelong...long.gif, invalid ext error should appear</li>        
+        <li>select 2larger.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
+        <li>select 3empty.txt, invalid size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
+        <li>select 4text.txt, uploaded file should be marked as failed (server returns jsgkdfgu4eyij)</li>             
+        <li>select 5text.txt, callback argument tests</li>        
+        <li>select 6text.txt, setParams, isUploading</li>
+        <li>select 7small.txt, too small size message should appear (in FF3.6+,Safari4+,Chrome without doing request)</li>
+        <li>select 8text.txt, returning false in onSubmit cancells upload, file should not be added to list</li>        
+        <li>
+            In FF,Chrome, select all files using drag-and-drop, only 1 error should appear.            
+        </li>
+    </ol>
+    
+    <div id="dialog" title="Basic dialog">
+        File uploader inside a dialog
+        <div id="file-uploader"></div>        
+    </div>               
+</body> 
+</html>
+
+
diff --git a/addon/js_upload/file-uploader/tests/test-drop-zone.htm b/addon/js_upload/file-uploader/tests/test-drop-zone.htm
new file mode 100644 (file)
index 0000000..d7f0acc
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+    <style>
+        .drop-zone {height:100px; width:256px; background:gray; margin:20px;}
+    </style>  
+    <script src="jquery-1.4.2.min.js" type="text/javascript"></script>
+    <script src="../client/fileuploader.js" type="text/javascript" ></script>    
+    <script>
+    
+function createDropZone(selector){
+    var element = $(selector)[0];  
+          
+    new qq.UploadDropZone({
+        element: element,
+        onEnter: function(){
+            console.log('enter')
+            $(element).css('background', 'green');
+        },
+        onLeave: function(){
+            console.log('leave')
+        },
+        onLeaveNotDescendants: function(){
+            console.log('onLeaveNotDescendants')
+            $(element).css('background', 'gray');
+        },
+        onDrop: function(e){
+            $(element).css('background', 'gray');
+            console.log('drop');
+            console.log(e.dataTransfer.files);
+        } 
+    });    
+}    
+
+jQuery(function(){
+    createDropZone('#drop-zone1');
+    createDropZone('#drop-zone2');                
+});
+
+    </script>      
+</head>
+<body> 
+    <div id="drop-zone1" class="drop-zone"><p>drop-zone1</p></div>
+    <div id="drop-zone2" class="drop-zone"><p>drop-zone2</p></div>          
+</body> 
+</html>
+
+
diff --git a/addon/js_upload/file-uploader/tests/test-handler-queue.htm b/addon/js_upload/file-uploader/tests/test-handler-queue.htm
new file mode 100644 (file)
index 0000000..52e3b3a
--- /dev/null
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<head>  
+    <script src="jquery-1.4.2.min.js" type="text/javascript"></script>
+    
+    <link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
+    <script src="qunit/qunit/qunit.js" type="text/javascript"></script>
+    
+    <script src="../client/fileuploader.js" type="text/javascript" ></script>
+    <script>
+jQuery(function(){
+
+    function getHandler(){
+        if(qq.UploadHandlerXhr.isSupported()){           
+            return qq.UploadHandlerXhr;                        
+        } else {
+            return qq.UploadHandlerForm;
+        }
+    }    
+
+    asyncTest("upload", function() {                                      
+            expect(2);
+                            
+            var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
+            var savedId;
+                                                    
+            var uploadHandler = new (getHandler())({
+                action: 'action-handler-queue-test.php',
+                maxConnections: 1,
+                onComplete: function(id, fileName, response){
+                    if (!response.success){
+                        ok(false, 'server did not receive file')
+                        return;    
+                    }
+                    
+                    delete response.success;
+                    delete response.qqfile;
+                    
+                    same(response, data, 'server received file and data');                                                              
+                }
+            });
+                
+                
+            $('#testinput1, #testinput2').change(upload);    
+            
+            function upload(){
+                setTimeout(start, 9000);
+                
+                var file = this;
+                if (uploadHandler instanceof qq.UploadHandlerXhr){
+                    file = this.files[0];
+                }
+                var id = uploadHandler.add(file);        
+                uploadHandler.upload(id, data);                
+            }
+            
+            
+    });
+});
+    </script>  
+</head>
+<body> 
+    <h1 id="qunit-header">File uploader tests</h1> 
+    <h2 id="qunit-banner"></h2> 
+    <h2 id="qunit-userAgent"></h2> 
+    <ol id="qunit-tests"></ol>
+
+        
+    <p>
+        Please select a file for each input below,
+        should be less than 4 sec, between selection.
+    </p>
+
+    
+    <input id="testinput1" type="file">
+    <input id="testinput2" type="file">
+        
+</body> 
+</html>
+
+
diff --git a/addon/js_upload/file-uploader/tests/test-upload-handlers.htm b/addon/js_upload/file-uploader/tests/test-upload-handlers.htm
new file mode 100644 (file)
index 0000000..9cf74fe
--- /dev/null
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML>
+<html>
+<head> 
+       <script src="jquery-1.4.2.min.js" type="text/javascript"></script>
+       
+       <link href="qunit/qunit/qunit.css" rel="stylesheet" type="text/css" media="screen" />
+       <script src="qunit/qunit/qunit.js" type="text/javascript"></script>
+       
+       <script src="../client/fileuploader.js" type="text/javascript" ></script>
+       <script>
+
+jQuery(function(){
+
+    module('qq');
+
+    test("contains", function(){
+        var el1 = document.createElement('div');
+        var el2 = document.createElement('div');
+        var el3 = document.createElement('div');
+        el1.appendChild(el2);
+        el2.appendChild(el3);
+        
+        var el4 = document.createElement('div');
+        
+        ok(qq.contains(el1,el1));
+        ok(qq.contains(el1,el2));
+        ok(qq.contains(el1,el3));
+        ok(!qq.contains(el1,el4));
+        ok(!qq.contains(el3,el2));
+    }); 
+        
+    test("hasClass, addClass, removeClass", function(){
+        var element = document.createElement('div');
+        qq.addClass(element, 'some-class');
+        ok(!qq.hasClass(element, 'some'), 'dash in class name');
+    });
+
+    test("children", function(){
+        same(qq.children(document.createElement('div')), [], 'empty');
+        var element = document.createElement('div');
+        element.innerHTML = 'asdasd<div>text</div><span>asdas</span>asdasd';
+        same(qq.children(element).length, 2);
+    });
+        
+    test("getByClass", function(){
+        var element = document.createElement('div');
+        element.style.display = 'none';
+        element.innerHTML = '<div class="class"><div class="someclass class"></div></div><span></span><div class="test"></div><div class="class"></div>';
+        document.body.appendChild(element);
+        
+        var outside = document.createElement('div');
+        outside.className = 'outside class';
+        document.body.appendChild(outside);
+        
+        same(qq.getByClass(document, 'class').length, 4, 'in document');
+        same(qq.getByClass(element, 'class').length, 3, 'in test div');
+        
+        qq.remove(element);
+        qq.remove(outside);     
+    }); 
+
+    test("obj2url", function(){
+        var tests = [
+          {title:'empty',                   obj:{}, expect:''},
+          {title:'general json',            obj:{a:'b',c:'d',e:'f'}, expect:'a=b&c=d&e=f'},
+          {title:'general json',            obj:{a:1,b:2,c:3,d:4}, expect:'a=1&b=2&c=3&d=4'},
+          {title:'general json array',      obj:{a:[1,2,3,4]}, expect:'a[0]=1&a[1]=2&a[2]=3&a[3]=4'},
+          {title:'complex json',            obj:{a:'b',c:'d',e:['f',{g:'h',i:['j',{k:'l',m:'n'}],
+                                                 o:undefined,p:true,q:false}]}, 
+                                            expect:'a=b&c=d&'
+                                                  +'e[0]=f&'
+                                                  +'e[1][g]=h&'
+                                                  +'e[1][i][0]=j&'
+                                                  +'e[1][i][1][k]=l&'
+                                                  +'e[1][i][1][m]=n&'
+                                                  +'e[1][o]=undefined&'
+                                                  +'e[1][p]=true&'
+                                                  +'e[1][q]=false'},
+          {title:'function',                obj:{a:function(){return 'b';}}, expect:'a=b'},
+          {title:'function no return',      obj:{a:function(){},undefined:'b'}, expect:'a=undefined'},
+          {title:'null',                    obj:{a:null}, expect:'a=null'},
+          {title:'prevent double encoding', obj:{a:[1,2,3],'b[]':[4,5,6],'c[d]':[7,8,9]}, 
+                                            expect:'a[0]=1&a[1]=2&a[2]=3&'
+                                                  +'b[]=4&b[]=5&b[]=6&'
+                                                  +'c[d][0]=7&c[d][1]=8&c[d][2]=9'},
+          {title:'spaces',                  obj:{a:'All your base are belong to us'}, 
+                                            expect:'a=All+your+base+are+belong+to+us'},
+          {title:'undefined simple',        obj:{undefined:undefined}, expect:''},
+          {title:'undefined complex',       obj:{undefined:undefined,
+                                                 a:{undefined:undefined},
+                                                 b:[{undefined:'c'},undefined,{d:'e'}]}, 
+                                            expect:'b[1]=undefined&b[2][d]=e'},
+          {title:'prefix url no params',    obj:{a:'b'}, 
+                                            prefix:'http://any.url', 
+                                            expect:'http://any.url?a=b'},
+          {title:'prefix url trailing ?',   obj:{a:'b'}, 
+                                            prefix:'http://any.url?', 
+                                            expect:'http://any.url?a=b'},
+          {title:'prefix url param',        obj:{a:'b'}, prefix:'http://any.url?foo', 
+                                            expect:'http://any.url?foo&a=b'},
+          {title:'prefix url param=value',  obj:{a:'b'}, 
+                                            prefix:'http://any.url?foo=bar', 
+                                            expect:'http://any.url?foo=bar&a=b'},
+          {title:'prefix url multi param',  obj:{a:'b'}, 
+                                            prefix:'http://any.url?foo=bar&bla=blub', 
+                                            expect:'http://any.url?foo=bar&bla=blub&a=b'},
+          {title:'prefix url array param',  obj:{a:'b',c:'d'}, 
+                                            prefix:'http://any.url?foo[0]=bla&foo[1]=blub', 
+                                            expect:'http://any.url?foo[0]=bla&foo[1]=blub&a=b&c=d'} 
+        ];
+        
+        for (var i = 0, l = tests.length; i<l; i++) {
+          //console.log('------------------ obj2url-test'+(i+1)+': '+tests[i].title);
+          //console.log('object: '+tests[i].obj);
+          //console.log('prefix: '+tests[i].prefix); 
+          var result = '';
+          if (tests[i].prefix) {
+            result = qq.obj2url(tests[i].obj, tests[i].prefix);
+          } else {
+            result = qq.obj2url(tests[i].obj);
+          }
+          //console.log('result: '+result);
+          same(decodeURIComponent(result), tests[i].expect, tests[i].title);
+        }
+    }); 
+    
+       
+       var uploadTimeout = 700,
+               loadTimeout = 300;
+       
+    if (qq.UploadHandlerXhr.isSupported()){
+        $('.handlerform').remove();    
+    } else {                   
+       //
+       module('qq.UploadHandlerForm');
+       //
+       
+       asyncTest("_getIframeContentJSON", function() {                                         
+               expect(3);
+               setTimeout(start, loadTimeout);         
+               
+               var exampleObject = {
+                 "example" : "&amp;a&lt;computer networks&gt;, to download means to receive data to a local system from a remote system, or to initiate such a data transfer. Examples of a remote system from which a download might be performed include a webserver, FTP server, email server, or other similar systems. A download can mean either any file that is offered for downloading or that has been downloaded, or the process of receiving such a file.The inverse operation, uploading, can refer to the sending of data from a local system to a remote system such as a server or another client with the intent that the remote system should store a copy of the data being transferred, or the initiation of such a process. The words first came into popular usage among computer users with the increased popularity of Bulletin Board Systems (BBSs), facilitated by the widespread distribution and implementation of dial-up access the in the 1970s",
+                 "sub" : {
+                   "arr": [10,20,30],
+                   "boo": false    
+                 }
+               };
+       
+               var testedFn = qq.UploadHandlerForm.prototype._getIframeContentJSON;            
+               
+               // IE 7,8 doesn't support application-javascript, application-json, text-javascript, text-plain
+               // as a response type, it also doesn't file load event when iframe loads page with 404 header           
+               createIframe('iframe-content-tests/somepage.php', function(iframe){
+                       same(testedFn(iframe), {}, "Server didn't return valid JSON object");
+               });             
+               createIframe('iframe-content-tests/text-html.php', function(iframe){
+                       same(testedFn(iframe), exampleObject, "text-html");
+               });                     
+               
+               // test larger response (>4k)
+               //http://www.coderholic.com/firefox-4k-xml-node-limit/
+            createIframe('iframe-content-tests/text-html-large.php', function(iframe){
+                same(testedFn(iframe).length, 5000, ">4k");
+            });         
+                               
+               
+               function createIframe(src, onLoad){
+                       var iframe = document.createElement('iframe');                  
+                       qq.attach(iframe, 'load', function(){
+                               onLoad(iframe);
+                               
+                               setTimeout(function(){
+                                       qq.remove(iframe);      
+                               }, 1);                                          
+                       });
+                       iframe.src = src;
+                       document.body.appendChild(iframe);                              
+               }               
+       });
+    
+        test("upload, cancel with empty input", function(){
+            expect(1);
+    
+            var uploadHandlerForm = new qq.UploadHandlerForm({
+                action: 'action-slow-response.php',
+                onComplete: function(id, fileName, response){
+                    ok(false, 'onComplete should not run, the request should be cancelled');
+                }
+            });
+                
+            var input = document.createElement('input');
+            var id = uploadHandlerForm.add(input);        
+            uploadHandlerForm.cancel(id);
+            
+            try {
+                // should fail
+                uploadHandlerForm.upload(id);
+            } catch (err){
+                ok(true, "wasn't uploaded after cancelling")            
+            };        
+            
+        });
+        
+       asyncTest("upload", function() {                                
+               expect(4);              
+                               
+               var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
+               var savedId;
+                                                                                               
+               var uploadHandler = new qq.UploadHandlerForm({
+                       action: 'action-handler-test.php',
+                       onComplete: function(id, fileName, response){                                                                                       
+                           ok(savedId == id, 'proper id in callback');                     
+                           same(fileName, uploadHandler.getName(id), 'getName method');
+                           
+                           data.fileName = fileName;                                           
+                               same(response, data, 'server received file and correct params, filenames match');
+                       }
+               });
+                       
+               var input = document.getElementById('testinput1');
+               qq.attach(input, 'change', function(){
+                       setTimeout(start, uploadTimeout);
+                                                                               
+                       savedId = uploadHandler.add(input);                     
+                       ok(savedId != null, 'id returned by add');
+                       
+                       uploadHandler.upload(savedId, data);
+               });
+       });
+       
+       asyncTest("cancel", function() {                                
+               var uploadHandlerForm = new qq.UploadHandlerForm({
+                       action: 'action-slow-response.php',
+                       onComplete: function(id, fileName, response){
+                               ok(false, 'onComplete should not run, the request should be cancelled');
+                       }
+               });
+                       
+               var input = document.getElementById('testinput2');
+               qq.attach(input, 'change', function(){
+                       var id = uploadHandlerForm.add(input);
+                       uploadHandlerForm.upload(id);
+                       uploadHandlerForm.cancel(id);
+                       start();
+               });
+       });     
+                       
+       test("check that forms and iframes were removed after use", function(){
+               same($('form,iframe').length, 0, 'check that forms and iframes were removed after use');
+       });
+       
+        asyncTest('going back', function(){
+            setTimeout(function(){
+                var goBack = confirm("checking that the history wasn't changed, the page will go back to previous now");
+                if (goBack){
+                   window.history.back();
+                   
+                   start();
+                   ok(false, "the page didn't change (fails in Opera)");
+                }              
+            }, 1000);               
+        });            
+       
+       }
+       
+    if (!qq.UploadHandlerXhr.isSupported()){
+        $('.handlerxhr').remove();    
+    } else {
+        //      
+        module('qq.UploadHandlerXhr');
+        //
+       
+       asyncTest("upload", function() {                
+           expect(9);
+               
+               var data = {stringOne: 'rtdfghdfhfh',stringTwo: 'dfsgsdfgsdg',stringThree: 'dfsgfhdfhdg'};
+               var onProgressCalled = false;
+               var expectedId, expectedName;
+                                                                                                               
+               var uploadHandler = new qq.UploadHandlerXhr({
+                       action: 'action-handler-test.php',
+                       onProgress: function(id, fileName, loaded, total){
+                               if (!onProgressCalled) {
+                                       onProgressCalled = true;
+                                       
+                                       same(id, expectedId, 'progress event fired with correct id param');
+                                       same(fileName, expectedName, 'progress event fired with correct fileName param')                                        
+                                       ok(loaded <= total && total > 0, 'progress event fired with possible loaded and total');
+                                       
+                                       same(total, uploadHandler.getSize(id), 'getSize method');                                       
+                               }
+                       },
+                       onComplete: function(id, fileName, response){                               
+                    same(id, expectedId, 'progress event fired with correct id param');
+                    same(fileName, expectedName, 'progress event fired with correct fileName param')
+                                                               
+                               data.fileName = fileName;
+                    data.qqfile = fileName;
+
+                               same(response, data, 'server received passed params, filenames match');
+                               
+                               same(fileName, uploadHandler.getName(id), 'getName method');                                     
+                       }
+               });
+                       
+               var input = document.getElementById('handlerxhr1');
+               
+               qq.attach(input, 'change', function(){
+                       setTimeout(start, uploadTimeout);
+                                                                               
+                       var id = uploadHandler.add(input.files[0]);
+                       ok(id != null, 'id returned by add');
+                       
+                       expectedId = id;
+                       expectedName = input.files[0].name || input.files[0].fileName;                          
+                       if (!expectedName){
+                           ok(false, 'false value as a file name used');
+                       }
+                       
+                       uploadHandler.upload(id, data);
+                       
+                       qq.remove(input);                       
+               });
+       });         
+               
+       asyncTest("cancel", function() {                                                
+               var uploadHandler = new qq.UploadHandlerXhr({
+                       action: 'action-slow-response.php',
+                       onComplete: function(id, fileName, response){
+                               ok(false, 'onComplete should not run, the request should be cancelled');
+                       }
+               });
+                       
+               var input = document.getElementById('handlerxhr2');
+               if (!input){
+                       // input removed because uploading via XHR is not supported
+                       return;
+               }
+               
+               qq.attach(input, 'change', function(){                                          
+                       var id = uploadHandler.add(input.files[0]);
+                       uploadHandler.upload(id);
+                       uploadHandler.cancel(id);
+                       
+                       start();                        
+                       qq.remove(input);                                                               
+               });
+       });             
+       }       
+});
+       </script>  
+</head>
+<body> 
+       <h1 id="qunit-header">File uploader tests</h1> 
+       <h2 id="qunit-banner"></h2> 
+       <h2 id="qunit-userAgent"></h2> 
+       <ol id="qunit-tests"></ol>
+       
+       <p>
+           Open this page via https connection, and make sure that loading bar is not acting strange after all tests are run.
+           Back button test fails in Opera. 
+       </p>
+       
+       <p>Please select a file for each input below (in order)</p>
+
+    <p>qq.FileUploader</p>
+    <div id="fileuploader1"></div>
+       
+       <p>qq.UploadHandlerForm</p>
+       <input class="handlerform" id="testinput1" type="file">
+       <input class="handlerform" id="testinput2" type="file">
+
+       <p>qq.UploadHandlerXhr</p>      
+       <input class="handlerxhr" id="handlerxhr1" type="file">
+       <input class="handlerxhr" id="handlerxhr2" type="file">  
+               
+</body> 
+</html>
+
+
diff --git a/addon/js_upload/js_upload.php b/addon/js_upload/js_upload.php
new file mode 100644 (file)
index 0000000..9f3fa96
--- /dev/null
@@ -0,0 +1,335 @@
+<?php
+
+/**
+ *
+ * JavaScript Photo/Image Uploader
+ *
+ * Uses Valum 'qq' Uploader. 
+ * Module Author: Chris Case
+ *
+ * Prior to enabling, ensure that you have a directory 'uploads'
+ * which is writable by the web server.
+ *
+ */
+
+
+function js_upload_install() {
+       register_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
+       register_hook('photo_post_init',   'addon/js_upload/js_upload.php', 'js_upload_post_init');
+       register_hook('photo_post_file',   'addon/js_upload/js_upload.php', 'js_upload_post_file');
+       register_hook('photo_post_end',    'addon/js_upload/js_upload.php', 'js_upload_post_end');
+}
+
+
+function js_upload_uninstall() {
+       unregister_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
+       unregister_hook('photo_post_init',   'addon/js_upload/js_upload.php', 'js_upload_post_init');
+       unregister_hook('photo_post_file',   'addon/js_upload/js_upload.php', 'js_upload_post_file');
+       unregister_hook('photo_post_end',    'addon/js_upload/js_upload.php', 'js_upload_post_end');
+}
+
+
+function js_upload_form(&$a,&$b) {
+
+       $b['default_upload'] = false;
+
+       $b['addon_text'] .= '<link href="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.css" rel="stylesheet" type="text/css">';
+       $b['addon_text'] .= '<script src="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.js" type="text/javascript"></script>';
+   
+       $upload_msg = t('Upload a file');
+       $drop_msg = t('Drop files here to upload');
+       $cancel = t('Cancel');
+       $failed = t('Failed');
+
+       $b['addon_text'] .= <<< EOT
+       
+ <div id="file-uploader-demo1">                
+  <noscript>                   
+   <p>Please enable JavaScript to use file uploader.</p>
+   <!-- or put a simple form for upload here -->
+  </noscript> 
+ </div>
+
+<script type="text/javascript">
+var uploader = null;       
+function getSelected(opt) {
+            var selected = new Array();
+            var index = 0;
+            for (var intLoop = 0; intLoop < opt.length; intLoop++) {
+               if ((opt[intLoop].selected) ||
+                   (opt[intLoop].checked)) {
+                  index = selected.length;
+                  //selected[index] = new Object;
+                  selected[index] = opt[intLoop].value;
+                  //selected[index] = intLoop;
+               }
+            }
+            return selected;
+         } 
+function createUploader() {
+       uploader = new qq.FileUploader({
+               element: document.getElementById('file-uploader-demo1'),
+               action: '{$b['post_url']}',
+
+        template: '<div class="qq-uploader">' + 
+                '<div class="qq-upload-drop-area"><span>$drop_msg</span></div>' +
+                '<div class="qq-upload-button">$upload_msg</div>' +
+                '<ul class="qq-upload-list"></ul>' + 
+             '</div>',
+
+        // template for one item in file list
+        fileTemplate: '<li>' +
+                '<span class="qq-upload-file"></span>' +
+                '<span class="qq-upload-spinner"></span>' +
+                '<span class="qq-upload-size"></span>' +
+                '<a class="qq-upload-cancel" href="#">$cancel</a>' +
+                '<span class="qq-upload-failed-text">$failed</span>' +
+            '</li>',        
+
+               debug: true,
+               onSubmit: function(id,filename) {
+
+                       uploader.setParams( {
+                               newalbum                :       document.getElementById('photos-upload-newalbum').value,
+                               album                   :       document.getElementById('photos-upload-album-select').value,
+                               group_allow             :       getSelected(document.getElementById('group_allow')).join(','),
+                               contact_allow   :       getSelected(document.getElementById('contact_allow')).join(','),
+                               group_deny              :       getSelected(document.getElementById('group_deny')).join(','),
+                               contact_deny    :       getSelected(document.getElementById('contact_deny')).join(',')
+                       });
+               }
+       });           
+}
+
+
+// in your app create uploader as soon as the DOM is ready
+// don't wait for the window to load  
+window.onload = createUploader;     
+
+
+</script>
+EOT;
+
+
+}
+
+function js_upload_post_init(&$a,&$b) {
+
+       // list of valid extensions, ex. array("jpeg", "xml", "bmp")
+
+       $allowedExtensions = array("jpeg","gif","png","jpg");
+
+       // max file size in bytes
+
+       $sizeLimit = 6 * 1024 * 1024;
+
+       $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
+
+       $result = $uploader->handleUpload();
+
+
+       // to pass data through iframe you will need to encode all html tags
+       $a->data['upload_jsonresponse'] =  htmlspecialchars(json_encode($result), ENT_NOQUOTES);
+
+       if(isset($result['error'])) {
+               logger('mod/photos.php: photos_post(): error uploading photo: ' . $result['error'] , 'LOGGER_DEBUG');
+               killme();
+       }
+
+       $a->data['upload_result'] = $result;
+
+}
+
+function js_upload_post_file(&$a,&$b) {
+
+       $result = $a->data['upload_result'];
+
+       $b['src']               = $result['path'];
+       $b['filename']  = $result['filename'];
+       $b['filesize']  = filesize($b['src']);
+
+}
+
+
+function js_upload_post_end(&$a,&$b) {
+
+logger('upload_post_end');
+       if(x($a->data,'upload_jsonresponse')) {
+               echo $a->data['upload_jsonresponse'];
+               killme();
+       }
+
+}
+
+
+/**
+ * Handle file uploads via XMLHttpRequest
+ */
+class qqUploadedFileXhr {
+
+       private $pathnm = '';
+
+    /**
+     * Save the file in the temp dir.
+     * @return boolean TRUE on success
+     */
+    function save() {    
+        $input = fopen("php://input", "r");
+        $this->pathnm = tempnam(sys_get_temp_dir(),'frn');
+               $temp = fopen($this->pathnm,"w");
+        $realSize = stream_copy_to_stream($input, $temp);
+
+        fclose($input);
+               fclose($temp);
+        
+        if ($realSize != $this->getSize()){            
+            return false;
+        }
+        return true;
+    }
+
+       function getPath() {
+               return $this->pathnm;
+       }
+
+    function getName() {
+        return $_GET['qqfile'];
+    }
+
+    function getSize() {
+        if (isset($_SERVER["CONTENT_LENGTH"])){
+            return (int)$_SERVER["CONTENT_LENGTH"];            
+        } else {
+            throw new Exception('Getting content length is not supported.');
+        }      
+    }   
+}
+
+/**
+ * Handle file uploads via regular form post (uses the $_FILES array)
+ */
+
+class qqUploadedFileForm {  
+
+
+    /**
+     * Save the file to the specified path
+     * @return boolean TRUE on success
+     */
+
+
+    function save() {
+        return true;
+    }
+
+       function getPath() {
+               return $_FILES['qqfile']['tmp_name'];
+       }
+
+    function getName() {
+        return $_FILES['qqfile']['name'];
+    }
+    function getSize() {
+        return $_FILES['qqfile']['size'];
+    }
+}
+
+class qqFileUploader {
+    private $allowedExtensions = array();
+    private $sizeLimit = 10485760;
+    private $file;
+
+    function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){        
+        $allowedExtensions = array_map("strtolower", $allowedExtensions);
+            
+        $this->allowedExtensions = $allowedExtensions;        
+        $this->sizeLimit = $sizeLimit;
+        
+        $this->checkServerSettings();       
+
+        if (isset($_GET['qqfile'])) {
+            $this->file = new qqUploadedFileXhr();
+        } elseif (isset($_FILES['qqfile'])) {
+            $this->file = new qqUploadedFileForm();
+        } else {
+            $this->file = false; 
+        }
+
+    }
+    
+    private function checkServerSettings(){        
+        $postSize = $this->toBytes(ini_get('post_max_size'));
+        $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));        
+               logger('mod/photos.php: qqFileUploader(): upload_max_filesize=' . $uploadSize , 'LOGGER_DEBUG');
+        if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
+            $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';             
+            die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
+        }        
+    }
+    
+    private function toBytes($str){
+        $val = trim($str);
+        $last = strtolower($str[strlen($str)-1]);
+        switch($last) {
+            case 'g': $val *= 1024;
+            case 'm': $val *= 1024;
+            case 'k': $val *= 1024;        
+        }
+        return $val;
+    }
+    
+    /**
+     * Returns array('success'=>true) or array('error'=>'error message')
+     */
+    function handleUpload(){
+        
+        if (!$this->file){
+            return array('error' => t('No files were uploaded.'));
+        }
+        
+        $size = $this->file->getSize();
+        
+        if ($size == 0) {
+            return array('error' => t('Uploaded file is empty'));
+        }
+        
+        if ($size > $this->sizeLimit) {
+
+            return array('error' => t('Uploaded file is too large'));
+        }
+        
+
+               $maximagesize = get_config('system','maximagesize');
+
+               if(($maximagesize) && ($size > $maximagesize)) {
+                       return array('error' => t('Image exceeds size limit of ') . $maximagesize );
+
+               }
+
+        $pathinfo = pathinfo($this->file->getName());
+        $filename = $pathinfo['filename'];
+
+        $ext = $pathinfo['extension'];
+
+        if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
+            $these = implode(', ', $this->allowedExtensions);
+            return array('error' => t('File has an invalid extension, it should be one of ') . $these . '.');
+        }
+        
+        if ($this->file->save()){
+            return array(
+                               'success'=>true,
+                               'path' => $this->file->getPath(), 
+                               'filename' => $filename . '.' . $ext
+                       );
+        } else {
+            return array(
+                               'error'=> t('Upload was cancelled, or server error encountered'),
+                               'path' => $this->file->getPath(), 
+                               'filename' => $filename . '.' . $ext
+                       );
+        }
+        
+    }    
+}
diff --git a/addon/oembed/oembed.js b/addon/oembed/oembed.js
new file mode 100644 (file)
index 0000000..54547a8
--- /dev/null
@@ -0,0 +1,10 @@
+function oembed(){
+  $("#oembed").toggleClass('hide');
+}
+
+function oembed_do(){
+  embed = "[embed]"+$('#oembed_url').attr('value')+"[/embed]";
+  
+  tinyMCE.execCommand('mceInsertRawHTML',false,embed);
+  oembed();
+}
diff --git a/addon/oembed/oembed.php b/addon/oembed/oembed.php
new file mode 100644 (file)
index 0000000..4bbd753
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * oembed plugin
+ * 
+ * oEmbed is a format for allowing an embedded representation of a URL on third party sites
+ * http://www.oembed.com/
+ * 
+ */
+function oembed_install() {
+  register_hook('jot_tool', 'addon/oembed/oembed.php', 'oembed_hook_jot_tool');
+  register_hook('page_header', 'addon/oembed/oembed.php', 'oembed_hook_page_header');
+}
+
+function oembed_uninstall() {
+  unregister_hook('jot_tool', 'addon/oembed/oembed.php', 'oembed_hook_jot_tool');
+  unregister_hook('page_header', 'addon/oembed/oembed.php', 'oembed_hook_page_header');
+}
+
+function oembed_hook_page_header($a, &$b){
+  $b .= '<script src="addon/oembed/oembed.js"></script>
+  <style>#oembed.hide { display: none } 
+  #oembed {
+     display:block; position: absolute; width: 300px; height:200px;
+     background-color:#fff; color: #000;
+     border:2px solid #8888FF; padding: 1em;
+     top: 200px; left: 400px; z-index:2000;  
+   }
+  #oembed_url { width: 100%; margin-bottom:3px;}
+   </style>';
+  
+  $b .= '
+  <div id="oembed" class="hide"><input id="oembed_url">&nbsp;
+    <input type="button" value="Embed" onclick="oembed_do()" style="float:left;">
+    <a onclick="oembed(); return false;" style="float:right;"><img onmouseout="imgdull(this);" onmouseover="imgbright(this);" class="wall-item-delete-icon" src="images/b_drophide.gif" style="width: 16px; height: 16px;"></a>
+    <p style="clear:both">Paste a link from 5min.com, Amazon Product Image, blip.tv, Clikthrough, CollegeHumor Video, 
+      Daily Show with Jon Stewart, Dailymotion, dotSUB.com, Flickr Photos, Funny or Die Video, 
+      Google Video, Hulu, Kinomap, LiveJournal UserPic, Metacafe, National Film Board of Canada, 
+      Phodroid Photos, Photobucket, Qik Video, Revision3, Scribd, SlideShare, TwitPic, Twitter Status, 
+      Viddler Video, Vimeo, Wikipedia, Wordpress.com, XKCD Comic, YFrog, YouTube</p> 
+  </div>
+  ';
+}
+
+
+function oembed_hook_jot_tool($a, &$b) {
+  $b .= '
+    <div class="tool-wrapper" style="display: $visitor;" >
+      <img class="tool-link" src="addon/oembed/oembed.png" alt="Embed" title="Embed" onclick="oembed();" />
+    </div> 
+  ';
+}
+
+
+
+
+?>
\ No newline at end of file
diff --git a/addon/oembed/oembed.png b/addon/oembed/oembed.png
new file mode 100644 (file)
index 0000000..6fc3794
Binary files /dev/null and b/addon/oembed/oembed.png differ
diff --git a/addon/piwik/piwik.css b/addon/piwik/piwik.css
new file mode 100644 (file)
index 0000000..bb43b67
--- /dev/null
@@ -0,0 +1,8 @@
+#piwik-optout-link {
+       padding: 100px 50px;
+       text-align: justify;
+       font-size: 0.85em;
+}
+#piwik-code-block {
+       display: none;
+}
diff --git a/addon/piwik/piwik.php b/addon/piwik/piwik.php
new file mode 100644 (file)
index 0000000..aad2fd8
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/*   Piwik Analytics Plugin for Friendika
+ *
+ *   Author: Tobias Diekershoff
+ *           tobias.diekershoff@gmx.net
+ *
+ *   License: 3-clause BSD license (same as Friendika)
+ *
+ *   Configuration:
+ *     Add the following two lines to your .htconfig.php file:
+ *
+ *     $a->config['piwik']['baseurl'] = 'www.example.com/piwik/';
+ *     $a->config['piwik']['sideid'] = '1';
+ *     $a->config['piwik']['optout'] = true;  // set to false to disable
+ *
+ *     Change the sideid to the ID that the Piwik tracker for your Friendika
+ *     installation has. Alter the baseurl to fit your needs, don't care
+ *     about http/https but beware to put the trailing / at the end of your
+ *     setting.
+ */
+
+function piwik_install() {
+       register_hook('page_end', 'addon/piwik/piwik.php', 'piwik_analytics');
+
+        logger("installed piwik plugin");
+}
+
+function piwik_uninstall() {
+       unregister_hook('page_end', 'addon/piwik/piwik.php', 'piwik_analytics');
+
+        logger("uninstalled piwik plugin");
+}
+
+function piwik_analytics($a,&$b) {
+
+       /*
+        *   styling of every HTML block added by this plugin is done in the
+        *   associated CSS file. We just have to tell Friendika to get it
+        *   into the page header.
+        */
+       $a->page['htmlhead'] .= '<link rel="stylesheet"  type="text/css" href="' . $a->get_baseurl() . '/addon/piwik/piwik.css' . '" media="all" />' . "\r\n";
+
+       /*
+        *   Get the configuration variables from the .htconfig file.
+        */
+       $baseurl = get_config('piwik','baseurl');
+       $sideod  = get_config('piwik','sideid');
+       $optout  = get_config('piwik','optout');
+
+       /*
+        *   Add the Piwik code for the side.
+        */
+       $b .= "<div id='piwik-code-block'> <!-- Piwik -->\r\n <script type=\"text/javascript\">\r\n var pkBaseURL = ((\"https:\" == document.location.protocol) ? \"https://".$baseurl."\" : \"http://".$baseurl."\");\r\n document.write(unescape(\"%3Cscript src='\" + pkBaseURL + \"piwik.js' type='text/javascript'%3E%3C/script%3E\"));\r\n </script>\r\n<script type=\"text/javascript\">\r\n try {\r\n var piwikTracker = Piwik.getTracker(pkBaseURL + \"piwik.php\", 8);\r\n piwikTracker.trackPageView();\r\n piwikTracker.enableLinkTracking();\r\n }\r\n catch( err ) {}\r\n </script>\r\n<noscript><p><img src=\"http://".$baseurl."/piwik.php?idsite=8\" style=\"border:0\" alt=\"\" /></p></noscript>\r\n <!-- End Piwik Tracking Tag --> </div>";
+       /*
+        *   If the optout variable is set to true then display the notice
+        *   otherwise just include the above code into the page.
+        */
+       if ($optout) {
+               $b .= "<div id='piwik-optout-link'>This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> analytics tool. If you do not want that your visits are logged this way you <a href='http://". $baseurl ."index.php?module=CoreAdminHome&action=optOut'>can set a cookie to prevent Piwik from tracking further visits of the site</a> (opt-out).</div>";
+       }
+
+}
+
diff --git a/addon/poormancron/poormancron.php b/addon/poormancron/poormancron.php
new file mode 100644 (file)
index 0000000..c31d277
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Poor Man Cron. Execute updates on pageviews
+ *
+ * Addon Name: poormancron
+ *
+ */
+
+function poormancron_install() {
+       register_hook('page_end', 'addon/poormancron/poormancron.php', 'poormancron_hook');
+       register_hook('proc_run', 'addon/poormancron/poormancron.php','poormancron_procrun');
+       logger("installed poormancron");
+}
+
+function poormancron_uninstall() {
+       unregister_hook('page_end', 'addon/poormancron/poormancron.php', 'poormancron_hook');
+       unregister_hook('proc_run', 'addon/poormancron/poormancron.php','poormancron_procrun');
+       logger("removed poormancron");
+}
+
+
+
+function poormancron_hook($a,&$b) {
+    $now = time();
+    $lastupdate = get_config('poormancron', 'lastupdate');
+
+    // 300 secs, 5 mins
+    if (!$lastupdate || ($now-$lastupdate)>300) {
+        set_config('poormancron','lastupdate', $now);
+        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
+        proc_run($php_path,"include/poller.php");
+    }
+}
+
+function poormancron_procrun($a, $argv) {
+       logger("poormancron procrun ".implode(", ",$argv));
+       array_shift($argv);
+       $argc = count($argv);
+       logger("poormancron procrun require_once ".basename($argv[0]));
+       require_once(basename($argv[0]));
+       $funcname=str_replace(".php", "", basename($argv[0]))."_run";
+  
+       $funcname($argv, $argc);
+}
+
+
+
+?>
index 05b33abd6ef93d1d4d3f5cea4e5e0e5d8e806065..4fc05f81a39ff0ae32cbef58d8fe3adbff9bbd47 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -2,14 +2,24 @@
 
 set_time_limit(0);
 
-define ( 'BUILD_ID',               1033   );
-define ( 'FRIENDIKA_VERSION',      '2.01.1005' );
-define ( 'DFRN_PROTOCOL_VERSION',  '2.0'  );
+define ( 'BUILD_ID',               1034   );
+define ( 'FRIENDIKA_VERSION',      '2.10.0904' );
+define ( 'DFRN_PROTOCOL_VERSION',  '2.1'  );
 
 define ( 'EOL',                    "<br />\r\n"     );
 define ( 'ATOM_TIME',              'Y-m-d\TH:i:s\Z' );
 define ( 'DOWN_ARROW',             '&#x21e9;'       );
          
+
+/**
+ * SSL redirection policies
+ */
+
+define ( 'SSL_POLICY_NONE',         0 );
+define ( 'SSL_POLICY_FULL',         1 );
+define ( 'SSL_POLICY_SELFSIGN',     2 );
+
+
 /**
  * log levels
  */
@@ -270,10 +280,17 @@ class App {
        }
 
        function get_baseurl($ssl = false) {
-               if(strlen($this->baseurl))
-                       return $this->baseurl;
 
-               $this->baseurl = (($ssl) ? 'https' : $this->scheme) . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
+               $scheme = $this->scheme;
+
+               if(x($this->config,'ssl_policy')) {
+                       if(($ssl) || ($this->config['ssl_policy'] == SSL_POLICY_FULL)) 
+                               $scheme = 'https';
+                       if(($this->config['ssl_policy'] == SSL_POLICY_SELFSIGN) && (local_user() || x($_POST,'auth-params')))
+                               $scheme = 'https';
+               }
+
+               $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
                return $this->baseurl;
        }
 
@@ -1349,6 +1366,7 @@ function lrdd($uri) {
        else {
                $html = fetch_url($uri);
                $headers = $a->get_curl_headers();
+               logger('lrdd: headers=' . $headers, LOGGER_DEBUG);
                $lines = explode("\n",$headers);
                if(count($lines)) {
                        foreach($lines as $line) {                              
@@ -1357,6 +1375,11 @@ function lrdd($uri) {
                                        $link = $matches[1];
                                        break;
                                }
+                               // don't try and run feeds through the html5 parser
+                               if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
+                                       return array();
+                               if(stristr($html,'<rss') || stristr($html,'<feed'))
+                                       return array();
                        }
                }
                if(! isset($link)) {
@@ -1655,7 +1678,6 @@ function attribute_contains($attr,$s) {
 
 if(! function_exists('logger')) {
 function logger($msg,$level = 0) {
-
        $debugging = get_config('system','debugging');
        $loglevel  = intval(get_config('system','loglevel'));
        $logfile   = get_config('system','logfile');
@@ -1687,7 +1709,12 @@ function activity_match($haystack,$needle) {
 if(! function_exists('get_tags')) {
 function get_tags($s) {
        $ret = array();
-       if(preg_match_all('/([@#][^ \x0D\x0A,:?]*)([ \x0D\x0A,:?]|$)/',$s,$match)) {
+
+       // ignore anything in a code block
+
+       $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
+
+       if(preg_match_all('/([@#][^ \x0D\x0A,:?]+)([ \x0D\x0A,:?]|$)/',$s,$match)) {
                foreach($match[1] as $match) {
                        if(strstr($match,"]")) {
                                // we might be inside a bbcode color tag - leave it alone
@@ -1873,7 +1900,7 @@ function aes_encrypt($val,$ky)
 
 if(! function_exists('linkify')) {
 function linkify($s) {
-       $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'\%]*)/", ' <a href="$1" >$1</a>', $s);
+       $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'\%]*)/", ' <a href="$1" target="external-link">$1</a>', $s);
        return($s);
 }}
 
@@ -2210,3 +2237,41 @@ function link_compare($a,$b) {
                return true;
        return false;
 }}
+
+
+if(! function_exists('prepare_body')) {
+function prepare_body($item) {
+
+       require_once('include/bbcode.php');
+
+       $s = smilies(bbcode($item['body']));
+
+       return $s;
+}}
+
+/**
+ * 
+ * Wrap calls to proc_close(proc_open()) and call hook
+ * so plugins can take part in process :)
+ * 
+ * args:
+ * $cmd program to run
+ *  next args are passed as $cmd command line
+ * 
+ * e.g.: proc_run("ls","-la","/tmp");
+ * 
+ * $cmd and string args are surrounded with ""
+ */
+
+if(! function_exists('run_proc')) {
+function proc_run($cmd){
+       $args = func_get_args();
+       call_hooks("proc_run", $args);
+       
+       foreach ($args as &$arg){
+               if(is_string($arg)) $arg='"'.$arg.'"';
+       }
+       $cmdline = implode($args," ");
+       proc_close(proc_open($cmdline." &",array(),$foo));
+}}
+
index 54950f0fd1ad7ee49d4bfb816683311974f8f4a0..817fd09226f1c0d2676b244f843e8f2ea1db0e84 100644 (file)
@@ -471,4 +471,8 @@ CREATE TABLE IF NOT EXISTS `event` (
 `deny_gid` MEDIUMTEXT NOT NULL
 ) ENGINE = MYISAM DEFAULT CHARSET=utf8;
 
-
+CREATE TABLE IF NOT EXISTS 'cache' (
+ `k` CHAR( 255 ) NOT NULL PRIMARY KEY ,
+ `v` TEXT NOT NULL,
+ `updated` DATETIME NOT NULL
+) ENGINE = MYISAM DEFAULT CHARSET=utf8;
index 6f6e3faf96b5be465ec69f61a4eb713e1226843c..5f5c76cbd7863788de6a990d7c06f6630060ff29 100644 (file)
@@ -64,4 +64,15 @@ $a->config['system']['huburl'] = 'http://pubsubhubbub.appspot.com';
 
 $a->config['system']['rino_encrypt'] = true;
 
\ No newline at end of file
+
+// Addons or plugins are configured here.
+// This is a comma seperated list of addons to enable. Example:
+// $a->config['system']['addon'] = 'js_upload,randplace,oembed';
+
+$a->config['system']['addon'] = 'js_upload';
+
+
+// Disable oembed embedding
+// This disable the conversion of [embed]$url[/embed] tag in html
+// $a->config['system']['no_oembed'] = true;
+
diff --git a/images/document.gif b/images/document.gif
new file mode 100644 (file)
index 0000000..02d9409
Binary files /dev/null and b/images/document.gif differ
diff --git a/images/people.gif b/images/people.gif
new file mode 100644 (file)
index 0000000..cac31db
Binary files /dev/null and b/images/people.gif differ
index 98d3e7c0b1083a40b15ff6802f7724c5ce37d2cd..7cac3c0e0ca9a3b555b1569a1bb05d0461ddc418 100644 (file)
@@ -6,6 +6,10 @@
 // authorisation to do this.
 
 function user_remove($uid) {
+       if(! $uid)
+               return;
+       $a = get_app();
+       logger('Removing user: ' . $uid);
        q("DELETE FROM `contact` WHERE `uid` = %d", intval($uid));
        q("DELETE FROM `group` WHERE `uid` = %d", intval($uid));
        q("DELETE FROM `group_member` WHERE `uid` = %d", intval($uid));
@@ -19,7 +23,7 @@ function user_remove($uid) {
        if($uid == local_user()) {
                unset($_SESSION['authenticated']);
                unset($_SESSION['uid']);
-               killme();
+               goaway($a->get_baseurl());
        }
 }
 
index 10ec54d1347aa968ec35c3d9b1b9185ca61976dc..ff98992526314474b6dcc7aa20386a92f114c332 100644 (file)
@@ -5,12 +5,31 @@ require_once('library/HTML5/Parser.php');
 if(! function_exists('scrape_dfrn')) {
 function scrape_dfrn($url) {
 
+       $a = get_app();
+
        $ret = array();
+
+       logger('scrape_dfrn: url=' . $url);
+
        $s = fetch_url($url);
 
        if(! $s) 
                return $ret;
 
+       $headers = $a->get_curl_headers();
+       logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG);
+
+
+       $lines = explode("\n",$headers);
+       if(count($lines)) {
+               foreach($lines as $line) {                              
+                       // don't try and run feeds through the html5 parser
+                       if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
+                               return ret;
+               }
+       }
+
+
        $dom = HTML5_Parser::parse($s);
 
        if(! $dom)
@@ -22,6 +41,8 @@ function scrape_dfrn($url) {
 
        foreach($items as $item) {
                $x = $item->getAttribute('rel');
+               if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml'))
+                       $ret['feed_atom'] = $item->getAttribute('href');
                if(substr($x,0,5) == "dfrn-")
                        $ret[$x] = $item->getAttribute('href');
                if($x === 'lrdd') {
@@ -75,12 +96,31 @@ function validate_dfrn($a) {
 if(! function_exists('scrape_meta')) {
 function scrape_meta($url) {
 
+       $a = get_app();
+
        $ret = array();
+
+       logger('scrape_meta: url=' . $url);
+
        $s = fetch_url($url);
 
        if(! $s) 
                return $ret;
 
+       $headers = $a->get_curl_headers();
+       logger('scrape_meta: headers=' . $headers, LOGGER_DEBUG);
+
+       $lines = explode("\n",$headers);
+       if(count($lines)) {
+               foreach($lines as $line) {                              
+                       // don't try and run feeds through the html5 parser
+                       if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
+                               return ret;
+               }
+       }
+
+
+
        $dom = HTML5_Parser::parse($s);
 
        if(! $dom)
@@ -103,12 +143,27 @@ function scrape_meta($url) {
 if(! function_exists('scrape_vcard')) {
 function scrape_vcard($url) {
 
+       $a = get_app();
+
        $ret = array();
+
+       logger('scrape_vcard: url=' . $url);
+
        $s = fetch_url($url);
 
        if(! $s) 
                return $ret;
 
+       $headers = $a->get_curl_headers();
+       $lines = explode("\n",$headers);
+       if(count($lines)) {
+               foreach($lines as $line) {                              
+                       // don't try and run feeds through the html5 parser
+                       if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
+                               return ret;
+               }
+       }
+
        $dom = HTML5_Parser::parse($s);
 
        if(! $dom)
@@ -135,3 +190,54 @@ function scrape_vcard($url) {
 
        return $ret;
 }}
+
+
+if(! function_exists('scrape_feed')) {
+function scrape_feed($url) {
+
+       $a = get_app();
+
+       $ret = array();
+       $s = fetch_url($url);
+
+       if(! $s) 
+               return $ret;
+
+       $headers = $a->get_curl_headers();
+       logger('scrape_feed: headers=' . $headers, LOGGER_DEBUG);
+
+       $lines = explode("\n",$headers);
+       if(count($lines)) {
+               foreach($lines as $line) {                              
+                       if(stristr($line,'content-type:')) {
+                               if(stristr($line,'application/atom+xml') || stristr($s,'<feed')) {
+                                       $ret['feed_atom'] = $url;
+                                       return $ret;
+                               }
+                               if(stristr($line,'application/rss+xml') || stristr($s,'<rss')) {
+                                       $ret['feed_rss'] = $url;
+                                       return ret;
+                               }
+                       }
+               }
+       }
+
+       $dom = HTML5_Parser::parse($s);
+
+       if(! $dom)
+               return $ret;
+
+       $items = $dom->getElementsByTagName('link');
+
+       // get Atom link elements
+
+       foreach($items as $item) {
+               $x = $item->getAttribute('rel');
+               if(($x === 'alternate') && ($item->getAttribute('type') === 'application/atom+xml'))
+                       $ret['feed_atom'] = $item->getAttribute('href');
+               if(($x === 'alternate') && ($item->getAttribute('type') === 'application/rss+xml'))
+                       $ret['feed_rss'] = $item->getAttribute('href');
+       }
+
+       return $ret;
+}}
\ No newline at end of file
index d0952421ea3b92aa78d4a9b79f5a0d42f3481034..269dc3e349b66f20c5ca10ea992e5463cb37d744 100644 (file)
@@ -17,8 +17,9 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
                                $selected = " selected=\"selected\" ";
                        else
                                $selected = '';
+                       $trimmed = substr($rr['name'],0,12);
 
-                       $o .= "<option value=\"{$rr['id']}\" $selected >{$rr['name']}</option>\r\n";
+                       $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}\" >$trimmed</option>\r\n";
                }
        
        }
@@ -30,7 +31,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
 
 
 
-function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false) {
+function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false) {
 
        $o = '';
 
@@ -43,6 +44,10 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
                $sql_extra .= sprintf(" AND `rel` = %d ", intval(REL_BUD));
        }
 
+       if($privmail || $privatenet) {
+               $sql_extra .= " AND `network` IN ( 'dfrn' ) ";
+       }       
+
        if($privmail)
                $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" >\r\n";
        else 
@@ -61,11 +66,10 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
                                $selected = " selected=\"selected\" ";
                        else
                                $selected = '';
-                       if(($privmail) && ($rr['network'] === 'stat'))
-                               $disabled = ' disabled="true" ' ;
-                       else
-                               $disabled = '';
-                       $o .= "<option value=\"{$rr['id']}\" $selected  $disabled title=\"{$rr['url']}\" >{$rr['name']}</option>\r\n";
+
+                       $trimmed = substr($rr['name'],0,22);
+
+                       $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}|{$rr['url']}\" >$trimmed</option>\r\n";
                }
        
        }
@@ -110,7 +114,7 @@ function populate_acl($user = null,$celeb = false) {
        $o .= '</div>';
        $o .= '<div id="contact_allow_wrapper">';
        $o .= '<label id="acl-allow-contact-label" for="contact_allow" >' . t('Contacts') . '</label>';
-       $o .= contact_select('contact_allow','contact_allow',$allow_cid,4,false,$celeb);
+       $o .= contact_select('contact_allow','contact_allow',$allow_cid,4,false,$celeb,true);
        $o .= '</div>';
        $o .= '</div>' . "\r\n";
        $o .= '<div id="acl-allow-end"></div>' . "\r\n";
@@ -125,7 +129,7 @@ function populate_acl($user = null,$celeb = false) {
        $o .= '</div>';
        $o .= '<div id="contact_deny_wrapper" >';
        $o .= '<label id="acl-deny-contact-label" for="contact_deny" >' . t('Contacts') . '</label>';
-       $o .= contact_select('contact_deny','contact_deny', $deny_cid,4,false, $celeb);
+       $o .= contact_select('contact_deny','contact_deny', $deny_cid,4,false, $celeb,true);
        $o .= '</div>';
        $o .= '</div>' . "\r\n";
        $o .= '<div id="acl-deny-end"></div>' . "\r\n";
index 81b581cdbdde51672cf6277182afc1c1f2b1b196..eb0806dc527fee8b6b36a89d6d6239e807ca665e 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-
+require_once("include/oembed.php");
        // BBcode 2 HTML was written by WAY2WEB.net
        // extended to work with Mistpark/Friendika - Mike Macgirvin
 
@@ -22,10 +22,10 @@ function bbcode($Text) {
        // Perform URL Search
 
 
-       $Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'\%]*)/", ' <a href="$2" >$2</a>', $Text);
+       $Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\'\%]+)/", ' <a href="$2" target="external-link">$2</a>', $Text);
 
-       $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '<a href="$1" >$1</a>', $Text);
-       $Text = preg_replace("(\[url\=([$URLSearchString]*)\](.+?)\[/url\])", '<a href="$1" >$2</a>', $Text);
+       $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '<a href="$1" target="external-link">$1</a>', $Text);
+       $Text = preg_replace("(\[url\=([$URLSearchString]*)\](.+?)\[/url\])", '<a href="$1" target="external-link">$2</a>', $Text);
        //$Text = preg_replace("(\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[/url\])", '<a href="$1" target="_blank">$2</a>', $Text);
 
 
@@ -93,6 +93,9 @@ function bbcode($Text) {
         $Text = preg_replace("/\[youtube\]http:\/\/www.youtube.com\/watch\?v\=(.+?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text); 
        $Text = preg_replace("/\[youtube\](.+?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
 
+       // oembed tag
+       $Text = oembed_bbcode2html($Text);
+
        call_hooks('bbcode',$Text);
 
        return $Text;
index 5f835dc4bf58dc036a4ebbc33a46cfb3585bca0b..2c9daa5ea6f3b025241a0a2d65f79bc734c417c1 100644 (file)
@@ -1,17 +1,22 @@
 <?php
-
-       require_once("boot.php");
-
-       $a = new App;
-
-       @include(".htconfig.php");
-       require_once("dba.php");
-       $db = new dba($db_host, $db_user, $db_pass, $db_data);
-               unset($db_host, $db_user, $db_pass, $db_data);
-
+require_once("boot.php");
+
+function directory_run($argv, $argc){
+  global $a, $db;
+
+  if(is_null($a)){
+    $a = new App;
+  }
+  
+  if(is_null($db)){
+    @include(".htconfig.php");
+    require_once("dba.php");
+    $db = new dba($db_host, $db_user, $db_pass, $db_data);
+    unset($db_host, $db_user, $db_pass, $db_data);
+  };
 
        if($argc != 2)
-               exit;
+               return;
 
        load_config('system');
 
        $dir = get_config('system','directory_submit_url');
 
        if(! strlen($dir))
-               exit;
+               return;
 
        fetch_url($dir . '?url=' . bin2hex($argv[1]));
 
-       exit;
+       return;
+}
 
+if (array_search(__file__,get_included_files())===0){
+  directory_run($argv,$argc);
+  killme();
+}
index 65cbcec41f66835acca21810cfe64200d43b87dd..6af8df824e76bbf35552e881b81aaa2c783364c5 100644 (file)
@@ -23,7 +23,7 @@ function html2bbcode($s) {
                '/\<div(.*?)\>(.*?)\<\/div\>/is',
                '/\<br(.*?)\>/is',
                '/\<strong\>(.*?)\<\/strong\>/is',
-               '/\<a href=\"(.*?)\"(.*?)\>(.*?)\<\/a\>/is',
+               '/\<a (.*?)href=\"(.*?)\"(.*?)\>(.*?)\<\/a\>/is',
                '/\<code\>(.*?)\<\/code\>/is',
                '/\<span style=\"color:(.*?)\"\>(.*?)\<\/span\>/is',
                '/\<blockquote\>(.*?)\<\/blockquote\>/is',
@@ -48,7 +48,7 @@ function html2bbcode($s) {
                '$2',
                "\n",
                '[b]$1[/b]',
-               '[url=$1]$3[/url]',
+               '[url=$2]$4[/url]',
                '[code]$1[/code]',
                '[color="$1"]$2[/color]',
                '[quote]$1[/quote]',
index 5f8264beb860a64708a3da8ff407fd17d06d9181..359378ff7d9296ead60a69268c33f6975b804402 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 
 require_once('bbcode.php');
+require_once('oembed.php');
+require_once('include/salmon.php');
 
 function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) {
 
@@ -375,6 +377,21 @@ function get_atom_elements($feed,$item) {
        }
 
 
+       /**
+        * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it.
+        */
+
+       $have_real_body = false;
+
+       $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env');
+       if($rawenv) {
+               $have_real_body = true;
+               $res['body'] = $rawenv[0]['data'];
+               $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']);
+               // make sure nobody is trying to sneak some html tags by us
+               $res['body'] = notags(base64url_decode($res['body']));
+       }
+
        $maxlen = get_max_import_size();
        if($maxlen && (strlen($res['body']) > $maxlen))
                $res['body'] = substr($res['body'],0, $maxlen);
@@ -390,11 +407,13 @@ function get_atom_elements($feed,$item) {
        // html.
 
 
-       if((strpos($res['body'],'<')) || (strpos($res['body'],'>'))) {
+       if((strpos($res['body'],'<') !== false) || (strpos($res['body'],'>') !== false)) {
 
                $res['body'] = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s',
                        '[youtube]$1[/youtube]', $res['body']);
 
+               $res['body'] = oembed_html2bbcode($res['body']);
+       
                $config = HTMLPurifier_Config::createDefault();
                $config->set('Cache.DefinitionImpl', null);
 
@@ -407,10 +426,7 @@ function get_atom_elements($feed,$item) {
 
                $res['body'] = html2bbcode($res['body']);
        }
-       else
-               $res['body'] = escape_tags($res['body']);
        
-
        $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow');
        if($allow && $allow[0]['data'] == 1)
                $res['last-child'] = 1;
@@ -423,18 +439,30 @@ function get_atom_elements($feed,$item) {
        else
                $res['private'] = 0;
 
-       $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published');
-       if($rawcreated)
-               $res['created'] = unxmlify($rawcreated[0]['data']);
 
        $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location');
        if($rawlocation)
                $res['location'] = unxmlify($rawlocation[0]['data']);
 
 
+       $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published');
+       if($rawcreated)
+               $res['created'] = unxmlify($rawcreated[0]['data']);
+
+
        $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated');
        if($rawedited)
-               $res['edited'] = unxmlify($rawcreated[0]['data']);
+               $res['edited'] = unxmlify($rawedited[0]['data']);
+
+       if((x($res,'edited')) && (! (x($res,'created'))))
+               $res['created'] = $res['edited']; 
+
+       if(! $res['created'])
+               $res['created'] = $item->get_date('c');
+
+       if(! $res['edited'])
+               $res['edited'] = $item->get_date('c');
+
 
        $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
        if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
@@ -497,7 +525,7 @@ function get_atom_elements($feed,$item) {
                                $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
                        // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
                        $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n";
-                       if((strpos($body,'<')) || (strpos($body,'>'))) {
+                       if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
 
                                $body = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s',
                                        '[youtube]$1[/youtube]', $body);
@@ -509,8 +537,6 @@ function get_atom_elements($feed,$item) {
                                $body = $purifier->purify($body);
                                $body = html2bbcode($body);
                        }
-                       else
-                               $body = escape_tags($body);
 
                        $res['object'] .= '<content>' . $body . '</content>' . "\n";
                }
@@ -538,7 +564,7 @@ function get_atom_elements($feed,$item) {
                                $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
                        // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
                        $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n";
-                       if((strpos($body,'<')) || (strpos($body,'>'))) {
+                       if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
 
                                $body = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s',
                                        '[youtube]$1[/youtube]', $body);
@@ -550,8 +576,6 @@ function get_atom_elements($feed,$item) {
                                $body = $purifier->purify($body);
                                $body = html2bbcode($body);
                        }
-                       else
-                               $body = escape_tags($body);
 
                        $res['target'] .= '<content>' . $body . '</content>' . "\n";
                }
@@ -587,7 +611,7 @@ function encode_rel_links($links) {
        return xmlify($o);
 }
 
-function item_store($arr) {
+function item_store($arr,$force_parent = false) {
 
        if($arr['gravity'])
                $arr['gravity'] = intval($arr['gravity']);
@@ -600,6 +624,13 @@ function item_store($arr) {
 
        if(! x($arr,'type'))
                $arr['type']      = 'remote';
+
+       // Shouldn't happen but we want to make absolutely sure it doesn't leak from a plugin.
+
+       if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) 
+               $arr['body'] = strip_tags($arr['body']);
+
+
        $arr['wall']          = ((x($arr,'wall'))          ? intval($arr['wall'])                : 0);
        $arr['uri']           = ((x($arr,'uri'))           ? notags(trim($arr['uri']))           : random_string());
        $arr['author-name']   = ((x($arr,'author-name'))   ? notags(trim($arr['author-name']))   : '');
@@ -628,20 +659,7 @@ function item_store($arr) {
        $arr['deny_cid']      = ((x($arr,'deny_cid'))      ? trim($arr['deny_cid'])              : '');
        $arr['deny_gid']      = ((x($arr,'deny_gid'))      ? trim($arr['deny_gid'])              : '');
        $arr['private']       = ((x($arr,'private'))       ? intval($arr['private'])             : 0 );
-       $arr['body']          = ((x($arr,'body'))          ? escape_tags(trim($arr['body']))     : '');
-
-       // The content body has been through a lot of filtering and transport escaping by now. 
-       // We don't want to skip any filters, however a side effect of all this filtering 
-       // is that ampersands and <> may have been double encoded, depending on which filter chain
-       // they came through. 
-
-       $arr['body']          = str_replace(
-                                                               array('&amp;amp;', '&amp;gt;', '&amp;lt;', '&amp;quot;'),
-                                                               array('&amp;'    , '&gt;'    , '&lt;',     '&quot;'),
-                                                               $arr['body']
-                                                       );
-
-
+       $arr['body']          = ((x($arr,'body'))          ? trim($arr['body'])                  : '');
 
        if($arr['parent-uri'] === $arr['uri']) {
                $parent_id = 0;
@@ -670,15 +688,28 @@ function item_store($arr) {
                                $arr['parent-uri'] = $r[0]['parent-uri'];
                        }
 
-                       $parent_id = $r[0]['id'];
-                       $allow_cid = $r[0]['allow_cid'];
-                       $allow_gid = $r[0]['allow_gid'];
-                       $deny_cid  = $r[0]['deny_cid'];
-                       $deny_gid  = $r[0]['deny_gid'];
+                       $parent_id      = $r[0]['id'];
+                       $parent_deleted = $r[0]['deleted'];
+                       $allow_cid      = $r[0]['allow_cid'];
+                       $allow_gid      = $r[0]['allow_gid'];
+                       $deny_cid       = $r[0]['deny_cid'];
+                       $deny_gid       = $r[0]['deny_gid'];
                }
                else {
-                       logger('item_store: item parent was not found - ignoring item');
-                       return 0;
+
+                       // Allow one to see reply tweets from status.net even when
+                       // we don't have or can't see the original post.
+
+                       if($force_parent) {
+                               logger('item_store: $force_parent=true, reply converted to top-level post.');
+                               $parent_id = 0;
+                               $arr['thr-parent'] = $arr['parent-uri'];
+                               $arr['parent-uri'] = $arr['uri'];
+                       }
+                       else {
+                               logger('item_store: item parent was not found - ignoring item');
+                               return 0;
+                       }
                }
        }
 
@@ -709,10 +740,10 @@ function item_store($arr) {
                return 0;
        }
 
-       if($arr['parent-uri'] === $arr['uri'])
+       if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))      
                $parent_id = $current_post;
-       if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
+
+       if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
                $private = 1;
        else
                $private = $arr['private']; 
@@ -720,13 +751,14 @@ function item_store($arr) {
        // Set parent id - and also make sure to inherit the parent's ACL's.
 
        $r = q("UPDATE `item` SET `parent` = %d, `allow_cid` = '%s', `allow_gid` = '%s',
-               `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d WHERE `id` = %d LIMIT 1",
+               `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d, `deleted` = %d WHERE `id` = %d LIMIT 1",
                intval($parent_id),
                dbesc($allow_cid),
                dbesc($allow_gid),
                dbesc($deny_cid),
                dbesc($deny_gid),
                intval($private),
+               intval($parent_deleted),
                intval($current_post)
        );
 
@@ -746,11 +778,11 @@ function get_item_contact($item,$contacts) {
 }
 
 
-function dfrn_deliver($owner,$contact,$atom) {
+function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
 
        $a = get_app();
 
-       if((! strlen($contact['dfrn-id'])) && (! $contact['duplex']) && (! ($owner['page-flags'] == PAGE_COMMUNITY)))
+       if((! strlen($contact['issued-id'])) && (! $contact['duplex']) && (! ($owner['page-flags'] == PAGE_COMMUNITY)))
                return 3;
 
        $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
@@ -782,6 +814,12 @@ function dfrn_deliver($owner,$contact,$atom) {
        if(! $xml)
                return 3;
 
+       if(strpos($xml,'<?xml') === false) {
+               logger('dfrn_deliver: no valid XML returned');
+               logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA);
+               return 3;
+       }
+
        $res = simplexml_load_string($xml);
 
        if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
@@ -790,19 +828,20 @@ function dfrn_deliver($owner,$contact,$atom) {
        $postvars     = array();
        $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
        $challenge    = hex2bin((string) $res->challenge);
+       $dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0);
        $rino_allowed = ((intval($res->rino) === 1) ? 1 : 0);
 
        $final_dfrn_id = '';
 
 
-       if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
-               openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
-               openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
-       }
-       else {
+       if(($contact['duplex'] && strlen($contact['pubkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
                openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
                openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
        }
+       else {
+               openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
+               openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
+       }
 
        $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
 
@@ -817,6 +856,8 @@ function dfrn_deliver($owner,$contact,$atom) {
 
        $postvars['dfrn_id']      = $idtosend;
        $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
+       if($dissolve)
+               $postvars['dissolve'] = '1';
 
        if(($contact['rel']) && ($contact['rel'] != REL_FAN) && (! $contact['blocked']) && (! $contact['readonly'])) {
                $postvars['data'] = $atom;
@@ -828,17 +869,28 @@ function dfrn_deliver($owner,$contact,$atom) {
                $postvars['data'] = str_replace('<dfrn:comment-allow>1','<dfrn:comment-allow>0',$atom);
        }
 
-       if($rino && $rino_allowed) {
+       if($rino && $rino_allowed && (! $dissolve)) {
                $key = substr(random_string(),0,16);
                $data = bin2hex(aes_encrypt($postvars['data'],$key));
                $postvars['data'] = $data;
                logger('rino: sent key = ' . $key);     
 
-               if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
-                       openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']);
+
+               if($dfrn_version >= 2.1) {      
+                       if(($contact['duplex'] && strlen($contact['pubkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
+                               openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']);
+                       }
+                       else {
+                               openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']);
+                       }
                }
                else {
-                       openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']);
+                       if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
+                               openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']);
+                       }
+                       else {
+                               openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']);
+                       }
                }
 
                logger('md5 rawkey ' . md5($postvars['key']));
@@ -856,6 +908,13 @@ function dfrn_deliver($owner,$contact,$atom) {
        if((! $curl_stat) || (! strlen($xml)))
                return(-1); // timed out
 
+
+       if(strpos($xml,'<?xml') === false) {
+               logger('dfrn_deliver: phase 2: no valid XML returned');
+               logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA);
+               return 3;
+       }
+
        $res = simplexml_load_string($xml);
 
        return $res->status;
@@ -891,6 +950,10 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                $feed->enable_order_by_date(false);
        $feed->init();
 
+       if($feed->error())
+               logger('consume_feed: Error parsing XML: ' . $feed->error());
+
+
        // Check at the feed level for updated contact name and/or photo
 
        $name_updated  = '';
@@ -1145,7 +1208,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                                        continue;
                                }
                                $datarray = get_atom_elements($feed,$item);
+                               $force_parent = false;
                                if($contact['network'] === 'stat') {
+                                       $force_parent = true;
                                        if(strlen($datarray['title']))
                                                unset($datarray['title']);
                                        $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
@@ -1155,6 +1220,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                                        );
                                        $datarray['last-child'] = 1;
                                }
+
+                               if(($contact['network'] === 'feed') || (! strlen($contact['notify']))) {
+                                       // one way feed - no remote comment ability
+                                       $datarray['last-child'] = 0;
+                               }
                                $datarray['parent-uri'] = $parent_uri;
                                $datarray['uid'] = $importer['uid'];
                                $datarray['contact-id'] = $contact['id'];
@@ -1163,7 +1233,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                                        $datarray['gravity'] = GRAVITY_LIKE;
                                }
 
-                               $r = item_store($datarray);
+                               $r = item_store($datarray,$force_parent);
                                continue;
                        }
 
@@ -1207,6 +1277,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                                        $datarray['last-child'] = 1;
                                }
 
+                               if(($contact['network'] === 'feed') || (! strlen($contact['notify']))) {
+                                       // one way feed - no remote comment ability
+                                       $datarray['last-child'] = 0;
+                               }
+
                                $datarray['parent-uri'] = $item_id;
                                $datarray['uid'] = $importer['uid'];
                                $datarray['contact-id'] = $contact['id'];
@@ -1216,7 +1291,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) {
                        }
                }
        }
-
 }
 
 function new_follower($importer,$contact,$datarray,$item) {
@@ -1392,6 +1466,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false) {
        $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
        $o .= '<published>' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '</published>' . "\r\n";
        $o .= '<updated>' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '</updated>' . "\r\n";
+       $o .= '<dfrn:env>' . base64url_encode($item['body'], true) . '</dfrn:env>' . "\r\n";
        $o .= '<content type="' . $type . '" >' . xmlify(($type === 'html') ? bbcode($item['body']) : $item['body']) . '</content>' . "\r\n";
        $o .= '<link rel="alternate" href="' . xmlify($a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id']) . '" />' . "\r\n";
        if($comment)
index fcd1d6fee0bc4e1a624ff40a969de771b85fb9bb..63b34bd21aa0bd9acc889541ad974595708d51bf 100644 (file)
                                        $('#pause').html('');
                                }
                        }
-                       if(event.keyCode == '36' && event.shiftKey == true) {
-                               if(homebase !== undefined) {
-                                       event.preventDefault();
-                                       document.location = homebase;
-                               }
-                       }
+// this is shift-home on FF, but $ on IE, disabling until I figure out why the diff.
+// update: incompatible usage of onKeyDown vs onKeyPress
+//                     if(event.keyCode == '36' && event.shiftKey == true) {
+//                             if(homebase !== undefined) {
+//                                     event.preventDefault();
+//                                     document.location = homebase;
+//                             }
+//                     }
                });                                     
        });
 
index 4efdad4ce4fd480b864932b7c7ee0f2f083ad35e..a71da853db977f1a5725759b96d9c5231c880b13 100644 (file)
@@ -1,14 +1,19 @@
 <?php
+require_once("boot.php");
 
-       require_once("boot.php");
-
-       $a = new App;
-
-       @include(".htconfig.php");
-       require_once("dba.php");
-       $db = new dba($db_host, $db_user, $db_pass, $db_data);
-               unset($db_host, $db_user, $db_pass, $db_data);
+function notifier_run($argv, $argc){
+       global $a, $db;
 
+       if(is_null($a)){
+               $a = new App;
+       }
+  
+       if(is_null($db)) {
+               @include(".htconfig.php");
+               require_once("dba.php");
+               $db = new dba($db_host, $db_user, $db_pass, $db_data);
+                       unset($db_host, $db_user, $db_pass, $db_data);
+       }
 
        require_once("session.php");
        require_once("datetime.php");
@@ -16,7 +21,7 @@
        require_once('include/bbcode.php');
 
        if($argc < 3)
-               exit;
+               return;
 
        $a->set_baseurl(get_config('system','url'));
 
@@ -29,8 +34,9 @@
                case 'mail':
                default:
                        $item_id = intval($argv[2]);
-                       if(! $item_id)
-                               killme();
+                       if(! $item_id){
+                               return;
+                       }
                        break;
        }
 
                $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
                                intval($item_id)
                );
-               if(! count($message))
-                       killme();
+               if(! count($message)){
+                       return;
+               }
                $uid = $message[0]['uid'];
                $recipients[] = $message[0]['contact-id'];
                $item = $message[0];
 
        }
        else {
-               // find ancestors
 
+               // find ancestors
                $r = q("SELECT `parent`, `uid`, `edited` FROM `item` WHERE `id` = %d LIMIT 1",
                        intval($item_id)
                );
-               if(! count($r))
-                       killme();
 
-               $parent_id = $r[0]['parent'];
+               if((! count($r)) || (! intval($r[0]['parent']))) {
+                       return;
+               }
+
+               $parent_id = intval($r[0]['parent']);
                $uid = $r[0]['uid'];
                $updated = $r[0]['edited'];
 
                        intval($parent_id)
                );
 
-               if(! count($items))
-                       killme();
+               if(! count($items)){
+                       return;
+               }
+
+               // avoid race condition with deleting entries
+
+               if($items[0]['deleted']) {
+                       foreach($items as $item)
+                               $item['deleted'] = 1;
+
        }
 
        $r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags` 
@@ -78,9 +95,9 @@
 
        if(count($r))
                $owner = $r[0];
-       else
-               killme();
-
+       else {
+               return;
+       }
        $hub = get_config('system','huburl');
 
        // If this is a public conversation, notify the feed hub
 
                        $allow_people = expand_acl($parent['allow_cid']);
                        $allow_groups = expand_groups(expand_acl($parent['allow_gid']));
-                       $deny_people = expand_acl($parent['deny_cid']);
-                       $deny_groups = expand_groups(expand_acl($parent['deny_gid']));
+                       $deny_people  = expand_acl($parent['deny_cid']);
+                       $deny_groups  = expand_groups(expand_acl($parent['deny_gid']));
 
                        $conversants = array();
 
 
                $r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
 
-               if( ! count($r))
-                       killme();
+//             if( ! count($r)){
+//                     return;
+//             }
 
-               $contacts = $r;
+               if(count($r))
+                       $contacts = $r;
        }
 
        $feed_template = load_view_file('view/atom_feed.tpl');
        else {
                if($followup) {
                        foreach($items as $item) {  // there is only one item
+                               if(! $item['parent'])
+                                       continue;
                                if($item['id'] == $item_id) {
                                        logger('notifier: followup: item: ' . print_r($item,true), LOGGER_DATA);
                                        $slap  = atom_entry($item,'html',$owner,$owner,false);
                }
                else {
                        foreach($items as $item) {
+                               if(! $item['parent'])
+                                       continue;
+
                                $contact = get_item_contact($item,$contacts);
                                if(! $contact)
                                        continue;
                $recip_str = implode(', ', $recipients);
 
 
-       $r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) AND `blocked` = 0 ",
+       $r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) AND `blocked` = 0 AND `pending` = 0 ",
                dbesc($recip_str)
        );
-       if(! count($r))
-               killme();
 
        // delivery loop
 
        require_once('include/salmon.php');
 
-       foreach($r as $contact) {
-               if($contact['self'])
-                       continue;
+       if(count($r)) {
+               foreach($r as $contact) {
+                       if($contact['self'])
+                               continue;
 
-               $deliver_status = 0;
+                       $deliver_status = 0;
 
-               switch($contact['network']) {
-                       case 'dfrn':
-                               logger('notifier: dfrndelivery: ' . $contact['name']);
-                               $deliver_status = dfrn_deliver($owner,$contact,$atom);
-
-                               logger('notifier: dfrn_delivery returns ' . $deliver_status);
-
-                               if($deliver_status == (-1)) {
-                                       logger('notifier: delivery failed: queuing message');
-                                       // queue message for redelivery
-                                       q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
-                                               VALUES ( %d, '%s', '%s', '%s') ",
-                                               intval($contact['id']),
-                                               dbesc(datetime_convert()),
-                                               dbesc(datetime_convert()),
-                                               dbesc($atom)
-                                       );
-                               }
-                               break;
-                       case 'stat':
-                               if($followup && $contact['notify']) {
-                                       logger('notifier: slapdelivery: ' . $contact['name']);
-                                       $deliver_status = slapper($owner,$contact['notify'],$slap);
+                       switch($contact['network']) {
+                               case 'dfrn':
+                                       logger('notifier: dfrndelivery: ' . $contact['name']);
+                                       $deliver_status = dfrn_deliver($owner,$contact,$atom);
 
+                                       logger('notifier: dfrn_delivery returns ' . $deliver_status);
+       
                                        if($deliver_status == (-1)) {
+                                               logger('notifier: delivery failed: queuing message');
                                                // queue message for redelivery
                                                q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
                                                        VALUES ( %d, '%s', '%s', '%s') ",
                                                        intval($contact['id']),
                                                        dbesc(datetime_convert()),
                                                        dbesc(datetime_convert()),
-                                                       dbesc($slap)
+                                                       dbesc($atom)
                                                );
-
                                        }
+                                       break;
+                               case 'stat':
+                                       if($followup && $contact['notify']) {
+                                               logger('notifier: slapdelivery: ' . $contact['name']);
+                                               $deliver_status = slapper($owner,$contact['notify'],$slap);
+
+                                               if($deliver_status == (-1)) {
+                                                       // queue message for redelivery
+                                                       q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
+                                                               VALUES ( %d, '%s', '%s', '%s') ",
+                                                               intval($contact['id']),
+                                                               dbesc(datetime_convert()),
+                                                               dbesc(datetime_convert()),
+                                                               dbesc($slap)
+                                                       );
 
+                                               }
+       
 
-                               }
-                               else {
-
-                                       // only send salmon if public - e.g. if it's ok to notify
-                                       // a public hub, it's ok to send a salmon
-
-                                       if(count($slaps) && $notify_hub) {
-                                               logger('notifier: slapdelivery: ' . $contact['name']);
-                                               foreach($slaps as $slappy) {
-                                                       if($contact['notify']) {
-                                                               $deliver_status = slapper($owner,$contact['notify'],$slappy);
-                                                               if($deliver_status == (-1)) {
-                                                                       // queue message for redelivery
-                                                                       q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
-                                                                               VALUES ( %d, '%s', '%s', '%s') ",
-                                                                               intval($contact['id']),
-                                                                               dbesc(datetime_convert()),
-                                                                               dbesc(datetime_convert()),
-                                                                               dbesc($slappy)
-                                                                       );                                                              
+                                       }
+                                       else {
+
+                                               // only send salmon if public - e.g. if it's ok to notify
+                                               // a public hub, it's ok to send a salmon
+
+                                               if(count($slaps) && $notify_hub) {
+                                                       logger('notifier: slapdelivery: ' . $contact['name']);
+                                                       foreach($slaps as $slappy) {
+                                                               if($contact['notify']) {
+                                                                       $deliver_status = slapper($owner,$contact['notify'],$slappy);
+                                                                       if($deliver_status == (-1)) {
+                                                                               // queue message for redelivery
+                                                                               q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
+                                                                                       VALUES ( %d, '%s', '%s', '%s') ",
+                                                                                       intval($contact['id']),
+                                                                                       dbesc(datetime_convert()),
+                                                                                       dbesc(datetime_convert()),
+                                                                                       dbesc($slappy)
+                                                                               );                                                              
+                                                                       }
                                                                }
                                                        }
                                                }
                                        }
-                               }
-                               break;
-                       case 'mail':
-                       case 'dspr':
-                       case 'feed':
-                       default:
-                               break;
+                                       break;
+                               case 'mail':
+                               case 'dspr':
+                               case 'feed':
+                               default:
+                                       break;
+                       }
                }
        }
                
                                        continue;
                                $params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
                                post_url($h,$params);
-                               logger('pubsub: publish: ' . $h . ' returned ' . $a->get_curl_code());
+                               logger('pubsub: publish: ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code());
                                if(count($hubs) > 1)
                                        sleep(7);                               // try and avoid multiple hubs responding at precisely the same time
                        }
                }
        }
 
-       killme();
+       if($notify_hub) {
+
+               /**
+                *
+                * If you have less than 150 dfrn friends and it's a public message,
+                * we'll just go ahead and push them out securely with dfrn/rino.
+                * If you've got more than that, you'll have to rely on PuSH delivery.
+                *
+                */
+
+               $max_allowed = ((get_config('system','maxpubdeliver') === false) ? 150 : intval(get_config('system','maxdeliver')));
+                               
+               /**
+                *
+                * Only get the bare essentials and go back for the full record. 
+                * If you've got a lot of friends and we grab all the details at once it could exhaust memory. 
+                *
+                */
+
+               $r = q("SELECT `id`, `name` FROM `contact` 
+                       WHERE `network` = 'dfrn' AND `uid` = %d AND `blocked` = 0 AND `pending` = 0
+                       AND `rel` != %d ",
+                       intval($owner['uid']),
+                       intval(REL_FAN)
+               );
+
+               if((count($r)) && (($max_allowed == 0) || (count($r) < $max_allowed))) {
+
+                       foreach($r as $rr) {
+
+                               /* Don't deliver to folks who have already been delivered to */
+
+                               if(! in_array($rr['id'], $conversants)) {
+                                       $n = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
+                                                       intval($rr['id'])
+                                       );
+
+                                       if(count($n)) {
+                                       
+                                               logger('notifier: dfrnpubdelivery: ' . $n[0]['name']);
+                                               $deliver_status = dfrn_deliver($owner,$n[0],$atom);
+                                       }
+                               }
+                               else
+                                       logger('notifier: dfrnpubdelivery: ignoring ' . $rr['name']);
+                       }
+               }
+       }
+
+       return;
+}
 
+if (array_search(__file__,get_included_files())===0){
+  echo "run!";
+  notifier_run($argv,$argc);
+  killme();
+}
diff --git a/include/oembed.php b/include/oembed.php
new file mode 100644 (file)
index 0000000..37923a8
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+function oembed_replacecb($matches){
+  $embedurl=$matches[1];
+  
+  $r = q("SELECT v FROM `cache` WHERE k='%s'",
+               dbesc($embedurl));
+  if(count($r)){
+       $txt = $r[0]['v'];
+  } else {
+         $ourl = "http://oohembed.com/oohembed/?url=".urlencode($embedurl);  
+         $txt = fetch_url($ourl);
+         //save in cache
+         q("INSERT INTO `cache` VALUES ('%s','%s','%s')",
+               dbesc($embedurl),
+               dbesc($txt),
+               dbesc(datetime_convert()));
+  }
+  $j = json_decode($txt);
+  $ret="<span class='oembed'>";
+  switch ($j->type) {
+    case "video": {
+       if (isset($j->thumbnail_url)) {
+         $tw = (isset($j->thumbnail_width)) ? $j->thumbnail_width:200;
+         $th = (isset($j->thumbnail_height)) ? $j->thumbnail_height:180;
+         $ret = "<a href='".$embedurl."' onclick='this.innerHTML=unescape(\"".urlencode($j->html)."\").replace(/\+/g,\" \"); return false;' >";
+         $ret.= "<img width='$tw' height='$th' src='".$j->thumbnail_url."'>";
+         $ret.= "</a>";
+       } else {
+         $ret=$j->html;
+       }
+       $ret.="<br>";
+    }; break;
+    case "photo": {
+      $ret = "<img width='".$j->width."' height='".$j->height."' src='".$j->url."'>";
+      $ret.="<br>";
+    }; break;  
+    case "link": {
+      //$ret = "<a href='".$embedurl."'>".$j->title."</a>";
+    }; break;  
+    case "rich": {
+      // not so safe.. 
+      $ret = "<blockquote>".$j->html."</blockquote>";
+    }; break;
+  }
+  
+  $embedlink = (isset($j->title))?$j->title:$embedurl;
+  $ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
+  if (isset($j->author_name)) $ret.=" by ".$j->author_name;
+  if (isset($j->provider_name)) $ret.=" on ".$j->provider_name;
+  $ret.="</span>";
+  return $ret;
+}
+
+function oembed_bbcode2html($text){
+       $stopoembed = get_config("system","no_oembed");
+       if ($stopoembed == true){
+               return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "<!-- oembed $1 --><i>". t('Embedding disabled') ." : $1</i><!-- /oembed $1 -->" ,$text);
+       }
+       return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", 'oembed_replacecb' ,$text);
+}
+
+
+function oe_build_xpath($attr, $value){
+       // http://westhoffswelt.de/blog/0036_xpath_to_select_html_by_class.html
+       return "contains( normalize-space( @$attr ), ' $value ' ) or substring( normalize-space( @$attr ), 1, string-length( '$value' ) + 1 ) = '$value ' or substring( normalize-space( @$attr ), string-length( @$attr ) - string-length( '$value' ) ) = ' $value' or @$attr = '$value'";
+}
+
+function oe_get_inner_html( $node ) {
+    $innerHTML= '';
+    $children = $node->childNodes;
+    foreach ($children as $child) {
+        $innerHTML .= $child->ownerDocument->saveXML( $child );
+    }
+    return $innerHTML;
+} 
+
+/**
+ * Find <span class='oembed'>..<a href='url' rel='oembed'>..</a></span>
+ * and replace it with [embed]url[/embed]
+ */
+function oembed_html2bbcode($text) {
+       $dom = DOMDocument::loadHTML($text);
+       $xpath = new DOMXPath($dom);
+       $attr = "oembed";
+       
+       $xattr = oe_build_xpath("class","oembed");
+       $entries = $xpath->query("//span[$xattr]");
+       
+       $xattr = oe_build_xpath("rel","oembed");
+       foreach($entries as $e) {
+               $href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue;
+               if(!is_null($href)) $e->parentNode->replaceChild(new DOMText("[embed]".$href."[embed]"), $e);
+       }
+       return oe_get_inner_html( $dom->getElementsByTagName("body")->item(0) ); 
+}
+
+?>
\ No newline at end of file
index 8234becbb92b95d7ec32dc3fef203f6314aa6abf..20c84990e0576f99cb8e58fa111cb373eb1b3e3b 100644 (file)
@@ -1,14 +1,19 @@
 <?php
-
-
-       require_once('boot.php');
-
-       $a = new App;
-
-       @include('.htconfig.php');
-       require_once('dba.php');
-       $db = new dba($db_host, $db_user, $db_pass, $db_data);
-               unset($db_host, $db_user, $db_pass, $db_data);
+require_once("boot.php");
+
+function poller_run($argv, $argc){
+  global $a, $db;
+
+  if(is_null($a)){
+    $a = new App;
+  }
+  
+  if(is_null($db)){
+    @include(".htconfig.php");
+    require_once("dba.php");
+    $db = new dba($db_host, $db_user, $db_pass, $db_data);
+    unset($db_host, $db_user, $db_pass, $db_data);
+  };
 
        require_once('session.php');
        require_once('datetime.php');
        $a->set_baseurl(get_config('system','url'));
 
        logger('poller: start');
-
+       
        // run queue delivery process in the background
 
        $php_path = ((x($a->config,'php_path') && strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
-       proc_close(proc_open("\"$php_path\" \"include/queue.php\" &", array(), $foo));
-
+       //proc_close(proc_open("\"$php_path\" \"include/queue.php\" &", array(), $foo));
+       proc_run($php_path,"include/queue.php");
+       
+       // clear old cache
+       q("DELETE FROM `cache` WHERE `updated`<'%s'",
+               dbesc(datetime_convert('UTC','UTC',"now - 30 days")));
 
+       $manual_id  = 0;
        $hub_update = false;
-       $force = false;
+       $force      = false;
 
        if(($argc > 1) && ($argv[1] == 'force'))
                $force = true;
 
+       if(($argc > 1) && intval($argv[1])) {
+               $manual_id = intval($argv[1]);
+               $force     = true;
+       }
+
+       $sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
+
        // 'stat' clause is a temporary measure until we have federation subscriptions working both directions
        $contacts = q("SELECT * FROM `contact` 
                WHERE ( ( `network` = 'dfrn' AND ( `dfrn-id` != '' OR (`issued-id` != '' AND `duplex` = 1)))
-               OR ( `network` IN ( 'stat', 'feed' ) AND `poll` != '' )) 
+               OR ( `network` IN ( 'stat', 'feed' ) AND `poll` != '' ))
+               $sql_extra 
                AND `self` = 0 AND `blocked` = 0 AND `readonly` = 0 ORDER BY RAND()");
 
-       if(! count($contacts))
-               killme();
+       if(! count($contacts)){
+               return;
+       }
 
        foreach($contacts as $contact) {
 
+               if($manual_id)
+                       $contact['last-update'] = '0000-00-00 00:00:00';
+
                if($contact['priority'] || $contact['subhub']) {
 
                        $hub_update = true;
@@ -61,7 +83,7 @@
                                $contact['priority'] = (($interval !== false) ? intval($interval) : 3);
                                $hub_update = false;
 
-                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
+                               if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force)
                                                $hub_update = true;
                        }
 
                // loop - next contact
        }  
                
-       killme();
-
-
+       return;
+}
 
+if (array_search(__file__,get_included_files())===0){
+  poller_run($argv,$argc);
+  killme();
+}
index 96ddfa81bc143df6fb2def04ae0111502abbb22d..d4fc7dbd6277d0aa0cebd7fe198fa5a2efdc0d54 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-
+require_once("boot.php");
 
 function update_queue_time($id) {
        logger('queue: requeue item ' . $id);
@@ -16,14 +16,19 @@ function remove_queue_item($id) {
        );
 }
 
-       require_once("boot.php");
-
-       $a = new App;
+function queue_run($argv, $argc){
+  global $a, $db;
 
-       @include(".htconfig.php");
-       require_once("dba.php");
-       $db = new dba($db_host, $db_user, $db_pass, $db_data);
-               unset($db_host, $db_user, $db_pass, $db_data);
+  if(is_null($a)){
+    $a = new App;
+  }
+  
+  if(is_null($db)){
+    @include(".htconfig.php");
+    require_once("dba.php");
+    $db = new dba($db_host, $db_user, $db_pass, $db_data);
+    unset($db_host, $db_user, $db_pass, $db_data);
+  };
 
 
        require_once("session.php");
@@ -50,9 +55,9 @@ function remove_queue_item($id) {
                
        $r = q("SELECT `id` FROM `queue` WHERE `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ");
 
-       if(! count($r))
-               killme();
-
+       if(! count($r)){
+               return;
+       }
        // delivery loop
 
        require_once('include/salmon.php');
@@ -118,7 +123,11 @@ function remove_queue_item($id) {
                }
        }
                
-       killme();
+       return;
 
-       // NOTREACHED
+}
 
+if (array_search(__file__,get_included_files())===0){
+  queue_run($argv,$argc);
+  killme();
+}
index 49384efea76d80009e6036a48669d625bc896ee6..8a56882adb6f16ef6671b8b431cb38428e482c91 100644 (file)
@@ -18,15 +18,13 @@ function salmon_key($pubkey) {
 }
 
 
-function base64url_encode($s) {
+function base64url_encode($s, $strip_padding = false) {
+
        $s = strtr(base64_encode($s),'+/','-_');
-/*
- *  // placeholder for un-padded base64url_encode 
- *  // per latest salmon rev
- *
- *  $s = str_replace('=','',$s);
- *
- */
+
+       if($strip_padding)
+               $s = str_replace('=','',$s);
+
        return $s;
 }
 
index ae6a578cb4a68bb9b1b6c02b6e6a675643ed4fb7..685a76a13185e26baf02960e43bf2e4a17896776 100644 (file)
--- a/index.php
+++ b/index.php
@@ -140,7 +140,7 @@ if(strlen($a->module)) {
        }
        else {
                if((x($_SERVER,'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
-                       logger('index.php: dreamhost_error_hack invoked');
+                       logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
                        goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']);
                }
 
diff --git a/jumploader_z.jar b/jumploader_z.jar
deleted file mode 100644 (file)
index 9ef2abd..0000000
Binary files a/jumploader_z.jar and /dev/null differ
index 7236a200d5a94b090fd76c67cb9bc7098eb29927..61d9ce3986f49056147d353e9c088ab050444a4c 100644 (file)
@@ -53,9 +53,9 @@ function contacts_post(&$a) {
                        return;
                }
        }
+logger('contact_edit ' . print_r($_POST,true));
 
-
-       $priority = intval($_POST['priority']);
+       $priority = intval($_POST['poll']);
        if($priority == (-1))
                
        if($priority > 5 || $priority < 0)
@@ -121,6 +121,15 @@ function contacts_content(&$a) {
                        return; // NOTREACHED
                }
 
+               if($cmd === 'update') {
+
+                       // pull feed and consume it, which should subscribe to the hub.
+
+                       $php_path = ((x($a->config,'php_path') && strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
+                       proc_run($php_path,"include/poller.php","$contact_id");
+                       goaway($a->get_baseurl() . '/contacts/' . $contact_id);
+                       // NOTREACHED
+               }
 
                if($cmd === 'block') {
                        $blocked = (($orig_record[0]['blocked']) ? 0 : 1);
@@ -177,6 +186,12 @@ function contacts_content(&$a) {
                                }
                        }
 
+                       if($orig_record[0]['network'] === 'dfrn') {
+                               require_once('include/items.php');
+                               dfrn_deliver($a->user,$orig_record[0],'placeholder', 1);
+                       }
+
+
                        contact_remove($contact_id);
                        notice( t('Contact has been removed.') . EOL );
                        goaway($a->get_baseurl() . '/contacts');
@@ -242,11 +257,12 @@ function contacts_content(&$a) {
                        '$last_update' => (($r[0]['last-update'] == '0000-00-00 00:00:00') 
                                ? t('Never') 
                                : datetime_convert('UTC',date_default_timezone_get(),$r[0]['last-update'],'D, j M Y, g:i A')),
+                       '$udnow' => t('Update now'),
                        '$profile_select' => contact_profile_assign($r[0]['profile-id'],(($r[0]['network'] !== 'dfrn') ? true : false)),
                        '$contact_id' => $r[0]['id'],
                        '$block_text' => (($r[0]['blocked']) ? t('Unblock this contact') : t('Block this contact') ),
                        '$ignore_text' => (($r[0]['readonly']) ? t('Unignore this contact') : t('Ignore this contact') ),
-                       '$insecure' => (($r[0]['network'] === 'dfrn') ? '' : load_view_file('view/insecure_net.tpl')),
+                       '$insecure' => (($r[0]['network'] === 'stat') ? load_view_file('view/insecure_net.tpl') : ''),
                        '$info' => $r[0]['info'],
                        '$blocked' => (($r[0]['blocked']) ? '<div id="block-message">' . t('Currently blocked') . '</div>' : ''),
                        '$ignored' => (($r[0]['readonly']) ? '<div id="ignore-message">' . t('Currently ignored') . '</div>' : ''),
@@ -351,7 +367,7 @@ function contacts_content(&$a) {
                                '$alt_text' => $alt_text,
                                '$dir_icon' => $dir_icon,
                                '$thumb' => $rr['thumb'], 
-                               '$name' => $rr['name'],
+                               '$name' => substr($rr['name'],0,20),
                                '$sparkle' => $sparkle,
                                '$url' => $url
                        ));
index 41e0771afa6f5b2fe3269517775cdb4004604011..24e8bf106a9a938dcf6e0ddf3352b2839fcbf38f 100644 (file)
@@ -438,8 +438,8 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
 
                                $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
 
-                           proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"activity\" \"$i\" &",
-                       array(),$foo));
+                           //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"activity\" \"$i\" &", array(),$foo));
+                           proc_run($php_path,"include/notifier.php","activity","$i");
 
                        }
 
index 49356d358c4cd2d217006bca20dad413571d44c6..142d1328450d20e06b14a838fd4bb4e3db267914 100644 (file)
@@ -11,6 +11,7 @@ function dfrn_notify_post(&$a) {
        $challenge    = ((x($_POST,'challenge'))    ? notags(trim($_POST['challenge'])) : '');
        $data         = ((x($_POST,'data'))         ? $_POST['data']                    : '');
        $key          = ((x($_POST,'key'))          ? $_POST['key']                     : '');
+       $dissolve     = ((x($_POST,'dissolve'))     ? intval($_POST['dissolve'])        :  0);
 
        $direction = (-1);
        if(strpos($dfrn_id,':') == 1) {
@@ -23,7 +24,7 @@ function dfrn_notify_post(&$a) {
                dbesc($challenge)
        );
        if(! count($r)) {
-               logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id);
+               logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
                xml_status(3);
        }
 
@@ -65,17 +66,24 @@ function dfrn_notify_post(&$a) {
                //NOTREACHED
        }
 
+       // $importer in this case contains the contact record for the remote contact joined with the user record of our user. 
+
        $importer = $r[0];
 
        logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
        logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
 
-       if($importer['readonly']) {
-               // We aren't receiving stuff from this person. But we will quietly ignore them
-               // rather than a blatant "go away" message.
-               logger('dfrn_notify: ignoring');
+       if($dissolve == 1) {
+
+               /**
+                * Relationship is dissolved permanently
+                */
+
+               require_once('include/Contact.php'); 
+               contact_remove($importer['id']);
+               logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
                xml_status(0);
-               //NOTREACHED
+
        }
 
        if(strlen($key)) {
@@ -83,11 +91,21 @@ function dfrn_notify_post(&$a) {
                logger('rino: md5 raw key: ' . md5($rawkey));
                $final_key = '';
 
-               if((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
-                       openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
+               if($dfrn_version >= 2.1) {
+                       if((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
+                               openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
+                       }
+                       else {
+                               openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
+                       }
                }
                else {
-                       openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
+                       if((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
+                               openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
+                       }
+                       else {
+                               openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
+                       }
                }
 
                logger('rino: received key : ' . $final_key);
@@ -95,6 +113,17 @@ function dfrn_notify_post(&$a) {
                logger('rino: decrypted data: ' . $data, LOGGER_DATA);
        }
 
+
+
+
+       if($importer['readonly']) {
+               // We aren't receiving stuff from this person. But we will quietly ignore them
+               // rather than a blatant "go away" message.
+               logger('dfrn_notify: ignoring');
+               xml_status(0);
+               //NOTREACHED
+       }
+
        // Consume notification feed. This may differ from consuming a public feed in several ways
        // - might contain email
        // - might contain remote followup to our message
@@ -260,54 +289,58 @@ function dfrn_notify_post(&$a) {
                                        $datarray['last-child'] = 0;
                                }
                                $posted_id = item_store($datarray);
+                               $parent = 0;
 
                                if($posted_id) {
+                                       $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+                                               intval($posted_id),
+                                               intval($importer['importer_uid'])
+                                       );
+                                       if(count($r))
+                                               $parent = $r[0]['parent'];
+                               
                                        if(! $is_like) {
-                                               $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-                                                       intval($posted_id),
-                                                       intval($importer['importer_uid'])
+                                               $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d",
+                                                       dbesc(datetime_convert()),
+                                                       intval($importer['importer_uid']),
+                                                       intval($r[0]['parent'])
                                                );
-                                               if(count($r)) {
-                                                       $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d",
-                                                               dbesc(datetime_convert()),
-                                                               intval($importer['importer_uid']),
-                                                               intval($r[0]['parent'])
-                                                       );
-                                               }
+
                                                $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1",
-                                                               dbesc(datetime_convert()),
-                                                               intval($importer['importer_uid']),
-                                                               intval($posted_id)
+                                                       dbesc(datetime_convert()),
+                                                       intval($importer['importer_uid']),
+                                                       intval($posted_id)
                                                );
                                        }
 
-                                       $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
-
-                                       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"comment-import\" \"$posted_id\" &", 
-                                               array(),$foo));
-
-                                       if((! $is_like) && ($importer['notify-flags'] & NOTIFY_COMMENT) && (! $importer['self'])) {
-                                               require_once('bbcode.php');
-                                               $from = stripslashes($datarray['author-name']);
-                                               $tpl = load_view_file('view/cmnt_received_eml.tpl');                    
-                                               $email_tpl = replace_macros($tpl, array(
-                                                       '$sitename' => $a->config['sitename'],
-                                                       '$siteurl' =>  $a->get_baseurl(),
-                                                       '$username' => $importer['username'],
-                                                       '$email' => $importer['email'],
-                                                       '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 
-                                                       '$from' => $from,
-                                                       '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))
-                                               ));
-       
-                                               $res = mail($importer['email'], $from . t(' commented on an item at ') . $a->config['sitename'],
-                                                       $email_tpl, "From: " . t('Administrator') . '@' . $a->get_hostname() );
-                                       }
-                               }
+                                       if($posted_id && $parent) {
+                               
+                                               $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
 
-                               xml_status(0);
-                               // NOTREACHED
+                                               proc_run($php_path,"include/notifier.php","comment-import","$posted_id");
+                                       
+                                               if((! $is_like) && ($importer['notify-flags'] & NOTIFY_COMMENT) && (! $importer['self'])) {
+                                                       require_once('bbcode.php');
+                                                       $from = stripslashes($datarray['author-name']);
+                                                       $tpl = load_view_file('view/cmnt_received_eml.tpl');                    
+                                                       $email_tpl = replace_macros($tpl, array(
+                                                               '$sitename' => $a->config['sitename'],
+                                                               '$siteurl' =>  $a->get_baseurl(),
+                                                               '$username' => $importer['username'],
+                                                               '$email' => $importer['email'],
+                                                               '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 
+                                                               '$from' => $from,
+                                                               '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))
+                                                       ));
+               
+                                                       $res = mail($importer['email'], $from . t(' commented on an item at ') . $a->config['sitename'],
+                                                               $email_tpl, "From: " . t('Administrator') . '@' . $a->get_hostname() );
+                                               }
+                                       }
 
+                                       xml_status(0);
+                                       // NOTREACHED
+                               }
                        }
                        else {
                                // regular comment that is part of this total conversation. Have we seen it? If not, import it.
@@ -346,13 +379,13 @@ function dfrn_notify_post(&$a) {
                        
                                if(($datarray['type'] != 'activity') && ($importer['notify-flags'] & NOTIFY_COMMENT)) {
 
-                                       $myconv = q("SELECT `author-link` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d",
+                                       $myconv = q("SELECT `author-link` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
                                                dbesc($parent_uri),
                                                intval($importer['importer_uid'])
                                        );
                                        if(count($myconv)) {
                                                foreach($myconv as $conv) {
-                                                       if($conv['author-link'] != $importer['url'])
+                                                       if(! link_compare($conv['author-link'],$importer['url']))
                                                                continue;
                                                        require_once('bbcode.php');
                                                        $from = stripslashes($datarray['author-name']);
@@ -439,12 +472,13 @@ function dfrn_notify_content(&$a) {
                $r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
 
                $r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` )
-                       VALUES( '%s', '%s', '%s') ",
+                       VALUES( '%s', '%s', %d ) ",
                        dbesc($hash),
                        dbesc($dfrn_id),
-                       intval(time() + 60 )
+                       intval(time() + 90 )
                );
 
+               logger('dfrn_notify: challenge=' . $hash );
 
                $sql_extra = '';
                switch($direction) {
@@ -477,14 +511,14 @@ function dfrn_notify_content(&$a) {
                $encrypted_id = '';
                $id_str = $my_id . '.' . mt_rand(1000,9999);
 
-               if((($r[0]['duplex']) && strlen($r[0]['pubkey'])) || (! strlen($r[0]['prvkey']))) {
-                       openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']);
-                       openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']);
-               }
-               else {
+               if((($r[0]['duplex']) && strlen($r[0]['prvkey'])) || (! strlen($r[0]['pubkey']))) {
                        openssl_private_encrypt($hash,$challenge,$r[0]['prvkey']);
                        openssl_private_encrypt($id_str,$encrypted_id,$r[0]['prvkey']);
                }
+               else {
+                       openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']);
+                       openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']);
+               }
 
                $challenge    = bin2hex($challenge);
                $encrypted_id = bin2hex($encrypted_id);
index 1061cdb899d10529279b1d4b93d1f8285f3bbe2e..85e7fc0afd0eaa855b1fa834e8f0f205e49b435c 100644 (file)
@@ -26,6 +26,7 @@ function dfrn_poll_init(&$a) {
        }
 
        if(($dfrn_id === '') && (! x($_POST,'dfrn_id')) && ($a->argc > 1)) {
+               logger('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] );
                header("Content-type: application/atom+xml");
                $o = get_feed_for($a, '*', $a->argv[1],$last_update);
                echo $o;
index de11ec35d65f08836f23d4a5838507fdb604f4f5..3215ae90a04958352fac8b7eb3e74298e731e7fa 100644 (file)
@@ -173,6 +173,9 @@ function display_content(&$a) {
 
                        $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'] ;
 
+                       // I think this is redundant now but too chicken to remove it unless
+                       // I've had six cups of coffee and tested it completely
+
                        if(($item['network'] === 'dfrn') && (! $item['self'] )) {
                                $profile_url = $redirect_url;
                                $sparkle = ' sparkle';
@@ -216,7 +219,18 @@ function display_content(&$a) {
                        $profile_name   = (((strlen($item['author-name']))   && $diff_author) ? $item['author-name']   : $item['name']);
                        $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $item['thumb']);
 
-                       $profile_link = $profile_url;
+                       // Can we use our special contact URL for this author? 
+
+                       if(strlen($item['author-link'])) {
+                               if((link_compare($item['author-link'],$item['url'])) && ($item['network'] === 'dfrn') && (! $item['self'])) {
+                                       $profile_link = $redirect_url;
+                                       $sparkle = ' sparkle';
+                               }
+                               else {
+                                       $profile_link = $item['author-link'];
+                                       $sparkle = '';
+                               }
+                       }
 
                        if(($item['contact-id'] == remote_user()) || ($item['uid'] == local_user()))
                                $drop = replace_macros(load_view_file('view/wall_item_drop.tpl'), array('$id' => $item['id']));
@@ -291,6 +305,9 @@ function display_content(&$a) {
                }
 
        }
+
+       $o .= '<div class="cc-license">' . t('Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.') . '</div>';
+
        return $o;
 }
 
index 14bdb9fc6d7d1809d11fa2026a3fd1c79f251cd6..8c1dc348fa7d4addd416a48135a5e837fef758ef 100644 (file)
@@ -10,7 +10,9 @@ function follow_post(&$a) {
                // NOTREACHED
        }
 
-       $url = notags(trim($_POST['url']));
+       $url = $orig_url = notags(trim($_POST['url']));
+       
+       $email_conversant = false;
 
        if($url) {
                $links = lrdd($url);
@@ -29,6 +31,11 @@ function follow_post(&$a) {
 
                        }
                }
+               else {
+                       if((strpos($orig_url,'@')) && validate_email($orig_url)) {
+                               $email_conversant = true;
+                       }
+               }
        }       
 
        // If we find a DFRN site, send our subscriber to the other person's
@@ -48,6 +55,9 @@ function follow_post(&$a) {
                }
        }
 
+       $network  = 'stat';
+       $priority = 0;
+
        if($hcard) {
                $vcard = scrape_vcard($hcard);
 
@@ -63,13 +73,64 @@ function follow_post(&$a) {
        if(! $profile)
                $profile = $url;
 
-       // do we have enough information?
 
        if(! x($vcard,'fn'))
                if(x($vcard,'nick'))
                        $vcard['fn'] = $vcard['nick'];
 
+       if((! isset($vcard)) && (! $poll)) {
+
+               $ret = scrape_feed($url);
+
+               if(count($ret) && ($ret['feed_atom'] || $ret['feed_rss'])) {
+                       $poll = ((x($ret,'feed_atom')) ? $ret['feed_atom'] : $ret['feed_rss']);
+                       $vcard = array();
+                       require_once('simplepie/simplepie.inc');
+                   $feed = new SimplePie();
+                       $xml = fetch_url($poll);
+
+               $feed->set_raw_data($xml);
+
+                   $feed->init();
+
+                       $vcard['photo'] = $feed->get_image_url();
+                       $author = $feed->get_author();
+                       if($author) {                   
+                               $vcard['fn'] = trim($author->get_name());
+                               $vcard['nick'] = strtolower($vcard['fn']);
+                               if(strpos($vcard['nick'],' '))
+                                       $vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' ')));
+                               $email = $author->get_email();
+                       }
+                       else {
+                               $item = $feed->get_item(0);
+                               if($item) {
+                                       $author = $item->get_author();
+                                       if($author) {                   
+                                               $vcard['fn'] = trim($author->get_name());
+                                               $vcard['nick'] = strtolower($vcard['fn']);
+                                               if(strpos($vcard['nick'],' '))
+                                                       $vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' ')));
+                                               $email = $author->get_email();
+                                       }
+                                       if(! $vcard['photo']) {
+                                               $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/','thumbnail');
+                                               if($rawmedia && $rawmedia[0]['attribs']['']['url'])
+                                                       $vcard['photo'] = $rawmedia[0]['attribs']['']['url'];
+                                       }
+                               }
+                       }
+                       if((! $vcard['photo']) && strlen($email))
+                               $vcard['photo'] = gravatar_img($email);
+                       
+                       $network = 'feed';
+                       $priority = 2;
+               }
+       }
+
        logger('follow: poll=' . $poll . ' notify=' . $notify . ' profile=' . $profile . ' vcard=' . print_r($vcard,true));
+
+       // do we have enough information?
        
        if(! ((x($vcard['fn'])) && ($poll) && ($profile))) {
                notice( t('The profile address specified does not provide adequate information.') . EOL);
@@ -104,9 +165,9 @@ function follow_post(&$a) {
        }
        else {
                // create contact record 
-               $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `notify`, `poll`, `name`, `nick`, `photo`, `network`, `rel`, 
+               $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `notify`, `poll`, `name`, `nick`, `photo`, `network`, `rel`, `priority`,
                        `blocked`, `readonly`, `pending` )
-                       VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 0 ) ",
+                       VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 0, 0, 0 ) ",
                        intval(local_user()),
                        dbesc(datetime_convert()),
                        dbesc($profile),
@@ -115,8 +176,9 @@ function follow_post(&$a) {
                        dbesc($vcard['fn']),
                        dbesc($vcard['nick']),
                        dbesc($vcard['photo']),
-                       dbesc('stat'),
-                       intval(REL_FAN)
+                       dbesc($network),
+                       intval(REL_FAN),
+                       intval($priority)
                );
        }
 
@@ -158,6 +220,9 @@ function follow_post(&$a) {
 
        // pull feed and consume it, which should subscribe to the hub.
 
+       $php_path = ((x($a->config,'php_path') && strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
+       //proc_close(proc_open("\"$php_path\" \"include/poller.php\" \"$contact_id\" &", array(), $foo));
+       proc_run($php_path,"include/poller.php","$contact_id");
 
        // create a follow slap
 
index 9d4497f5def01d3722f0e6f3fb55063f3a47d416..f67432746fe2d1726dab709e10ac2e1314059fb0 100644 (file)
@@ -57,10 +57,10 @@ function invite_content(&$a) {
                '$invite' => t('Send invitations'),
                '$addr_text' => t('Enter email addresses, one per line:'),
                '$msg_text' => t('Your message:'),
-               '$default_message' => t('Please join my social network on ') . $a->config['sitename'] . t("\r\n") . t("\r\n")
-                       . t('To accept this invitation, please visit:') . t("\r\n") . t("\r\n") . $a->get_baseurl()
-                       . t("\r\n") . t("\r\n") . t('Once you have registered, please connect with me via my profile page at:') 
-                       . t("\r\n") . t("\r\n") . $a->get_baseurl() . '/profile/' . $a->user['nickname'] ,
+               '$default_message' => t('Please join my social network on ') . $a->config['sitename'] . "\r\n" . "\r\n"
+                       . t('To accept this invitation, please visit:') . "\r\n" . "\r\n" . $a->get_baseurl()
+                       . "\r\n" . "\r\n" . t('Once you have registered, please connect with me via my profile page at:') 
+                       . "\r\n" . "\r\n" . $a->get_baseurl() . '/profile/' . $a->user['nickname'] ,
                '$submit' => t('Submit')
        ));
 
index f964e7737db2ab4f87ffaebf35aa2c3d090160f8..38ef580af71ed8b2b5aac5a7f6f9659235f15034 100644 (file)
@@ -1,11 +1,17 @@
 <?php
 
-// This is the POST destination for most all locally posted
-// text stuff. This function handles status, wall-to-wall status, 
-// local comments, and remote coments - that are posted on this site 
-// (as opposed to being delivered in a feed).
-// All of these become an "item" which is our basic unit of 
-// information. 
+/**
+ *
+ * This is the POST destination for most all locally posted
+ * text stuff. This function handles status, wall-to-wall status, 
+ * local comments, and remote coments - that are posted on this site 
+ * (as opposed to being delivered in a feed).
+ * All of these become an "item" which is our basic unit of 
+ * information.
+ * Posts that originate externally or do not fall into the above 
+ * posting categories go through item_store() instead of this function. 
+ *
+ */  
 
 function item_post(&$a) {
 
@@ -71,6 +77,7 @@ function item_post(&$a) {
        $location          = notags(trim($_POST['location']));
        $coord             = notags(trim($_POST['coord']));
        $verb              = notags(trim($_POST['verb']));
+       $emailcc           = notags(trim($_POST['emailcc']));
 
        if(! strlen($body)) {
                notice( t('Empty post discarded.') . EOL );
@@ -165,7 +172,11 @@ function item_post(&$a) {
                }
        }
 
+       /**
+        * Fold multi-line [code] sequences
+        */
 
+       $body = preg_replace('/\[\/code\]\s*\[code\]/m',"\n",$body); 
 
        /**
         * Look for any tags and linkify them
@@ -412,21 +423,51 @@ function item_post(&$a) {
                        );
                }
        }
+       else {
+               logger('mod_item: unable to retrieve post that was just stored.');
+               notify( t('System error. Post not saved.'));
+               goaway($a->get_baseurl() . "/" . $_POST['return'] );
+               // NOTREACHED
+       }
 
        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
 
        logger('mod_item: notifier invoked: ' . "\"$php_path\" \"include/notifier.php\" \"$notify_type\" \"$post_id\" &");
 
-       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"$notify_type\" \"$post_id\" &",
-               array(),$foo));
+       proc_run($php_path, "include/notifier.php", $notify_type, "$post_id");
 
        $datarray['id'] = $post_id;
 
        call_hooks('post_local_end', $datarray);
+
+       if(strlen($emailcc) && $profile_uid == local_user()) {
+               $erecips = explode(',', $emailcc);
+               if(count($erecips)) {
+                       foreach($erecips as $recip) {
+                               $addr = trim($recip);
+                               if(! strlen($addr))
+                                       continue;
+                               $disclaimer = '<hr />' . t('This message was sent to you by ') . $a->user['username'] 
+                                       . t(', a member of the Friendika social network.') . '<br />';
+                               $disclaimer .= t('You may visit them online at') . ' ' 
+                                       . $a->get_baseurl() . '/profile/' . $a->user['nickname'] . '<br />';
+                               $disclaimer .= t('Please contact the sender by replying to this post if you do not wish to receive these messages.') . '<br />'; 
+
+                               $subject  = '[Friendika]' . ' ' . $a->user['username'] . ' ' . t('posted an update.');
+                               $headers  = 'From: ' . $a->user['username'] . ' <' . $a->user['email'] . '>' . "\n";
+                               $headers .= 'MIME-Version: 1.0' . "\n";
+                               $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
+                               $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
+                               $link = '<a href="' . $a->get_baseurl() . '/profile/' . $a->user['nickname'] . '"><img src="' . $author['thumb'] . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
+                               $html    = prepare_body($datarray);
+                               $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';
+                               @mail($addr, $subject, $message, $headers);
+                       }
+               }
+       }
 
        goaway($a->get_baseurl() . "/" . $_POST['return'] );
-       return; // NOTREACHED
+       // NOTREACHED
 }
 
 
@@ -516,11 +557,11 @@ function item_content(&$a) {
                        
                        // send the notification upstream/downstream as the case may be
 
-                       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" &",
-                               array(), $foo));
+                       //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" &", array(), $foo));
+                       proc_run($php_path,"include/notifier.php","drop","$drop_id");
 
                        goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);
-                       return; //NOTREACHED
+                       //NOTREACHED
                }
                else {
                        notice( t('Permission denied.') . EOL);
index 7b20975781452166f942c333b65abf9b28f520ea..c78c1f030ca71d364d9e732f9ad0f28e1983d64d 100644 (file)
@@ -102,8 +102,8 @@ function like_content(&$a) {
                );
 
                $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
-               proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"like\" \"$post_id\" &",
-                       array(),$foo));
+               //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"like\" \"$post_id\" &", array(),$foo));
+               proc_run($php_path,"include/notifier.php","like","$post_id");
                return;
        }
 
@@ -176,8 +176,8 @@ EOT;
 
        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
 
-       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"like\" \"$post_id\" &",
-               array(),$foo));
+       //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"like\" \"$post_id\" &", array(),$foo));
+       proc_run($php_path,"include/notifier.php","like","$post_id");
 
        return; // NOTREACHED
 }
\ No newline at end of file
index a886effeb767832947effcc25f7d68a30a215dfc..9e64e2608b1e341f0e6de41373e643892f8fd85e 100644 (file)
@@ -2,12 +2,23 @@
 
 
 function lockview_content(&$a) {
-
-       $item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
+  
+       $type = (($a->argc > 1) ? $a->argv[1] : 0);
+       if (is_numeric($type)) {
+               $item_id = intval($type);
+               $type='item';
+       } else {
+               $item_id = (($a->argc > 2) ? intval($a->argv[2]) : 0);
+       }
+  
        if(! $item_id)
                killme();
 
-       $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1",
+       if (!in_array($type, array('item','photo','event')))
+               killme();
+     
+       $r = q("SELECT * FROM `%s` WHERE `id` = %d LIMIT 1",
+               dbesc($type),
                intval($item_id)
        );
        if(! count($r))
index 9cc2e2826cf0e5d6eae7d45a6609d2e52cefda77..7615f22bec727ff4ec22b63ba3e8d83296f56221 100644 (file)
@@ -72,8 +72,8 @@ function message_post(&$a) {
        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
        
        if($post_id) {
-               proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"mail\" \"$post_id\" &",
-                       array(),$foo));
+               //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"mail\" \"$post_id\" &", array(),$foo));
+               proc_run($php_path,"include/notifier.php","mail","$post_id");
                notice( t('Message sent.') . EOL );
        }
        else {
index 096c8a79ff1e45a59fdfb9ca5476b8eb40df0cca..2ec06fe614fea94d4c2786f091a4a88ef10cbcf3 100644 (file)
@@ -38,11 +38,11 @@ function network_content(&$a, $update = 0) {
 
        $group = 0;
 
+       $nouveau = false;
+
        if(! $update) {
                $o .= '<script> $(document).ready(function() { $(\'#nav-network-link\').addClass(\'nav-selected\'); });</script>';
 
-               $nouveau = false;
-
                if(($a->argc > 2) && $a->argv[2] === 'new')
                        $nouveau = true;
 
@@ -79,15 +79,21 @@ function network_content(&$a, $update = 0) {
 
                $celeb = ((($a->user['page-flags'] == PAGE_SOAPBOX) || ($a->user['page-flags'] == PAGE_COMMUNITY)) ? true : false);
 
+    $jotplugins = "";
+    call_hooks('jot_tool', $jotplugins);
+
                $o .= replace_macros($tpl,array(
                        '$return_path' => $a->cmd,
                        '$baseurl' => $a->get_baseurl(),
                        '$defloc' => $a->user['default-location'],
                        '$visitor' => 'block',
+                       '$emailcc' => t('CC: email addresses'),
+                       '$emtitle' => t('Example: bob@example.com, mary@example.com'),
                        '$lockstate' => $lockstate,
                        '$acl' => populate_acl((($group) ? $group_acl : $a->user), $celeb),
                        '$bang' => (($group) ? '!' : ''),
-                       '$profile_uid' => $_SESSION['uid']
+                       '$profile_uid' => $_SESSION['uid'],
+                       '$jotplugins' => $jotplugins
                ));
 
 
@@ -240,7 +246,7 @@ function network_content(&$a, $update = 0) {
                                        '$lock' => $lock,
                                        '$thumb' => $profile_avatar,
                                        '$title' => $item['title'],
-                                       '$body' => bbcode($item['body']),
+                                       '$body' => smilies(bbcode($item['body'])),
                                        '$ago' => relative_date($item['created']),
                                        '$location' => $location,
                                        '$indent' => '',
@@ -430,8 +436,10 @@ function network_content(&$a, $update = 0) {
                }
        }
 
-       if(! $update)
+       if(! $update) {
                $o .= paginate($a);
+               $o .= '<div class="cc-license">' . t('Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.') . '</div>';
+       }
 
        return $o;
 }
\ No newline at end of file
index e811ca395714ae0ee4915ed07b404b6b489c08b1..52cc66eae1c31fdbf80281ef7a50db26d6b60a7b 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 require_once('include/Photo.php');
 require_once('include/items.php');
 require_once('include/acl_selectors.php');
@@ -49,9 +48,18 @@ function photos_init(&$a) {
 
 
 
-
 function photos_post(&$a) {
 
+logger('mod/photos.php: photos_post(): begin' , 'LOGGER_DEBUG');
+
+foreach($_REQUEST AS $key => $val) {
+       logger('mod/photos.php: photos_post(): $_REQUEST key: ' . $key . ' val: ' . $val , 'LOGGER_DEBUG');
+}
+
+foreach($_FILES AS $key => $val) {
+       logger('mod/photos.php: photos_post(): $_FILES key: ' . $key . ' val: ' . $val , 'LOGGER_DEBUG');
+}
+
        $can_post  = false;
        $visitor   = 0;
 
@@ -179,9 +187,8 @@ function photos_post(&$a) {
                                        // send the notification upstream/downstream as the case may be
 
                                        if($rr['visible'])
-                                               proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" & ",
-                                                       array(),$foo));
-
+                                               //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" & ",array(),$foo));
+                                               proc_run($php_path,"include/notifier.php","drop","$drop_id");
                                }
                        }
                }
@@ -228,8 +235,8 @@ function photos_post(&$a) {
                                $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
 
                                if($i[0]['visible'])
-                                       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" & ",
-                                               array(),$foo));
+                                       //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"drop\" \"$drop_id\" & ",       array(),$foo));
+                                       proc_run($php_path,"include/notifier.php","drop","$drop_id");
                        }
                }
 
@@ -237,20 +244,26 @@ function photos_post(&$a) {
                return; // NOTREACHED
        }
 
-       if(($a->argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false))) {
+       if(($a->argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false)) || (x($_POST,'albname') !== false)) {
 
-               $desc        = ((x($_POST,'desc'))    ? notags(trim($_POST['desc']))   : '');
-               $rawtags     = ((x($_POST,'newtag'))  ? notags(trim($_POST['newtag'])) : '');
-               $item_id     = ((x($_POST,'item_id')) ? intval($_POST['item_id'])      : 0);
+               $desc        = ((x($_POST,'desc'))    ? notags(trim($_POST['desc']))    : '');
+               $rawtags     = ((x($_POST,'newtag'))  ? notags(trim($_POST['newtag']))  : '');
+               $item_id     = ((x($_POST,'item_id')) ? intval($_POST['item_id'])       : 0);
+               $albname     = ((x($_POST,'albname')) ? notags(trim($_POST['albname'])) : '');
                $resource_id = $a->argv[2];
 
+               if(! strlen($albname))
+                       $albname = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y');
+               
+
                $p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ORDER BY `scale` DESC",
                        dbesc($resource_id),
                        intval($page_owner_uid)
                );
-               if((count($p)) && ($p[0]['desc'] !== $desc)) {
-                       $r = q("UPDATE `photo` SET `desc` = '%s' WHERE `resource-id` = '%s' AND `uid` = %d",
+               if((count($p)) && (($p[0]['desc'] !== $desc) || ($p[0]['album'] !== $albname))) {
+                       $r = q("UPDATE `photo` SET `desc` = '%s', `album` = '%s' WHERE `resource-id` = '%s' AND `uid` = %d",
                                dbesc($desc),
+                               dbesc($albname),
                                dbesc($resource_id),
                                intval($page_owner_uid)
                        );
@@ -454,8 +467,8 @@ function photos_post(&$a) {
 
                                        $item_id = item_store($arr);
                                        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
-                                       proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"tag\" \"$item_id\" & ",
-                                               array(),$foo));
+                                       //proc_close(proc_open("\"$php_path\" \"include/notifier.php\" \"tag\" \"$item_id\" & ",array(),$foo));
+                                       proc_run($php_path,"include/notifier.php","tag","$item_id");
                                }
 
                        }
@@ -466,18 +479,20 @@ function photos_post(&$a) {
        }
 
 
-       // default post action - upload a photo
+       /**
+        * default post action - upload a photo
+        */
 
-       if(! x($_FILES,'userfile'))
-               killme();
+       call_hooks('photo_post_init', $_POST);
 
-       if($_POST['partitionCount'])
-               $java_upload = true;
-       else
-               $java_upload = false;
+       /**
+        * Determine the album to use
+        */
 
-       $album =  notags(trim($_POST['album']));
-       $newalbum = notags(trim($_POST['newalbum']));
+       $album    = notags(trim($_REQUEST['album']));
+       $newalbum = notags(trim($_REQUEST['newalbum']));
+
+       logger('mod/photos.php: photos_post(): album= ' . $album . ' newalbum= ' . $newalbum , 'LOGGER_DEBUG');
 
        if(! strlen($album)) {
                if(strlen($newalbum))
@@ -486,6 +501,16 @@ function photos_post(&$a) {
                        $album = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y');
        }
 
+       /**
+        *
+        * We create a wall item for every photo, but we don't want to
+        * overwhelm the data stream with a hundred newly uploaded photos.
+        * So we will make one photo (the first one uploaded to this album)
+        * visible by default, the rest will become visible over time when and if
+        * they acquire comments, likes, dislikes, and/or tags 
+        *
+        */
+
        $r = q("SELECT * FROM `photo` WHERE `album` = '%s' AND `uid` = %d",
                dbesc($album),
                intval($page_owner_uid)
@@ -495,15 +520,25 @@ function photos_post(&$a) {
        else
                $visible = 0;
 
+       $str_group_allow   = perms2str(((is_array($_REQUEST['group_allow']))   ? $_REQUEST['group_allow']   : explode(',',$_REQUEST['group_allow'])));
+       $str_contact_allow = perms2str(((is_array($_REQUEST['contact_allow'])) ? $_REQUEST['contact_allow'] : explode(',',$_REQUEST['contact_allow'])));
+       $str_group_deny    = perms2str(((is_array($_REQUEST['group_deny']))    ? $_REQUEST['group_deny']    : explode(',',$_REQUEST['group_deny'])));
+       $str_contact_deny  = perms2str(((is_array($_REQUEST['contact_deny']))  ? $_REQUEST['contact_deny']  : explode(',',$_REQUEST['contact_deny'])));
 
-       $str_group_allow   = perms2str($_POST['group_allow']);
-       $str_contact_allow = perms2str($_POST['contact_allow']);
-       $str_group_deny    = perms2str($_POST['group_deny']);
-       $str_contact_deny  = perms2str($_POST['contact_deny']);
+       $ret = array('src' => '', 'filename' => '', 'filesize' => 0);
 
-       $src               = $_FILES['userfile']['tmp_name'];
-       $filename          = basename($_FILES['userfile']['name']);
-       $filesize          = intval($_FILES['userfile']['size']);
+       call_hooks('photo_post_file',$ret);
+
+       if(x($ret,'src') && x($ret,'filesize')) {
+               $src      = $ret['src'];
+               $filename = $ret['filename'];
+               $filesize = $ret['filesize'];
+       }
+       else {
+               $src        = $_FILES['userfile']['tmp_name'];
+               $filename   = basename($_FILES['userfile']['name']);
+               $filesize   = intval($_FILES['userfile']['size']);
+       }
 
        $maximagesize = get_config('system','maximagesize');
 
@@ -513,10 +548,13 @@ function photos_post(&$a) {
                return;
        }
 
+       logger('mod/photos.php: photos_post(): loading the contents of ' . $src , 'LOGGER_DEBUG');
+
        $imagedata = @file_get_contents($src);
        $ph = new Photo($imagedata);
 
        if(! $ph->is_valid()) {
+               logger('mod/photos.php: photos_post(): unable to process image' , 'LOGGER_DEBUG');
                notice( t('Unable to process image.') . EOL );
                @unlink($src);
                killme();
@@ -524,7 +562,7 @@ function photos_post(&$a) {
 
        @unlink($src);
 
-       $width = $ph->getWidth();
+       $width  = $ph->getWidth();
        $height = $ph->getHeight();
 
        $smallest = 0;
@@ -534,6 +572,7 @@ function photos_post(&$a) {
        $r = $ph->store($page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
 
        if(! $r) {
+               logger('mod/photos.php: photos_post(): image store failed' , 'LOGGER_DEBUG');
                notice( t('Image upload failed.') . EOL );
                killme();
        }
@@ -555,7 +594,6 @@ function photos_post(&$a) {
 
        // Create item container
 
-
        $arr = array();
 
        $arr['uid']           = $page_owner_uid;
@@ -584,14 +622,13 @@ function photos_post(&$a) {
 
        $item_id = item_store($arr);
 
-       if(! $java_upload) {
-               goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
-               return; // NOTREACHED
-       }
+       call_hooks('photo_post_end',intval($item_id));
 
-       killme();
-       return; // NOTREACHED
+       // addon uploaders should call "killme()" [e.g. exit] within the photo_post_end hook
+       // if they do not wish to be redirected
 
+       goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
+       // NOTREACHED
 }
 
 
@@ -737,6 +774,22 @@ function photos_content(&$a) {
                $celeb = ((($a->user['page-flags'] == PAGE_SOAPBOX) || ($a->user['page-flags'] == PAGE_COMMUNITY)) ? true : false);
 
                $albumselect .= '</select>';
+
+               $uploader = '';
+
+               $ret = array('post_url' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'],
+                               'addon_text' => $uploader,
+                               'default_upload' => true);
+
+
+               call_hooks('photo_upload_form',$ret);
+
+               $default_upload = '<input type="file" name="userfile" />        <div class="photos-upload-submit-wrapper" >
+               <input type="submit" name="submit" value="' . t('Submit') . '" id="photos-upload-submit" /> </div>';
+
+
+
                $tpl = load_view_file('view/photos_upload.tpl');
                $o .= replace_macros($tpl,array(
                        '$pagename' => t('Upload Photos'),
@@ -744,14 +797,13 @@ function photos_content(&$a) {
                        '$nickname' => $a->data['user']['nickname'],
                        '$newalbum' => t('New album name: '),
                        '$existalbumtext' => t('or existing album name: '),
-                       '$filestext' => t('Select files to upload: '),
                        '$albumselect' => $albumselect,
                        '$permissions' => t('Permissions'),
                        '$aclselect' => (($visitor) ? '' : populate_acl($a->user, $celeb)),
-                       '$archive' => $a->get_baseurl() . '/jumploader_z.jar',
-                       '$nojava' => t('Use the following controls only if the Java uploader [above] fails to launch.'),
-                       '$uploadurl' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'],
-                       '$submit' => t('Submit')
+                       '$uploader' => $ret['addon_text'],
+                       '$default' => (($ret['default_upload']) ? $default_upload : ''),
+                       '$uploadurl' => $ret['post_url']
+
                ));
 
                return $o; 
@@ -861,7 +913,15 @@ function photos_content(&$a) {
                $o .= '<h3>' . '<a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']) . '">' . $ph[0]['album'] . '</a></h3>';
  
                if($can_post && ($ph[0]['uid'] == $owner_uid)) {
-                       $o .= '<div id="photo-edit-link-wrap" ><a id="photo-edit-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/edit' . '">' . t('Edit photo') . '</a></div>';
+                       $o .= '<div id="photo-edit-link-wrap" ><a id="photo-edit-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/edit' . '">' . t('Edit photo') . '</a>';
+                       
+                       // lock
+                       $o .= ( ( ($ph[0]['uid'] == local_user()) && (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) 
+                                       || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ) 
+                                       ? ' - <img src="images/lock_icon.gif" class="lockview" alt="' . t('Private Message') . '" onclick="lockview(event,\'photo/' . $ph[0]['id'] . '\');" />'
+                                       : '');
+                       
+                       $o .= '</div>';
                }
 
 
@@ -943,6 +1003,8 @@ function photos_content(&$a) {
                        $edit_tpl = load_view_file('view/photo_edit.tpl');
                        $o .= replace_macros($edit_tpl, array(
                                '$id' => $ph[0]['id'],
+                               '$album' => $ph[0]['album'],
+                               '$newalbum' => t('New album name'), 
                                '$nickname' => $a->data['user']['nickname'],
                                '$resource_id' => $ph[0]['resource-id'],
                                '$capt_label' => t('Caption'),
@@ -1154,3 +1216,4 @@ function photos_content(&$a) {
        $o .= paginate($a);
        return $o;
 }
+
index 9363793604f2f8a6ab9463ab6cc37eef9bceb2d1..91c1ba6d850e25c2e74a41cd1282b2aaf5bc6a13 100644 (file)
@@ -134,15 +134,22 @@ function profile_content(&$a, $update = 0) {
                                $lockstate = 'lock';
                        else
                                $lockstate = 'unlock';
+       
+      $jotplugins = "";
+      call_hooks('jot_tool', $jotplugins); 
+        
                        $o .= replace_macros($tpl,array(
                                '$baseurl' => $a->get_baseurl(),
                                '$defloc' => (($is_owner) ? $a->user['default-location'] : ''),
                                '$return_path' => $a->cmd,
                                '$visitor' => (($is_owner || $commvisitor) ? 'block' : 'none'),
                                '$lockstate' => $lockstate,
+                               '$emailcc' => t('CC: email addresses'),
+                               '$emtitle' => t('Example: bob@example.com, mary@example.com'),
                                '$bang' => '',
                                '$acl' => (($is_owner) ? populate_acl($a->user, $celeb) : ''),
-                               '$profile_uid' => $a->profile['profile_uid']
+                               '$profile_uid' => $a->profile['profile_uid'],
+                               '$jotplugins' => $jotplugins
                        ));
                }
 
@@ -379,6 +386,8 @@ function profile_content(&$a, $update = 0) {
        }
                
        $o .= paginate($a);
+       $o .= '<div class="cc-license">' . t('Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.') . '</div>';
+
 
        return $o;
 }
index 64093b2de0fb4c062dbd3250f003963440e97761..8b72bfca06ee27104e4f450718dc2dd7dceaea44 100644 (file)
@@ -90,8 +90,8 @@ function profile_photo_post(&$a) {
                                $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
                                $url = $_SESSION['my_url'];
                                if($url && strlen(get_config('system','directory_submit_url')))
-                                       proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &",
-                                               array(),$foo));
+                                       //proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &",array(),$foo));
+                                       proc_run($php_path,"include/directory.php","$url");
                        }
                        else
                                notice( t('Unable to process image') . EOL);
index 0bb476549eb89d93b624c404740b72aba13cd7b3..d74219501a0ce3501888994bf715e908320188af 100644 (file)
@@ -203,8 +203,8 @@ function profiles_post(&$a) {
                        $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
                        $url = $_SESSION['my_url'];
                        if($url && strlen(get_config('system','directory_submit_url')))
-                               proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &",
-                                       array(),$foo));
+                               //proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &", array(),$foo));
+                               proc_run($php_path,"include/directory.php","$url");
                }
        }
 }
diff --git a/mod/removeme.php b/mod/removeme.php
new file mode 100644 (file)
index 0000000..62b9a6d
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+function removeme_post(&$a) {
+
+       if(! local_user())
+               return;
+
+       if((! x($_POST,'qxz_password')) || (! strlen(trim($_POST['qxz_password']))))
+               return;
+
+       if((! x($_POST,'verify')) || (! strlen(trim($_POST['verify']))))
+               return;
+
+       if($_POST['verify'] !== $_SESSION['remove_account_verify'])
+               return;
+
+       $encrypted = hash('whirlpool',trim($_POST['qxz_password']));
+
+       if((strlen($a->user['password'])) && ($encrypted === $a->user['password'])) {
+               require_once('include/Contact.php');
+               user_remove($a->user['uid']);
+               // NOTREACHED
+       }
+
+}
+
+
+
+function removeme_content(&$a) {
+
+       if(! local_user())
+               goaway($a->get_baseurl());
+
+       $hash = random_string();
+
+       $_SESSION['remove_account_verify'] = $hash;
+
+       $tpl = load_view_file('view/removeme.tpl');
+       $o .= replace_macros($tpl, array(
+               '$basedir' => $a->get_baseurl(),
+               '$hash' => $hash,
+               '$title' => t('Remove My Account'),
+               '$desc' => t('This will completely remove your account. Once this has been done it is not recoverable.'),
+               '$passwd' => t('Please enter your password for verification:'),
+               '$submit' => t('Remove My Account')
+       ));
+
+       return $o;              
+
+}
\ No newline at end of file
index 1923c58da1148d4f69742dd6df209fce410559b3..dbbac8bdeb3c9b14f2eededb6a74242c64889d29 100644 (file)
@@ -87,11 +87,14 @@ function settings_post(&$a) {
 
        $err = '';
 
+       $name_change = false;
+
        if($username != $a->user['username']) {
-               if(strlen($username) > 40)
-                       $err .= t(' Please use a shorter name.');
-               if(strlen($username) < 3)
-                       $err .= t(' Name too short.');
+               $name_change = true;
+               if(strlen($username) > 40)
+                       $err .= t(' Please use a shorter name.');
+               if(strlen($username) < 3)
+                       $err .= t(' Name too short.');
        }
 
        if($email != $a->user['email']) {
@@ -165,13 +168,22 @@ function settings_post(&$a) {
                intval(local_user())
        );
 
+
+       if($name_change) {
+               q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `self` = 1 LIMIT 1",
+                       dbesc($username),
+                       dbesc(datetime_convert()),
+                       intval(local_user())
+               );
+       }               
+
        if($old_visibility != $net_publish) {
                // Update global directory in background
                $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
                $url = $_SESSION['my_url'];
                if($url && strlen(get_config('system','directory_submit_url')))
-                       proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &",
-                               array(),$foo));
+                       //proc_close(proc_open("\"$php_path\" \"include/directory.php\" \"$url\" &",array(),$foo));
+                       proc_run($php_path,"include/directory.php","$url");
        }
 
        $_SESSION['theme'] = $theme;
index bd73b2ffbe837d1e657ca8aba9e6536d0c3e3057..90ff85b9dbd4476c3534a6138b108f1d6608d613 100644 (file)
@@ -43,7 +43,7 @@ function viewcontacts_content(&$a) {
                        '$id' => $rr['id'],
                        '$alt_text' => t('Visit ') . $rr['name'] . t('\'s profile'),
                        '$thumb' => $rr['thumb'], 
-                       '$name' => $rr['name'],
+                       '$name' => substr($rr['name'],0,20),
                        '$url' => $rr['url'] 
                ));
        }
index 8728f0c0f3286af70e31fccc17fd6d7436691019..ebccfb31158daa40e829a5fc358773368543501c 100644 (file)
                        rep(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");\r
                        rep(/<span style=\"color:(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");\r
                        rep(/<font>(.*?)<\/font>/gi,"$1");\r
+                       rep(/<img.*?width=\"(.*?)\".*?height=\"(.*?)\".*?src=\"(.*?)\".*?\/>/gi,"[img=$1x$2]$3[/img]");\r
+                       rep(/<img.*?height=\"(.*?)\".*?width=\"(.*?)\".*?src=\"(.*?)\".*?\/>/gi,"[img=$2x$1]$3[/img]");\r
+      rep(/<img.*?src=\"(.*?)\".*?height=\"(.*?)\".*?width=\"(.*?)\".*?\/>/gi,"[img=$3x$2]$1[/img]");\r
+      rep(/<img.*?src=\"(.*?)\".*?width=\"(.*?)\".*?height=\"(.*?)\".*?\/>/gi,"[img=$2x$3]$1[/img]");\r
                        rep(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]");\r
                        rep(/<code>(.*?)<\/code>/gi,"[code]$1[/code]");\r
                        rep(/<\/(strong|b)>/gi,"[/b]");\r
@@ -64,8 +68,8 @@
                        rep(/<u>/gi,"[u]");\r
                        rep(/<blockquote[^>]*>/gi,"[quote]");\r
                        rep(/<\/blockquote>/gi,"[/quote]");\r
-                       rep(/<br \/>/gi,"\n");\r
-                       rep(/<br\/>/gi,"\n");\r
+                       rep(/<br \/>/gi,"\n\n");\r
+                       rep(/<br\/>/gi,"\n\n");\r
                        rep(/<br>/gi,"\n");\r
                        rep(/<p>/gi,"");\r
                        rep(/<\/p>/gi,"\n");\r
                        rep(/\[\/u\]/gi,"</u>");\r
                        rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"<a href=\"$1\">$2</a>");\r
                        rep(/\[url\](.*?)\[\/url\]/gi,"<a href=\"$1\">$1</a>");\r
+                       rep(/\[img=(.*?)x(.*?)\](.*?)\[\/img\]/gi,"<img width=\"$1\" height=\"$2\" src=\"$3\" />");\r
                        rep(/\[img\](.*?)\[\/img\]/gi,"<img src=\"$1\" />");\r
                        rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"<span style=\"color: $1;\">$2</span>");\r
+//                     rep(/\[\/code\]\s*\[code\]/gi,"<br />"); // fold multiline code\r
                        rep(/\[code\](.*?)\[\/code\]/gi,"<code>$1</code>");\r
                        rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"<blockquote>$1</blockquote>");\r
 \r
index 69694b1f9f8cd4ecfe36a64b7ccb80014458a5fa..502b008176b31b1148f4811ee9280f169ebfb39f 100644 (file)
@@ -36,7 +36,7 @@ link_desc:"Insert/edit link",
 unlink_desc:"Unlink",\r
 image_desc:"Insert/edit image",\r
 cleanup_desc:"Cleanup messy code",\r
-code_desc:"Edit HTML Source",\r
+code_desc:"Edit BBcode Source",\r
 sub_desc:"Subscript",\r
 sup_desc:"Superscript",\r
 hr_desc:"Insert horizontal ruler",\r
index 9d124d7db69b022cdca56f02bc4d418e1f4b25c3..ea5a6dae28a8bbc62ebf1f99a5fdf0e8b087e595 100644 (file)
@@ -10,7 +10,7 @@ about_version:"Version",
 about_loaded:"Loaded plugins",\r
 anchor_title:"Insert/edit anchor",\r
 anchor_name:"Anchor name",\r
-code_title:"HTML Source Editor",\r
+code_title:"BBcode Source Editor",\r
 code_wordwrap:"Word wrap",\r
 colorpicker_title:"Select a color",\r
 colorpicker_picker_tab:"Picker",\r
index 36f38aba296a50bf8e8321df4d4b57ddc9a01c96..444063a828673aab64825e4e59a04fbd15f4e5e2 100644 (file)
@@ -18,6 +18,18 @@ del {color:red; text-decoration:line-through}
 cite {border-bottom:1px dashed blue}\r
 acronym {border-bottom:1px dotted #CCC; cursor:help}\r
 abbr {border-bottom:1px dashed #CCC; cursor:help}\r
+code {\r
+       font-family: Courier, monospace;\r
+       white-space: pre;\r
+       display: block;\r
+       overflow: auto;\r
+       border: 1px solid #444;\r
+       background: #EEE;\r
+       color: #444;\r
+       padding: 10px;\r
+       margin-top: 20px;\r
+}\r
+\r
 \r
 /* IE */\r
 * html body {\r
index 0bd58d6d48251f080607c3f1491fc49bd744101d..f7bf9da1eda951242963212b824fa9a4ceeab81a 100644 (file)
@@ -320,3 +320,11 @@ function update_1031() {
 function update_1032() {
        q("ALTER TABLE `profile` ADD `pdesc` CHAR( 255 ) NOT NULL AFTER `name` ");
 }
+
+function update_1033() {
+       q("CREATE TABLE IF NOT EXISTS `cache` (
+               `k` CHAR( 255 ) NOT NULL PRIMARY KEY ,
+               `v` TEXT NOT NULL,
+               `updated` DATETIME NOT NULL
+               ) ENGINE = MYISAM DEFAULT CHARSET=utf8;");
+}
index bb16a47da142914f034f235b5deed7f074cf20de..92ec8501cef4913826d2326a0d5fc45ddcc26e7a 100644 (file)
@@ -3,7 +3,7 @@
        $arr = array();
 
        $files = array('index.php','boot.php');
-       $files = array_merge($files,glob('mod/*'),glob('include/*'));
+       $files = array_merge($files,glob('mod/*'),glob('include/*'),glob('addon/*/*'));
 
 
        foreach($files as $file) {
diff --git a/util/string_translator.php b/util/string_translator.php
new file mode 100644 (file)
index 0000000..4d24f7a
--- /dev/null
@@ -0,0 +1,180 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
+<style>
+       textarea { width: 100% }
+       .no { background: #ffdddd; }
+</style>
+</head>
+<body> 
+<?php
+
+$FRIENDIKA_PATH = dirname(dirname(__FILE__));
+
+/* find languages */
+$LANGS=array();
+$d = dir($FRIENDIKA_PATH."/view");
+while (false !== ($entry = $d->read())) {
+       if (is_file($d->path."/".$entry."/strings.php")){
+               $LANGS[] = $entry;
+       }
+
+}
+$d->close();
+
+
+class A{
+       var $strings = Array();
+}
+
+function loadstrings($lang = NULL){
+       global $FRIENDIKA_PATH;
+       if (is_null($lang)) {
+               $path = $FRIENDIKA_PATH."/util/strings.php";
+       } else {
+               $path = $FRIENDIKA_PATH."/view/$lang/strings.php";
+       }
+       $a = new A();
+       include_once($path);
+       return $a->strings;
+}
+
+
+function savestrings($lang, $strings){
+       global $FRIENDIKA_PATH;
+       $path = $FRIENDIKA_PATH."/view/$lang/strings.php";
+       $f = fopen($path,"w");
+       fwrite($f, "<"); fwrite($f, "?php\n");
+       foreach($strings as $k=>$v){
+            $k=str_replace("'","\'", $k);
+            $k=str_replace("\\\\'","\'", $k);
+            $k=str_replace("\n","\\n", $k);
+            $k=str_replace("\r","\\r", $k);
+            $v=str_replace("'","\'", $v);
+            $v=str_replace("\\\\'","\'", $v);
+         $v=str_replace("\n","\\n", $v);
+            $v=str_replace("\r","\\r", $v);
+
+                fwrite( $f, '$a->strings[\''.$k.'\'] = \''. $v .'\';'."\n" );
+                #echo '$a->strings[\''.$k.'\'] = \''. $v .'\''."\n" ;
+       }
+    fwrite($f, "?"); fwrite($f, ">\n");
+       fclose($f);
+}
+
+
+
+function hexstr($hexstr) {
+  $hexstr = str_replace(' ', '', $hexstr);
+  $hexstr = str_replace('\x', '', $hexstr);
+  $retstr = pack('H*', $hexstr);
+  return $retstr;
+}
+
+function strhex($string) {
+  $hexstr = unpack('H*', $string);
+  return array_shift($hexstr);
+}
+
+
+echo "<h1>Translator</h1>";
+echo "<p>Utility to translate <code>string.php</code> file.";
+echo " Need write permission to language file you want to modify</p>";
+echo "<p>Installed languages:";
+echo "<ul>";
+foreach($LANGS as $l){
+       echo "<li><a href='?lang=$l'>$l</a></li>";
+}
+echo "</ul></p>";
+
+
+$strings['en'] = loadstrings();
+
+if (isset($_GET['lang'])){
+
+       $lang = $_GET['lang'];
+       $strings[$lang] = loadstrings($lang);
+       
+       $n1 = count($strings['en']);
+       $n2 = count($strings[$lang]);
+       
+       echo "<pre>";
+       echo "Tranlsate en to $lang<br>";
+       //echo "Translated $n2 over $n1 strings<br>";
+       echo "</pre><hr/>";
+
+
+
+       if (isset($_POST['save'])){
+               echo "saving...";
+               foreach ($_POST as $k=>$v){
+                       if ($k!="save" && $k!="from"){
+                           $k=hexstr($k);
+                               $strings[$lang][$k] = $v;
+                       }
+               }
+               savestrings($lang, $strings[$lang]);
+               echo "ok.<br>";
+       }
+
+
+
+
+
+       if (!isset($_POST['from'])){
+               $from=0;
+       } else {
+               $from = $_POST['from'];
+               if ($_POST['save']=="Next")
+                       $from += 10;
+               if ($_POST['save']=="Prev")
+                       $from -= 10;
+       }
+       $count = count($strings['en']);
+       $len = 10;
+       if ($from+$len>$count) $len=$count-$from;
+       $thestrings = array_slice($strings['en'], $from, $len, true);
+       
+
+       
+       echo "<form method='POST'>";
+       
+       if ($from>0)
+    echo "<input type='submit' name='save' id='save' value='Prev'/>";
+  echo "<input type='submit' name='reload' id='reload' value='Reload'/>";   
+  if ($from+$len<$count)
+    echo "<input type='submit' name='save' id='save' value='Next'/>";
+       
+       foreach($thestrings as $k=>$v){
+               $id = strhex($k);
+               $translation = $strings[$lang][$k];
+               
+               $v=str_replace("\n","\\n", $v);
+           $v=str_replace("\r","\\r", $v);
+               $translation=str_replace("\n","\\n", $translation);
+           $translation=str_replace("\r","\\r", $translation);
+               
+               $istranslate = $translation != '' ? 'yes':'no';
+               echo "<dl class='$istranslate'>";
+               echo "<dt><label for='$id'>".htmlspecialchars($v)."</label></dt>";
+               echo "<dd><textarea id='$id' name='$id'>$translation</textarea></dd>";
+               echo "</dl>";
+       }
+       
+       
+       echo "<input type='hidden' name='from' value='$from'/>";        
+
+       if ($from>0)
+               echo "<input type='submit' name='save' id='save' value='Prev'/>";
+       echo "<input type='submit' name='reload' id='reload' value='Reload'/>";         
+       if ($from+$len<$count)
+               echo "<input type='submit' name='save' id='save' value='Next'/>";
+
+       echo "</form>";
+       
+       
+}
+?>
+</body>
+</html>
+
index 8b58a6b7a5c8014a046c498ee636ad151a4f22c2..762c68d2bbaadcf36986f1400f968b7cece56bb5 100644 (file)
@@ -84,6 +84,7 @@ $a->strings['Delete contact'] = 'Delete contact';
 $a->strings['Last updated: '] = 'Last updated: ';
 $a->strings['Update public posts: '] = 'Update public posts: ';
 $a->strings['Never'] = 'Never';
+$a->strings['Update now'] = 'Update now';
 $a->strings['Unblock this contact'] = 'Unblock this contact';
 $a->strings['Block this contact'] = 'Block this contact';
 $a->strings['Unignore this contact'] = 'Unignore this contact';
@@ -163,6 +164,7 @@ $a->strings['Private Message'] = 'Private Message';
 $a->strings['This is you'] = 'This is you';
 $a->strings['View $name\'s profile'] = 'View $name\'s profile';
 $a->strings['Item has been removed.'] = 'Item has been removed.';
+$a->strings['Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.'] = 'Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.';
 $a->strings['The profile address specified does not provide adequate information.'] = 'The profile address specified does not provide adequate information.';
 $a->strings['Limited profile. This person will be unable to receive direct/personal notifications from you.'] = 'Limited profile. This person will be unable to receive direct/personal notifications from you.';
 $a->strings['Unable to retrieve contact information.'] = 'Unable to retrieve contact information.';
@@ -211,7 +213,6 @@ $a->strings['Send invitations'] = 'Send invitations';
 $a->strings['Enter email addresses, one per line:'] = 'Enter email addresses, one per line:';
 $a->strings['Your message:'] = 'Your message:';
 $a->strings['Please join my social network on '] = 'Please join my social network on ';
-$a->strings["\r\n"] = "\r\n";
 $a->strings['To accept this invitation, please visit:'] = 'To accept this invitation, please visit:';
 $a->strings['Once you have registered, please connect with me via my profile page at:'] = 'Once you have registered, please connect with me via my profile page at:';
 $a->strings['Unable to locate original post.'] = 'Unable to locate original post.';
@@ -219,6 +220,11 @@ $a->strings['Empty post discarded.'] = 'Empty post discarded.';
 $a->strings['Wall Photos'] = 'Wall Photos';
 $a->strings[" commented on your item at "] = " commented on your item at ";
 $a->strings[" posted on your profile wall at "] = " posted on your profile wall at ";
+$a->strings['This message was sent to you by '] = 'This message was sent to you by ';
+$a->strings[', a member of the Friendika social network.'] = ', a member of the Friendika social network.';
+$a->strings['You may visit them online at'] = 'You may visit them online at';
+$a->strings['Please contact the sender by replying to this post if you do not wish to receive these messages.'] = 'Please contact the sender by replying to this post if you do not wish to receive these messages.';
+$a->strings['posted an update.'] = 'posted an update.';
 $a->strings['photo'] = 'photo';
 $a->strings['status'] = 'status';
 $a->strings['likes'] = 'likes';
@@ -251,6 +257,8 @@ $a->strings['Delete message'] = 'Delete message';
 $a->strings['Send Reply'] = 'Send Reply';
 $a->strings['Normal View'] = 'Normal View';
 $a->strings['New Item View'] = 'New Item View';
+$a->strings['CC: email addresses'] = 'CC: email addresses';
+$a->strings['Example: bob@example.com, mary@example.com'] = 'Example: bob@example.com, mary@example.com';
 $a->strings['No such group'] = 'No such group';
 $a->strings['Group is empty'] = 'Group is empty';
 $a->strings['Group: '] = 'Group: ';
@@ -287,9 +295,7 @@ $a->strings['No photos selected'] = 'No photos selected';
 $a->strings['Upload Photos'] = 'Upload Photos';
 $a->strings['New album name: '] = 'New album name: ';
 $a->strings['or existing album name: '] = 'or existing album name: ';
-$a->strings['Select files to upload: '] = 'Select files to upload: ';
 $a->strings['Permissions'] = 'Permissions';
-$a->strings['Use the following controls only if the Java uploader [above] fails to launch.'] = 'Use the following controls only if the Java uploader [above] fails to launch.';
 $a->strings['Edit Album'] = 'Edit Album';
 $a->strings['View Photo'] = 'View Photo';
 $a->strings['Photo not available'] = 'Photo not available';
@@ -297,6 +303,7 @@ $a->strings['Edit photo'] = 'Edit photo';
 $a->strings['View Full Size'] = 'View Full Size';
 $a->strings['Tags: '] = 'Tags: ';
 $a->strings['[Remove any tag]'] = '[Remove any tag]';
+$a->strings['New album name'] = 'New album name';
 $a->strings['Caption'] = 'Caption';
 $a->strings['Add a Tag'] = 'Add a Tag';
 $a->strings['Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'] = 'Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping';
@@ -340,7 +347,6 @@ $a->strings['Your registration is pending approval by the site owner.'] = 'Your
 $a->strings["You may \x28optionally\x29 fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "You may \x28optionally\x29 fill in this form via OpenID by supplying your OpenID and clicking 'Register'.";
 $a->strings['If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.'] = 'If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.';
 $a->strings["Your OpenID \x28optional\x29: "] = "Your OpenID \x28optional\x29: ";
-$a->strings['Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.'] = 'Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.';
 $a->strings['Registration'] = 'Registration';
 $a->strings['Your Full Name ' . "\x28" . 'e.g. Joe Smith' . "\x29" . ': '] = 'Your Full Name ' . "\x28" . 'e.g. Joe Smith' . "\x29" . ': ';
 $a->strings['Your Email Address: '] = 'Your Email Address: ';
@@ -350,6 +356,9 @@ $a->strings['Register'] = 'Register';
 $a->strings['Please login.'] = 'Please login.';
 $a->strings['Registration revoked for '] = 'Registration revoked for ';
 $a->strings['Account approved.'] = 'Account approved.';
+$a->strings['Remove My Account'] = 'Remove My Account';
+$a->strings['This will completely remove your account. Once this has been done it is not recoverable.'] = 'This will completely remove your account. Once this has been done it is not recoverable.';
+$a->strings['Please enter your password for verification:'] = 'Please enter your password for verification:';
 $a->strings['Passwords do not match. Password unchanged.'] = 'Passwords do not match. Password unchanged.';
 $a->strings['Empty passwords are not allowed. Password unchanged.'] = 'Empty passwords are not allowed. Password unchanged.';
 $a->strings['Password changed.'] = 'Password changed.';
@@ -414,6 +423,7 @@ $a->strings['Network'] = 'Network';
 $a->strings['Notifications'] = 'Notifications';
 $a->strings['Settings'] = 'Settings';
 $a->strings['Profiles'] = 'Profiles';
+$a->strings['Embedding disabled'] = 'Embedding disabled';
 $a->strings['Male'] = 'Male';
 $a->strings['Female'] = 'Female';
 $a->strings['Currently Male'] = 'Currently Male';
@@ -467,6 +477,19 @@ $a->strings['Uncertain'] = 'Uncertain';
 $a->strings['Complicated'] = 'Complicated';
 $a->strings['Don\'t care'] = 'Don\'t care';
 $a->strings['Ask me'] = 'Ask me';
+$a->strings['Facebook status update failed.'] = 'Facebook status update failed.';
+$a->strings['Select files to upload: '] = 'Select files to upload: ';
+$a->strings['Use the following controls only if the Java uploader [above] fails to launch.'] = 'Use the following controls only if the Java uploader [above] fails to launch.';
+$a->strings['Upload a file'] = 'Upload a file';
+$a->strings['Drop files here to upload'] = 'Drop files here to upload';
+$a->strings['Failed'] = 'Failed';
+$a->strings['No files were uploaded.'] = 'No files were uploaded.';
+$a->strings['Uploaded file is empty'] = 'Uploaded file is empty';
+$a->strings['Uploaded file is too large'] = 'Uploaded file is too large';
+$a->strings['File has an invalid extension, it should be one of '] = 'File has an invalid extension, it should be one of ';
+$a->strings['Upload was cancelled, or server error encountered'] = 'Upload was cancelled, or server error encountered';
+$a->strings['Randplace Settings'] = 'Randplace Settings';
+$a->strings['Enable Randplace Plugin'] = 'Enable Randplace Plugin';
 $a->strings['Africa/Abidjan'] = 'Africa/Abidjan';
 $a->strings['Africa/Accra'] = 'Africa/Accra';
 $a->strings['Africa/Addis_Ababa'] = 'Africa/Addis_Ababa';
diff --git a/view/de/cmnt_received_eml.tpl b/view/de/cmnt_received_eml.tpl
new file mode 100644 (file)
index 0000000..500c93e
--- /dev/null
@@ -0,0 +1,17 @@
+
+Hallo $username,
+
+'$from' hat einen Pinnwandeintrag kommentiert dem du auch folgst.
+
+-----
+$body
+-----
+
+Um die gesamte Konversation zu sehen melde dich bitte bei $siteurl an:
+
+$display
+
+Danke für die Aufmerksamkeit
+        $sitename Administrator
+
diff --git a/view/de/contact_edit.tpl b/view/de/contact_edit.tpl
new file mode 100644 (file)
index 0000000..0b32bdd
--- /dev/null
@@ -0,0 +1,86 @@
+
+<h2>$header</h2>
+
+<div id="contact-edit-banner-name">$name</div>
+
+<form action="contacts/$contact_id" method="post" >
+<input type="hidden" name="contact_id" value="$contact_id">
+
+<div id="contact-edit-wrapper" >
+
+       <div id="contact-edit-photo-wrapper" >
+               <img id="contact-edit-direction-icon" src="$dir_icon" alt="$alt_text" title="$alt_text" />
+               <div id="contact-edit-photo" >
+                       <a href="$url" title="$visit" /><img src="$photo" $sparkle alt="$name" /></a>
+               </div>
+               <div id="contact-edit-photo-end" ></div>
+       </div>
+       <div id="contact-edit-nav-wrapper" >
+
+               <div id="contact-edit-links" >
+                       <a href="contacts/$contact_id/block" id="contact-edit-block-link" ><img src="images/b_block.gif" alt="$blockunblock" title="$block_text"/></a>
+                       <a href="contacts/$contact_id/ignore" id="contact-edit-ignore-link" ><img src="images/no.gif" alt="$ignorecont" title="$ignore_text"/></a>
+               </div>
+               <div id="contact-drop-links" >
+                       <a href="contacts/$contact_id/drop" id="contact-edit-drop-link" onclick="return confirmDelete();" ><img src="images/b_drophide.gif" alt="$delete" title="$delete" onmouseover="imgbright(this);" onmouseout="imgdull(this);" /></a>
+               </div>
+               <div id="contact-edit-nav-end"></div>
+
+
+               <div id="contact-edit-poll-wrapper">
+                       <div id="contact-edit-last-update-text">$lastupdtext<span id="contact-edit-last-updated">$last_update</span</div>
+                       <div id="contact-edit-poll-text">$updpub</div>
+                       $poll_interval
+                       <div id="contact-edit-update-now"><a href="contacts/$contact_id/update">$udnow</a></div>
+               </div>
+       </div>
+       <div id="contact-edit-end" ></div>
+
+$insecure
+$blocked
+$ignored
+
+
+<div id="contact-edit-info-wrapper">
+<h4>Kontaktinformation / Notizen</h4>
+<textarea id="contact-edit-info" rows="10" cols="72" name="info" >$info</textarea>
+</div>
+<div id="contact-edit-info-end"></div>
+
+<input class="contact-edit-submit" type="submit" name="submit" value="Submit" />
+
+<div id="contact-edit-profile-select-text">
+<h4>Profil Sichtbarkeit</h4>
+<p>Bitte wähle das Profil, das du $name gezeigt werden soll, wenn er sich dein
+Profil in Friendika betrachtet.
+</p> 
+</div>
+$profile_select
+<div id="contact-edit-profile-select-end"></div>
+
+<input class="contact-edit-submit" type="submit" name="submit" value="Submit" />
+
+
+<div id="contact-edit-rating-wrapper">
+<h4>Online Reputation</h4>
+<p>
+Gelegentlich werden sich deine Freunde nach der online Legitimität dieser
+Person erkundigen. Du kannst ihnen helfen bei der Entscheidung ob sie mit
+dieser Person interagieren wollen indem du den "Ruf" der Person bewertest.
+</p>
+<div id="contact-edit-rating-select-wrapper">
+$rating
+</div>
+<div id="contact-edit-rating-explain">
+<p>
+Bitte nimm dir einen Moment um deine Auswahl zu kommentieren wenn du meinst das
+könnte anderen weiter helfen.
+</p>
+<textarea id="contact-edit-rating-text" name="reason" rows="3" cols="64" >$reason</textarea>
+</div>
+</div>
+$groups
+
+<input class="contact-edit-submit" type="submit" name="submit" value="Submit" />
+</form>
+</div>
diff --git a/view/de/cropbody.tpl b/view/de/cropbody.tpl
new file mode 100644 (file)
index 0000000..0211fe3
--- /dev/null
@@ -0,0 +1,58 @@
+<h1>Bild zuschneiden</h1>
+<p id="cropimage-desc">
+Zur optimalen Darstellung des Bildes kann es nun auf einen Bereich
+zugeschnitten werden. Bitte wähle diesen Bereich.
+</p>
+<div id="cropimage-wrapper">
+<img src="$image_url" id="croppa" class="imgCrop" alt="" />
+</div>
+<div id="cropimage-preview-wrapper" >
+<div id="previewWrap" ></div>
+</div>
+
+<script type="text/javascript" language="javascript">
+
+       function onEndCrop( coords, dimensions ) {
+               $( 'x1' ).value = coords.x1;
+               $( 'y1' ).value = coords.y1;
+               $( 'x2' ).value = coords.x2;
+               $( 'y2' ).value = coords.y2;
+               $( 'width' ).value = dimensions.width;
+               $( 'height' ).value = dimensions.height;
+       }
+
+       Event.observe( window, 'load', function() {
+               new Cropper.ImgWithPreview(
+               'croppa',
+               {
+                       previewWrap: 'previewWrap',
+                       minWidth: 175,
+                       minHeight: 175,
+                       maxWidth: 640,
+                       maxHeight: 640,
+                       ratioDim: { x: 100, y:100 },
+                       displayOnInit: true,
+                       onEndCrop: onEndCrop
+               }
+               );
+       }
+       );
+
+</script>
+
+<form action="profile_photo/$resource" id="crop-image-form" method="post" />
+
+<input type="hidden" name="imagename" value="$hash" />
+<input type="hidden" name="cropfinal" value="1" />
+<input type="hidden" name="xstart" id="x1" />
+<input type="hidden" name="ystart" id="y1" />
+<input type="hidden" name="xfinal" id="x2" />
+<input type="hidden" name="yfinal" id="y2" />
+<input type="hidden" name="height" id="height" />
+<input type="hidden" name="width"  id="width" />
+
+<div id="crop-image-submit-wrapper" >
+<input type="submit" name="submit" value="Done Editing" />
+</div>
+
+</form>
diff --git a/view/de/dfrn_req_confirm.tpl b/view/de/dfrn_req_confirm.tpl
new file mode 100644 (file)
index 0000000..88d05b4
--- /dev/null
@@ -0,0 +1,17 @@
+
+<p id="dfrn-request-homecoming" >
+Willkommen zu Hause $username. 
+<br />
+Bitte bestätige deine Vorstellung bei $dfrn_url.
+
+</p>
+<form id="dfrn-request-homecoming-form" action="dfrn_request/$nickname" method="post"> 
+<input type="hidden" name="dfrn_url" value="$dfrn_url" />
+<input type="hidden" name="confirm_key" value="$confirm_key" />
+<input type="hidden" name="localconfirm" value="1" />
+$aes_allow
+
+<div id="dfrn-request-homecoming-submit-wrapper" >
+<input id="dfrn-request-homecoming-submit" type="submit" name="submit" value="Confirm" />
+</div>
+</form>
diff --git a/view/de/directory_header.tpl b/view/de/directory_header.tpl
new file mode 100644 (file)
index 0000000..cda2f49
--- /dev/null
@@ -0,0 +1,14 @@
+<h1>Verzeichnis dieser Seite</h1>
+
+$globaldir
+
+$finding
+
+<div id="directory-search-wrapper">
+<form id="directory-search-form" action="directory" method="get" >
+<input type="text" name="search" id="directory-search" class="search-input" onfocus="this.select();" value="$search" />
+<input type="submit" name="submit" id="directory-search-submit" value="Find" />
+</form>
+</div>
+<div id="directory-search-end"></div>
+
diff --git a/view/de/follow_notify_eml.tpl b/view/de/follow_notify_eml.tpl
new file mode 100644 (file)
index 0000000..d7259a2
--- /dev/null
@@ -0,0 +1,15 @@
+
+Hallo $myname,
+
+'$requestor' folgt dir jetzt auf $sitename.
+
+Du kannst das Profil unter $url abrufen.
+
+Bitte melde dich auf deiner Seite an um die Anfrage zu bestätigen, abzulehnen
+oder zu ignorieren.
+
+$siteurl
+
+Grüße,
+    $sitename Administrator
+
diff --git a/view/de/friend_complete_eml.tpl b/view/de/friend_complete_eml.tpl
new file mode 100644 (file)
index 0000000..f6e0adf
--- /dev/null
@@ -0,0 +1,22 @@
+
+Lieber $username,
+
+großartige Neuigkeiten... '$fn' von '$dfrn_url' hat deine Kontaktaufnahme auf
+'$sitename' bestätigt.
+
+Ihr seit nun beidseitige Freunde und könnt Statusmitteilungen, Fotos und
+EMail ohne Einschränkungen austauschen.
+
+Bitte rufe deine 'Kontakte' Seite auf $sitename auf um du Änderungen an
+dieser Freundschaft vorzunehmen.
+
+$siteurl
+
+[Du könntest zum Beispiel ein neue Profil anlegen mit Informationen die nicht
+für die Allgemeinheit bestimmt sind, die du aber gerne mit '$fn' teilen
+möchtest].
+
+Mit freundlichen Grüßen
+        $sitename Administrator
+
diff --git a/view/de/group_edit.tpl b/view/de/group_edit.tpl
new file mode 100644 (file)
index 0000000..1dea97f
--- /dev/null
@@ -0,0 +1,24 @@
+<h2>Gruppen Editor</h2>
+
+
+<div id="group-edit-wrapper" >
+<form action="group/$gid" id="group-edit-form" method="post" >
+<div id="group-edit-name-wrapper" >
+<label id="group-edit-name-label" for="group-edit-name" >Gruppen Name: </label>
+<input type="text" id="group-edit-name" name="groupname" value="$name" />
+</div>
+<div id="group-edit-name-end"></div>
+<div id="group-edit-select-wrapper" >
+<label id="group_members_select_label"  for="group_members_select" >Mitglieder:</label>
+$selector
+
+</div>
+$drop
+<div id="group_members_select_end"></div>
+<div id="group-edit-submit-wrapper" >
+<input type="submit" name="submit" value="Submit" >
+</div>
+
+<div id="group-edit-select-end" ></div>
+</form>
+</div>
diff --git a/view/de/group_new.tpl b/view/de/group_new.tpl
new file mode 100644 (file)
index 0000000..639eab8
--- /dev/null
@@ -0,0 +1,23 @@
+
+
+
+<div id="group-new-wrapper" >
+<form action="group/new" method="post">
+
+<div id="group-new-text">
+<p>
+Erstelle eine neue Gruppe für Freunde/Kontakte.
+
+<div id="group-new-input-wrapper">
+<label id="group-new-label" for="group-new-name" >Gruppen Name: </label>
+<input name="groupname" id="group-new-name" />
+</div>
+<div id="group-new-input-end" ></div>
+
+<div id="group-new-submit-wrapper" >
+<input type="submit" name="submit" value="Submit" />
+</form>
+</div>
+<div id="group-new-end"></div>
+
diff --git a/view/de/head.tpl b/view/de/head.tpl
new file mode 100644 (file)
index 0000000..50dd9ca
--- /dev/null
@@ -0,0 +1,31 @@
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<base href="$baseurl" />
+<link rel="stylesheet" type="text/css" href="$stylesheet" media="all" />
+<link rel="shortcut icon" href="$baseurl/images/ff-32.jpg">
+
+<!--[if IE]>
+<script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+<![endif]-->
+<script type="text/javascript" src="$baseurl/include/jquery.js" ></script>
+<script type="text/javascript" src="$baseurl/include/main.js" ></script>
+<script>
+
+       function confirmDelete() { return confirm("Delete this item?"); }
+       function commentOpen(obj,id) {
+               if(obj.value == 'Comment') {
+                       obj.value = '';
+                       obj.className = "comment-edit-text-full";
+                       openMenu("comment-edit-submit-wrapper-" + id);
+               }
+       }
+       function commentClose(obj,id) {
+               if(obj.value == '') {
+                       obj.value = 'Comment';
+                       obj.className="comment-edit-text-empty";
+                       closeMenu("comment-edit-submit-wrapper-" + id);
+               }
+       }
+
+</script>
+
+
diff --git a/view/de/htconfig.tpl b/view/de/htconfig.tpl
new file mode 100644 (file)
index 0000000..c7c19bf
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+// Set the following for your MySQL installation
+// Copy or rename this file to .htconfig.php
+
+$db_host = '$dbhost';
+$db_user = '$dbuser';
+$db_pass = '$dbpass';
+$db_data = '$dbdata';
+
+// If you are using a subdirectory of your domain you will need to put the
+// relative path (from the root of your domain) here.
+// For instance if your URL is 'http://example.com/directory/subdirectory',
+// set $a->path to 'directory/subdirectory'. 
+
+$a->path = '$urlpath';
+// Choose a legal default timezone. If you are unsure, use "America/Los_Angeles".
+// It can be changed later and only applies to timestamps for anonymous viewers.
+
+$default_timezone = '$timezone';
+
+// What is your site name?
+
+$a->config['sitename'] = "My Friend Network";
+
+// Your choices are REGISTER_OPEN, REGISTER_APPROVE, or REGISTER_CLOSED.
+// Be certain to create your own personal account before setting 
+// REGISTER_CLOSED. 'register_text' (if set) will be displayed prominently on 
+// the registration page. REGISTER_APPROVE requires you set 'admin_email'
+// to the email address of an already registered person who can authorise
+// and/or approve/deny the request.
+
+$a->config['register_policy'] = REGISTER_OPEN;
+$a->config['register_text'] = '';
+$a->config['admin_email'] = '';
+
+// Maximum size of an imported message, 0 is unlimited
+
+$a->config['max_import_size'] = 10000;
+
+// maximum size of uploaded photos
+
+$a->config['system']['maximagesize'] = 800000;
+
+// Location of PHP command line processor
+
+$a->config['php_path'] = '$phpath';
+
+// Location of global directory submission page.
+
+$a->config['system']['directory_submit_url'] = 'http://dir.friendika.com/submit';
+$a->config['system']['directory_search_url'] = 'http://dir.friendika.com/directory?search=';
+
+// PuSH - aka pubsubhubbub URL. This makes delivery of public posts as fast as private posts
+
+$a->config['system']['huburl'] = 'http://pubsubhubbub.appspot.com';
+
+// Server-to-server private message encryption (RINO) is allowed by default. 
+// Encryption will only be provided if this setting is true and the
+// PHP mcrypt extension is installed on both systems 
+
+$a->config['system']['rino_encrypt'] = true;
+
diff --git a/view/de/insecure_net.tpl b/view/de/insecure_net.tpl
new file mode 100644 (file)
index 0000000..900f286
--- /dev/null
@@ -0,0 +1,8 @@
+<div id="profile-edit-insecure">
+<p>
+Das Soziale Netzwerk dem $name angehört ist ein offenes Netzwerk das nur
+eingeschränkte oder nicht existente Privatspäreneinstellungen bietet.
+
+Bitte verhalte dich entsprechend diskret.
+</p>
+</div>
diff --git a/view/de/install_db.tpl b/view/de/install_db.tpl
new file mode 100644 (file)
index 0000000..804ce17
--- /dev/null
@@ -0,0 +1,40 @@
+
+<h3>Friendika Social Network</h3>
+<h3>Installation</h3>
+
+<p>
+Um Friendika installieren zu können müssen wir wissen wie wir die Datenbank erreichen könne. Bitte kontaktire deinen Hosting Anbieter oder Seitenadministrator wenn du Fragen zu diesen Einstellungen hast. Die Datenbank die du weiter unten angibst muss bereits existieren. Sollte dies nicht der Fall sein erzeuge sie bitte bevor du mit der Installation fortfährst.
+</p>
+
+<form id="install-form" action="$baseurl/install" method="post">
+
+<input type="hidden" name="phpath" value="$phpath" />
+
+<label for="install-dbhost" id="install-dbhost-label">Datenbank Servername</label>
+<input type="text" name="dbhost" id="install-dbhost" value="$dbhost" />
+<div id="install-dbhost-end"></div>
+
+<label for="install-dbuser" id="install-dbuser-label">Datenbank Anmeldename</label>
+<input type="text" name="dbuser" id="install-dbuser" value="$dbuser" />
+<div id="install-dbuser-end"></div>
+
+<label for="install-dbpass" id="install-dbpass-label">Datenbank Anmeldepassword</label>
+<input type="password" name="dbpass" id="install-dbpass" value="$dbpass" />
+<div id="install-dbpass-end"></div>
+
+<label for="install-dbdata" id="install-dbdata-label">Datenbankname</label>
+<input type="text" name="dbdata" id="install-dbdata"  value="$dbdata" />
+<div id="install-dbdata-end"></div>
+
+<div id="install-tz-desc">
+Bitte wähle die Standard-Zeitzone deiner Webseite
+</div>
+
+$tzselect
+
+<div id="install-tz-end" ></div>
+<input id="install-submit" type="submit" name="submit" value="$submit" /> 
+
+</form>
+<div id="install-end" ></div>
+
diff --git a/view/de/intro_complete_eml.tpl b/view/de/intro_complete_eml.tpl
new file mode 100644 (file)
index 0000000..46ffc87
--- /dev/null
@@ -0,0 +1,18 @@
+
+Lieber $username,
+
+'$fn' von '$dfrn_url' hat deine Kontaktanfrage auf '$sitename' bestätigt.
+
+'$fn' hat sich dazu entschlossen dich als "Fan" mit eingeschränkten
+Kommunikationsmöglichkeiten zu akzeptieren. Dies umfasst private Nachrichten
+und einige Profilaktivitäten. Sollte dies eine Prominenten oder
+Gemeinschaftsseite sein, wurden diese Einstellungen automatisch vorgenommen.
+
+'$fn' kann sich in Zukunft dazu entschließen eure Beziehung in eine beidseitige
+Freundschaft oder freizügigere Beziehung zu erweitern.
+
+Ab sofort wirst du Statusmitteilungen von '$fn' erhalten, die auf deiner
+'Netzwerkseite' erscheinen werden.
+
+Mit freundlichen Grüßen,
+        $sitename Administrator
diff --git a/view/de/intros-top.tpl b/view/de/intros-top.tpl
new file mode 100644 (file)
index 0000000..e65da1a
--- /dev/null
@@ -0,0 +1,7 @@
+<h1>Schwebende Freundschafts/Kontakt Benachrichtigungen</h1>
+
+<div id="notification-show-hide-wrapper" >
+<a href="$hide_url" id="notification-show-hide-link">$hide_text</a>
+</div>
+
+
diff --git a/view/de/jot-header.tpl b/view/de/jot-header.tpl
new file mode 100644 (file)
index 0000000..41abdf0
--- /dev/null
@@ -0,0 +1,140 @@
+
+<script language="javascript" type="text/javascript" src="$baseurl/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
+<script language="javascript" type="text/javascript">
+
+var editor;
+
+tinyMCE.init({
+       theme : "advanced",
+       mode : "specific_textareas",
+       editor_selector: /(profile-jot-text|prvmail-text)/,
+       plugins : "bbcode,paste",
+       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
+       theme_advanced_buttons2 : "",
+       theme_advanced_buttons3 : "",
+       theme_advanced_toolbar_location : "top",
+       theme_advanced_toolbar_align : "center",
+       theme_advanced_blockformats : "blockquote,code",
+       paste_text_sticky : true,
+       entity_encoding : "raw",
+       add_unload_trigger : false,
+       remove_linebreaks : false,
+       force_p_newlines : false,
+       force_br_newlines : true,
+       forced_root_block : '',
+       convert_urls: false,
+       content_css: "$baseurl/view/custom_tinymce.css",
+            //Character count
+       theme_advanced_path : false,
+       setup : function(ed) {
+               ed.onKeyUp.add(function(ed, e) {
+                       var txt = tinyMCE.activeEditor.getContent();
+                       var text = txt.length;
+                       if(txt.length <= 140) {
+                               $('#character-counter').removeClass('red');
+                               $('#character-counter').removeClass('orange');
+                               $('#character-counter').addClass('grey');
+                       }
+                       if((txt.length > 140) && (txt .length <= 420)) {
+                               $('#character-counter').removeClass('grey');
+                               $('#character-counter').removeClass('red');
+                               $('#character-counter').addClass('orange');
+                       }
+                       if(txt.length > 420) {
+                               $('#character-counter').removeClass('grey');
+                               $('#character-counter').removeClass('orange');
+                               $('#character-counter').addClass('red');
+                       }
+                       $('#character-counter').text(text);
+       });
+
+               ed.onInit.add(function(ed) {
+                       ed.pasteAsPlainText = true;
+               });
+
+       }
+});
+
+</script>
+<script type="text/javascript" src="include/ajaxupload.js" ></script>
+<script>
+       $(document).ready(function() {
+               var uploader = new window.AjaxUpload(
+                       'wall-image-upload',
+                       { action: 'wall_upload/$nickname',
+                               name: 'userfile',
+                               onSubmit: function(file,ext) { $('#profile-rotator').show(); },
+                               onComplete: function(file,response) {
+                                       tinyMCE.execCommand('mceInsertRawHTML',false,response);
+                                       $('#profile-rotator').hide();
+                               }                                
+                       }
+               );
+               $('#contact_allow, #contact_deny, #group_allow, #group_deny').change(function() {
+                       var selstr;
+                       $('#contact_allow option:selected, #contact_deny option:selected, #group_allow option:selected, #group_deny option:selected').each( function() {
+                               selstr = $(this).text();
+                               $('#profile-jot-perms img').attr('src', 'images/lock_icon.gif');
+
+                       });
+                       if(selstr == null)
+                               $('#profile-jot-perms img').attr('src', 'images/unlock_icon.gif');
+
+               }).trigger('change');
+
+       });
+
+       function jotGetLink() {
+               reply = prompt("Bitte URL des Links angeben:");
+               if(reply && reply.length) {
+                       $('#profile-rotator').show();
+                       $.get('parse_url?url=' + reply, function(data) {
+                               tinyMCE.execCommand('mceInsertRawHTML',false,data);
+                               $('#profile-rotator').hide();
+                       });
+               }
+       }
+
+       function jotGetVideo() {
+               reply = prompt("Bitte den YouTube Link angeben:");
+               if(reply && reply.length) {
+                       tinyMCE.execCommand('mceInsertRawHTML',false,'[youtube]' + reply + '[/youtube]');
+               }
+       }
+
+       function jotGetLocation() {
+               reply = prompt("Wo bist du im Moment?", $('#jot-location').val());
+               if(reply && reply.length) {
+                       $('#jot-location').val(reply);
+               }
+       }
+
+
+       function linkdropper(event) {
+               var linkFound = event.dataTransfer.types.contains("text/uri-list");
+               if(linkFound)
+                       event.preventDefault();
+       }
+
+       function linkdrop(event) {
+               var reply = event.dataTransfer.getData("text/uri-list");
+               event.target.textContent = reply;
+               event.preventDefault();
+               if(reply && reply.length) {
+                       $('#profile-rotator').show();
+                       $.get('parse_url?url=' + reply, function(data) {
+                               tinyMCE.execCommand('mceInsertRawHTML',false,data);
+                               $('#profile-rotator').hide();
+                       });
+               }
+       }
+
+       function jotClearLocation() {
+               $('#jot-coord').val('');
+               $('#profile-nolocation-wrapper').hide();
+       }
+
+       $geotag
+
+</script>
+
diff --git a/view/de/jot.tpl b/view/de/jot.tpl
new file mode 100644 (file)
index 0000000..545bbda
--- /dev/null
@@ -0,0 +1,56 @@
+
+<div id="profile-jot-wrapper" >
+       <div id="profile-jot-banner-wrapper">
+               <div id="profile-jot-desc" >&nbsp;</div>
+               <div id="character-counter" class="grey"></div>
+       </div>
+       <div id="profile-jot-banner-end"></div>
+
+       <form id="profile-jot-form" action="item" method="post" >
+               <input type="hidden" name="type" value="wall" />
+               <input type="hidden" name="profile_uid" value="$profile_uid" />
+               <input type="hidden" name="return" value="$return_path" />
+               <input type="hidden" name="location" id="jot-location" value="$defloc" />
+               <input type="hidden" name="coord" id="jot-coord" value="" />
+
+
+               <textarea rows="5" cols="64" class="profile-jot-text" id="profile-jot-text" name="body" ></textarea>
+
+<div id="profile-jot-submit-wrapper" >
+<input type="submit" id="profile-jot-submit" name="submit" value="Share" />
+       <div id="profile-upload-wrapper" style="display: $visitor;" >
+               <div id="wall-image-upload-div" ><img id="wall-image-upload" src="images/camera-icon.gif" alt="Foto hochladen" title="Foto hochladen"  /></div>
+       </div> 
+       <div id="profile-link-wrapper" style="display: $visitor;" ondragenter="linkdropper(event);" ondragover="linkdropper(event);" ondrop="linkdrop(event);" >
+               <img id="profile-link" src="images/link-icon.gif" alt="Weblink einfügen" title="Weblink einfügen" ondragenter="return linkdropper(event);" ondragover="return linkdropper(event);" ondrop="linkdrop(event);" onclick="jotGetLink();" />
+       </div> 
+       <div id="profile-youtube-wrapper" style="display: $visitor;" >
+               <img id="profile-video" src="images/youtube_icon.gif" alt="YouTube Video einfügen" title="YouTube Video einfügen" onclick="jotGetVideo();" />
+       </div> 
+       <div id="profile-location-wrapper" style="display: $visitor;" >
+               <img id="profile-location" src="images/globe.gif" alt="Deinen Standort festlegen" title="Deinen Standort festlegen" onclick="jotGetLocation();" />
+       </div> 
+       <div id="profile-nolocation-wrapper" style="display: none;" >
+               <img id="profile-nolocation" src="images/noglobe.gif" alt="Browser Standort leeren" title="Browser Standort leeren" onclick="jotClearLocation();" />
+       </div> 
+
+       <div id="profile-jot-plugin-wrapper" >
+       $jotplugins
+       </div>
+
+
+       <div id="profile-rotator-wrapper" style="display: $visitor;" >
+               <img id="profile-rotator" src="images/rotator.gif" alt="Bitte warten" title="Bitte warten" style="display: none;" />
+       </div> 
+       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Berechtigungseinstellungen" title="Berechtigungseinstellungen" onClick="openClose('profile-jot-acl-wrapper'); openClose('profile-jot-email-wrapper');" />$bang</div>
+       <div id="profile-jot-perms-end"></div>
+       <div id="profile-jot-email-wrapper" style="display: none;" >
+       <div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle">
+       <div id="profile-jot-email-end"></div>
+       </div>
+       <div id="profile-jot-acl-wrapper" style="display: none;" >$acl</div>
+</div>
+
+<div id="profile-jot-end"></div>
+</form>
+</div>
diff --git a/view/de/like.tpl b/view/de/like.tpl
new file mode 100644 (file)
index 0000000..2f77885
--- /dev/null
@@ -0,0 +1,5 @@
+<div class="wall-item-like-buttons" id="wall-item-like-buttons-$id">
+                               <img src="images/like.gif" alt="Ich mag das" title="Ich mag das [toggle]" onclick="dolike($id,'like');" />
+                               <img src="images/dislike.gif" alt="Ich mag das nicht" title="Ich mag das nicht [toggle]" onclick="dolike($id,'dislike');" />
+                               <img id="like-rotator-$id" class="like-rotator" src="images/rotator.gif" alt="Bitte warten" title="Bitte warten" style="display: none;" />
+                       </div>
diff --git a/view/de/logout.tpl b/view/de/logout.tpl
new file mode 100644 (file)
index 0000000..9a6c1d7
--- /dev/null
@@ -0,0 +1,6 @@
+<form action="" method="post" >
+<div class="logout-wrapper">
+<input type="hidden" name="auth-params" value="logout" />
+<input type="submit" name="submit" id="logout-button" value="Logout" />
+</div>
+</form>
diff --git a/view/de/lostpass.tpl b/view/de/lostpass.tpl
new file mode 100644 (file)
index 0000000..1a75447
--- /dev/null
@@ -0,0 +1,18 @@
+<h3>Passwort vergessen?</h3>
+
+<p id="lostpass-desc">
+Trage deine EMail Adresse ein um ein neues Passwort anzufordern. Du wirst eine EMail mit weiteren Anweisungen erhalten.
+</p>
+
+<form action="lostpass" method="post" >
+<div id="login-name-wrapper">
+        <label for="login-name" id="label-login-name">Spitzname oder EMail: </label>
+        <input type="text" maxlength="60" name="login-name" id="login-name" value="" />
+</div>
+<div id="login-extra-end"></div>
+<div id="login-submit-wrapper" >
+        <input type="submit" name="submit" id="lostpass-submit-button" value="Reset" />
+</div>
+<div id="login-submit-end"></div>
+</form>
+
diff --git a/view/de/lostpass_eml.tpl b/view/de/lostpass_eml.tpl
new file mode 100644 (file)
index 0000000..91b9b4c
--- /dev/null
@@ -0,0 +1,32 @@
+
+Lieber $username,
+wir haben gerade eine Anfrage erhalten dein Passwort auf $sitename zu ändern.
+Um diese Anfrage zu bestätigen folge bitte dem Bestätigungslink oder kopiere
+ihn in die Adresszeile deines Browsers.
+
+Solltest du KEINE Änderungsanfrage gestellt haben ignoriere diese EMail einfach
+und folge dem angegebenen Link UNTER KEINEN UMSTÄNDEN.
+
+Dein Passwort wird nicht geändert wenn du die Anfrage nicht bestätigst.
+
+Folge diesem Link zur Verifizierung der Anfrage:
+
+$reset_link
+
+Anschließend wirst du eine EMail erhalten die dein neues Passwort enthält.
+
+Du kannst dein Passwort jederzeit in den Einstellungen deines Accounts ändern
+nachdem du angemeldet bist.
+
+Die Anmelde Daten sind die Folgenden:
+
+Adresse der Seite:     $siteurl
+Anmelde Name:  $email
+
+
+
+
+Mit freundlichen Grüßen,
+       $sitename Administrator
+
diff --git a/view/de/mail_received_eml.tpl b/view/de/mail_received_eml.tpl
new file mode 100644 (file)
index 0000000..466d31e
--- /dev/null
@@ -0,0 +1,17 @@
+
+Lieber $username,
+
+du hast eine neue private Nachricht von '$from' auf '$sitename' erhhalten.
+-----
+$title
+-----
+$body
+-----
+Bitte melde dich unter $siteurl an um deine privaten Nachrichte zu lesen und zu
+beantworten.
+
+Viele Grüße,
+    $sitename Administrator
+
+
diff --git a/view/de/msg-header.tpl b/view/de/msg-header.tpl
new file mode 100644 (file)
index 0000000..3d2567f
--- /dev/null
@@ -0,0 +1,100 @@
+
+<script language="javascript" type="text/javascript" src="$baseurl/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
+<script language="javascript" type="text/javascript">
+
+tinyMCE.init({
+       theme : "advanced",
+       mode : "specific_textareas",
+       editor_selector: /(profile-jot-text|prvmail-text)/,
+       plugins : "bbcode",
+       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor",
+       theme_advanced_buttons2 : "",
+       theme_advanced_buttons3 : "",
+       theme_advanced_toolbar_location : "top",
+       theme_advanced_toolbar_align : "center",
+       theme_advanced_styles : "Code=codeStyle;Quote=quoteStyle",
+       content_css : "bbcode.css",
+       entity_encoding : "raw",
+       add_unload_trigger : false,
+       remove_linebreaks : false,
+       force_p_newlines : false,
+       force_br_newlines : true,
+       forced_root_block : '',
+       convert_urls: false,
+       content_css: "$baseurl/view/custom_tinymce.css",
+            //Character count
+       theme_advanced_path : false,
+       setup : function(ed) {
+               ed.onKeyUp.add(function(ed, e) {
+                       var txt = tinyMCE.activeEditor.getContent();
+                       var text = txt.length;
+                       if(txt.length <= 140) {
+                               $('#character-counter').removeClass('red');
+                               $('#character-counter').removeClass('orange');
+                               $('#character-counter').addClass('grey');
+                       }
+                       if((txt.length > 140) && (txt .length <= 420)) {
+                               $('#character-counter').removeClass('grey');
+                               $('#character-counter').removeClass('red');
+                               $('#character-counter').addClass('orange');
+                       }
+                       if(txt.length > 420) {
+                               $('#character-counter').removeClass('grey');
+                               $('#character-counter').removeClass('orange');
+                               $('#character-counter').addClass('red');
+                       }
+                       $('#character-counter').text(text);
+               });
+       }
+});
+
+</script>
+<script type="text/javascript" src="include/ajaxupload.js" ></script>
+<script>
+       $(document).ready(function() {
+               var uploader = new window.AjaxUpload(
+                       'prvmail-upload',
+                       { action: 'wall_upload/$nickname',
+                               name: 'userfile',
+                               onSubmit: function(file,ext) { $('#profile-rotator').show(); },
+                               onComplete: function(file,response) {
+                                       tinyMCE.execCommand('mceInsertRawHTML',false,response);
+                                       $('#profile-rotator').hide();
+                               }                                
+                       }
+               );
+
+       });
+
+       function jotGetLink() {
+               reply = prompt("Please enter a link URL:");
+               if(reply && reply.length) {
+                       $('#profile-rotator').show();
+                       $.get('parse_url?url=' + reply, function(data) {
+                               tinyMCE.execCommand('mceInsertRawHTML',false,data);
+                               $('#profile-rotator').hide();
+                       });
+               }
+       }
+
+       function linkdropper(event) {
+               var linkFound = event.dataTransfer.types.contains("text/uri-list");
+               if(linkFound)
+                       event.preventDefault();
+       }
+
+       function linkdrop(event) {
+               var reply = event.dataTransfer.getData("text/uri-list");
+               event.target.textContent = reply;
+               event.preventDefault();
+               if(reply && reply.length) {
+                       $('#profile-rotator').show();
+                       $.get('parse_url?url=' + reply, function(data) {
+                               tinyMCE.execCommand('mceInsertRawHTML',false,data);
+                               $('#profile-rotator').hide();
+                       });
+               }
+       }
+
+</script>
+
diff --git a/view/de/netfriend.tpl b/view/de/netfriend.tpl
new file mode 100644 (file)
index 0000000..79a7a09
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="intro-approve-as-friend-desc">Genehmigen als: </div>
+
+<div class="intro-approve-as-friend-wrapper">
+       <label class="intro-approve-as-friend-label" for="intro-approve-as-friend-$intro_id">Freund</label>
+       <input type="radio" name="duplex" id="intro-approve-as-friend-$intro_id" class="intro-approve-as-friend" $friend_selected value="1" />
+       <div class="intro-approve-friend-break" ></div> 
+</div>
+<div class="intro-approve-as-friend-end"></div>
+<div class="intro-approve-as-fan-wrapper">
+       <label class="intro-approve-as-fan-label" for="intro-approve-as-fan-$intro_id">Fan/Verehrer</label>
+       <input type="radio" name="duplex" id="intro-approve-as-fan-$intro_id" class="intro-approve-as-fan" $fan_selected value="0"  />
+       <div class="intro-approve-fan-break"></div>
+</div>
+<div class="intro-approve-as-end"></div>
diff --git a/view/de/pagetypes.tpl b/view/de/pagetypes.tpl
new file mode 100644 (file)
index 0000000..56be7c2
--- /dev/null
@@ -0,0 +1,25 @@
+
+               <div id="settings-normal-wrapper">
+                       <label id="settings-normal-label" for="settings-normal">Normales Profil</label>
+                       <input type="radio" name="page-flags" id="settings-normal" $normal_selected value="$page_normal" />
+                       <span id="settings-normal-desc">Dieser Account ist ein normaler persönlicher Account</span>
+               </div>
+               <div id="settings-normal-break" ></div> 
+               <div id="settings-soapbox-wrapper">
+                       <label id="settings-soapbox-label" for="settings-soapbox">Sandkasten Profil</label>
+                       <input type="radio" name="page-flags" id="settings-soapbox" $soapbox_selected value="$page_soapbox" />
+                       <span id="settings-soapbox-desc">Alle Kontakt/Freundschaftsanfragen werden automatisch als Nur-Lese Fans akzepdiert</span>
+               </div>
+               <div id="settings-soapbox-break" ></div>        
+               <div id="settings-community-wrapper">
+                       <label id="settings-community-label" for="settings-community">Gemeindschafts/Prominenten Profil</label>
+                       <input type="radio" name="page-flags" id="settings-community" $community_selected value="$page_community" />
+                       <span id="settings-community-desc">Alle Kontakt/Freundschaftsanfragen werden automatisch als Lese-und-Schreiben Fans akzepdiert</span>
+               </div>
+               <div id="settings-community-break" ></div>      
+               <div id="settings-freelove-wrapper">
+                       <label id="settings-freelove-label" for="settings-freelove">Automatisches Freundschafts-Profil</label>
+                       <input type="radio" name="page-flags" id="settings-freelove" $freelove_selected value="$page_freelove" />
+                       <span id="settings-freelove-desc">Alle Kontakt/Freundschaftsanfragen werden automatisch als Freund akzepdiert</span>
+               </div>
+                       <div id="settings-freelove-break" ></div>       
diff --git a/view/de/passchanged_eml.tpl b/view/de/passchanged_eml.tpl
new file mode 100644 (file)
index 0000000..894fd4e
--- /dev/null
@@ -0,0 +1,20 @@
+
+Lieber $username,
+dein Passwort wurde wie gewünscht geändert. Bitte hebe diese Informationen
+für deine Unterlagen auf (oder ändere das Passwort augenblicklich in etwas
+das du dir merken kannst).
+
+
+Deine Anmeldedaten sind die Folgenden:
+
+Adresse der Seite:     $siteurl
+Anmelde Name:  $email
+Passwort:      $new_password
+
+Du kannst diesen Passwort auf der "Einstellungen" Seite deines Accounts
+ändern nachdem du angemeldet bits.
+
+
+Viele Grüße,
+       $sitename Administrator
+
diff --git a/view/de/profile-hide-friends.tpl b/view/de/profile-hide-friends.tpl
new file mode 100644 (file)
index 0000000..1d69038
--- /dev/null
@@ -0,0 +1,16 @@
+<p id="hide-friends-text">
+Verberge meine Kontaktliste von Leuten die dieses Profil ansehen?
+</p>
+
+               <div id="hide-friends-yes-wrapper">
+               <label id="hide-friends-yes-label" for="hide-friends-yes">Ja</label>
+               <input type="radio" name="hide-friends" id="hide-friends-yes" $yes_selected value="1" />
+
+               <div id="hide-friends-break" ></div>    
+               </div>
+               <div id="hide-friends-no-wrapper">
+               <label id="hide-friends-no-label" for="hide-friends-no">Nein</label>
+               <input type="radio" name="hide-friends" id="hide-friends-no" $no_selected value="0"  />
+
+               <div id="hide-friends-end"></div>
+               </div>
diff --git a/view/de/profile-in-directory.tpl b/view/de/profile-in-directory.tpl
new file mode 100644 (file)
index 0000000..9cc62fc
--- /dev/null
@@ -0,0 +1,16 @@
+<p id="profile-in-directory">
+Soll dein Standard-Profil im Verzeichnis dieser Seite veröffentlich werden?
+</p>
+
+               <div id="profile-in-dir-yes-wrapper">
+               <label id="profile-in-dir-yes-label" for="profile-in-dir-yes">Ja</label>
+               <input type="radio" name="profile_in_directory" id="profile-in-dir-yes" $yes_selected value="1" />
+
+               <div id="profile-in-dir-break" ></div>  
+               </div>
+               <div id="profile-in-dir-no-wrapper">
+               <label id="profile-in-dir-no-label" for="profile-in-dir-no">Nein</label>
+               <input type="radio" name="profile_in_directory" id="profile-in-dir-no" $no_selected value="0"  />
+
+               <div id="profile-in-dir-end"></div>
+               </div>
diff --git a/view/de/profile-in-netdir.tpl b/view/de/profile-in-netdir.tpl
new file mode 100644 (file)
index 0000000..26f45ac
--- /dev/null
@@ -0,0 +1,16 @@
+<p id="profile-in-directory">
+Soll dein Standard-Profil im globalen Verzeichnis veröffentlicht werden?
+</p>
+
+               <div id="profile-in-netdir-yes-wrapper">
+               <label id="profile-in-netdir-yes-label" for="profile-in-netdir-yes">Ja</label>
+               <input type="radio" name="profile_in_netdirectory" id="profile-in-netdir-yes" $yes_selected value="1" />
+
+               <div id="profile-in-netdir-break" ></div>       
+               </div>
+               <div id="profile-in-netdir-no-wrapper">
+               <label id="profile-in-netdir-no-label" for="profile-in-netdir-no">Nein</label>
+               <input type="radio" name="profile_in_netdirectory" id="profile-in-netdir-no" $no_selected value="0"  />
+
+               <div id="profile-in-netdir-end"></div>
+               </div>
diff --git a/view/de/profile.php b/view/de/profile.php
new file mode 100644 (file)
index 0000000..40b6abd
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html ><?php // This is a perfect example of why I prefer to use template files rather than mixed PHP/HTML ?>\r
+<html>\r
+<head>\r
+  <title><?php if(x($page,'title')) echo $page['title']; ?></title>\r
+  <?php if(x($page,'htmlhead')) echo $page['htmlhead']; ?>\r
+</head>\r
+<body>\r
+<header><?php if(x($page,'header')) echo $page['header']; ?></header>\r
+<nav><div id="top-margin"></div><?php if(x($page,'nav')) echo $page['nav']; ?></nav>\r
+<aside>\r
+<?php if((is_array($profile)) && count($profile)) { ?>\r
+<div class="vcard">\r
+       <?php if(strlen($profile['name'])) { ?>\r
+               <div class="fn"><?php echo $profile['name']; ?></div>\r
+       <?php } ?>\r
+\r
+       <?php if(strlen($profile['photo'])) { ?>\r
+               <div id="profile-photo-wrapper"><img class="photo" src="<?php echo $profile['photo']; ?>" alt="<?php echo $profile['name']; ?>" /></div>\r
+       <?php } ?>\r
+\r
+       <div id="profile-extra-links">\r
+       <ul>\r
+       <?php if($profile['uid'] != $_SESSION['uid']) { ?>\r
+       <li><a id="dfrn-request-link" href="dfrn_request/<?php echo $profile['nickname']; ?>">In Verbindung treten</a></li>\r
+       <?php } ?>\r
+       </ul>\r
+\r
+       </div>\r
+\r
+       <?php if ( (strlen($profile['address'])) \r
+               || (strlen($profile['locality']))\r
+               || (strlen($profile['region'])) \r
+               || (strlen($profile['postal-code'])) \r
+               || (strlen($profile['country-name']))) { ?>\r
+               <div class="location">Standort:\r
+                       <div class="adr">\r
+                               <div class="street-address"><?php if(strlen($profile['address'])) echo $profile['address']; ?></div>\r
+                               <span class="city-state-zip"><span class="locality"><?php echo $profile['locality']; ?></span><?php if(strlen($profile['locality'])) echo ', '; ?><span class="region"><?php echo $profile['region'] ?></span><?php if(strlen($profile['postal-code'])) { ?> <span class="postal-code"><?php echo $profile['postal-code']; ?></span><?php } ?></span>\r
+                               <span class="country-name"><?php echo $profile['country-name']; ?></span>\r
+                       </div>\r
+               </div>\r
+\r
+       <?php } ?>\r
+\r
+       <?php if(strlen($profile['gender'])) { ?>\r
+               <div class="mf">Geschlecht: <span class="x-gender"><?php echo $profile['gender']; ?></span></div>\r
+\r
+       <?php } ?>\r
+\r
+       <?php if(strlen($profile['pubkey'])) { ?>\r
+               <div class="key" style="display: none;"><?php echo $profile['pubkey']; ?></div>\r
+       <?php } ?>\r
+</div>\r
+<?php } ?>\r
+<?php if(strlen($profile['marital'])) { ?>\r
+<div class="marital"><span class="marital-label"><span class="heart">&hearts;</span> Status: </span><span class="marital-text"><?php echo $profile['marital']; ?></span></div>\r
+<?php } ?>\r
+<?php if(strlen($profile['homepage'])) { ?>\r
+<div class="homepage"><span class="homepage-label">Homepage: </span><span class="homepage-url"><?php echo linkify($profile['homepage']); ?></span></div>\r
+<?php } ?>\r
+<?php if(x($page,'aside')) echo $page['aside'] ?>\r
+</aside>\r
+<section>\r
+<?php if(x($page,'content')) echo $page['content']; ?>\r
+<div id="page-footer"></div>\r
+</section>\r
+<footer>\r
+<?php if(x($page,'footer')) echo $page['footer']; ?>\r
+</footer>\r
+</body>\r
+</html>\r
+\r
diff --git a/view/de/profile_advanced.php b/view/de/profile_advanced.php
new file mode 100644 (file)
index 0000000..d2b9d06
--- /dev/null
@@ -0,0 +1,226 @@
+<?php
+
+$o .= '';
+
+$o .= <<< EOT
+
+<h2>Profile</h2>
+
+
+EOT;
+
+if($a->profile['name']) {
+$o .= <<< EOT
+<div id="advanced-profile-name-wrapper" >
+<div id="advanced-profile-name-text">Full Name:</div>
+<div id="advanced-profile-name">{$a->profile['name']}</div>
+</div>
+<div id="advanced-profile-name-end"></div>
+EOT;
+}
+
+if($a->profile['gender']) {
+$o .= <<< EOT
+<div id="advanced-profile-gender-wrapper" >
+<div id="advanced-profile-gender-text">Gender:</div>
+<div id="advanced-profile-gender">{$a->profile['gender']}</div>
+</div>
+<div id="advanced-profile-gender-end"></div>
+EOT;
+}
+
+if(($a->profile['dob']) && ($a->profile['dob'] != '0000-00-00')) {
+$o .= <<< EOT
+<div id="advanced-profile-dob-wrapper" >
+<div id="advanced-profile-dob-text">Birthday:</div>
+EOT;
+
+// If no year, add an arbitrary one so just we can parse the month and day.
+
+$o .= '<div id="advanced-profile-dob">' 
+       . ((intval($a->profile['dob'])) 
+               ? day_translate(datetime_convert('UTC','UTC',$a->profile['dob'] . ' 00:00 +00:00','j F, Y'))
+               : day_translate(datetime_convert('UTC','UTC','2001-' . substr($a->profile['dob'],6) . ' 00:00 +00:00','j F'))) 
+       . "</div>\r\n</div>";
+
+$o .= '<div id="advanced-profile-dob-end"></div>';
+
+}
+
+if($age = age($a->profile['dob'],$a->profile['timezone'],'')) {
+$o .= <<< EOT
+<div id="advanced-profile-age-wrapper" >
+<div id="advanced-profile-age-text">Age:</div>
+<div id="advanced-profile-age">$age</div>
+</div>
+<div id="advanced-profile-age-end"></div>
+EOT;
+}
+
+if($a->profile['marital']) {
+$o .= <<< EOT
+<div id="advanced-profile-marital-wrapper" >
+<div id="advanced-profile-marital-text"><span class="heart">&hearts;</span> Status:</div>
+<div id="advanced-profile-marital">{$a->profile['marital']}</div>
+EOT;
+
+if($a->profile['with'])
+       $o .= "<div id=\"advanced-profile-with\">({$a->profile['with']})</div>";
+$o .= <<< EOT
+</div>
+<div id="advanced-profile-marital-end"></div>
+EOT;
+}
+
+if($a->profile['sexual']) {
+$o .= <<< EOT
+<div id="advanced-profile-sexual-wrapper" >
+<div id="advanced-profile-sexual-text">Sexual Preference:</div>
+<div id="advanced-profile-sexual">{$a->profile['sexual']}</div>
+</div>
+<div id="advanced-profile-sexual-end"></div>
+EOT;
+}
+
+if($a->profile['homepage']) {
+       $homepage = linkify($a->profile['homepage']);
+$o .= <<< EOT
+<div id="advanced-profile-homepage-wrapper" >
+<div id="advanced-profile-homepage-text">Homepage:</div>
+<div id="advanced-profile-homepage">$homepage</div>
+</div>
+<div id="advanced-profile-homepage-end"></div>
+EOT;
+}
+
+if($a->profile['politic']) {
+$o .= <<< EOT
+<div id="advanced-profile-politic-wrapper" >
+<div id="advanced-profile-politic-text">Political Views:</div>
+<div id="advanced-profile-politic">{$a->profile['politic']}</div>
+</div>
+<div id="advanced-profile-politic-end"></div>
+EOT;
+}
+
+if($a->profile['religion']) {
+$o .= <<< EOT
+<div id="advanced-profile-religion-wrapper" >
+<div id="advanced-profile-religion-text">Religion:</div>
+<div id="advanced-profile-religion">{$a->profile['religion']}</div>
+</div>
+<div id="advanced-profile-religion-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['about'])) {
+$o .= <<< EOT
+<div id="advanced-profile-about-wrapper" >
+<div id="advanced-profile-about-text">About:</div>
+<br />
+<div id="advanced-profile-about">$txt</div>
+</div>
+<div id="advanced-profile-about-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['interest'])) {
+$o .= <<< EOT
+<div id="advanced-profile-interest-wrapper" >
+<div id="advanced-profile-interest-text">Hobbies/Interests:</div>
+<br />
+<div id="advanced-profile-interest">$txt</div>
+</div>
+<div id="advanced-profile-interest-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['contact'])) {
+$o .= <<< EOT
+<div id="advanced-profile-contact-wrapper" >
+<div id="advanced-profile-contact-text">Contact information and Social Networks:</div>
+<br />
+<div id="advanced-profile-contact">$txt</div>
+</div>
+<div id="advanced-profile-contact-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['music'])) {
+$o .= <<< EOT
+<div id="advanced-profile-music-wrapper" >
+<div id="advanced-profile-music-text">Musical interests:</div>
+<br />
+<div id="advanced-profile-music">$txt</div>
+</div>
+<div id="advanced-profile-music-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['book'])) {
+$o .= <<< EOT
+<div id="advanced-profile-book-wrapper" >
+<div id="advanced-profile-book-text">Books, literature:</div>
+<br />
+<div id="advanced-profile-book">$txt</div>
+</div>
+<div id="advanced-profile-book-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['tv'])) {
+$o .= <<< EOT
+<div id="advanced-profile-tv-wrapper" >
+<div id="advanced-profile-tv-text">Television:</div>
+<br />
+<div id="advanced-profile-tv">$txt</div>
+</div>
+<div id="advanced-profile-tv-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['film'])) {
+$o .= <<< EOT
+<div id="advanced-profile-film-wrapper" >
+<div id="advanced-profile-film-text">Film/dance/culture/entertainment:</div>
+<br />
+<div id="advanced-profile-film">$txt</div>
+</div>
+<div id="advanced-profile-film-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['romance'])) {
+$o .= <<< EOT
+<div id="advanced-profile-romance-wrapper" >
+<div id="advanced-profile-romance-text">Love/romance:</div>
+<br />
+<div id="advanced-profile-romance">$txt</div>
+</div>
+<div id="advanced-profile-romance-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['work'])) {
+$o .= <<< EOT
+<div id="advanced-profile-work-wrapper" >
+<div id="advanced-profile-work-text">Work/employment:</div>
+<br />
+<div id="advanced-profile-work">$txt</div>
+</div>
+<div id="advanced-profile-work-end"></div>
+EOT;
+}
+
+if($txt = bbcode($a->profile['education'])) {
+$o .= <<< EOT
+<div id="advanced-profile-education-wrapper" >
+<div id="advanced-profile-education-text">School/education:</div>
+<br />
+<div id="advanced-profile-education">$txt</div>
+</div>
+<div id="advanced-profile-education-end"></div>
+EOT;
+}
+
+
diff --git a/view/de/profile_edit.tpl b/view/de/profile_edit.tpl
new file mode 100644 (file)
index 0000000..09a7610
--- /dev/null
@@ -0,0 +1,293 @@
+<h1>Proil Details Bearbeiten</h1>
+
+<div id="profile-edit-links">
+<ul>
+<li><a href="profile/$profile_id/view?tab=profile" id="profile-edit-view-link" title="View this profile">View this profile</a></li>
+<li><a href="profiles/clone/$profile_id" id="profile-edit-clone-link" title="Create a new profile using these settings">Clone this profile</a></li>
+<li></li>
+<li><a href="profiles/drop/$profile_id" id="profile-edit-drop-link" title="Delete this profile" $disabled >Delete this profile</a></li>
+
+</ul>
+</div>
+
+<div id="profile-edit-links-end"></div>
+
+$default
+
+<div id="profile-edit-wrapper" >
+<form id="profile-edit-form" name="form1" action="profiles/$profile_id" method="post" >
+
+<div id="profile-edit-profile-name-wrapper" >
+<label id="profile-edit-profile-name-label" for="profile-edit-profile-name" >Profile Name: </label>
+<input type="text" size="32" name="profile_name" id="profile-edit-profile-name" value="$profile_name" /><div class="required">*</div>
+</div>
+<div id="profile-edit-profile-name-end"></div>
+
+<div id="profile-edit-name-wrapper" >
+<label id="profile-edit-name-label" for="profile-edit-name" >Your Full Name: </label>
+<input type="text" size="32" name="name" id="profile-edit-name" value="$name" />
+</div>
+<div id="profile-edit-name-end"></div>
+
+<div id="profile-edit-pdesc-wrapper" >
+<label id="profile-edit-pdesc-label" for="profile-edit-pdesc" >Title/Description: </label>
+<input type="text" size="32" name="pdesc" id="profile-edit-pdesc" value="$pdesc" />
+</div>
+<div id="profile-edit-pdesc-end"></div>
+
+
+<div id="profile-edit-gender-wrapper" >
+<label id="profile-edit-gender-label" for="gender-select" >Your Gender: </label>
+$gender
+</div>
+<div id="profile-edit-gender-end"></div>
+
+<div id="profile-edit-dob-wrapper" >
+<label id="profile-edit-dob-label" for="dob-select" >Birthday (y/m/d): </label>
+<div id="profile-edit-dob" >
+$dob $age
+</div>
+</div>
+<div id="profile-edit-dob-end"></div>
+
+$hide_friends
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+
+<div id="profile-edit-address-wrapper" >
+<label id="profile-edit-address-label" for="profile-edit-address" >Street Address: </label>
+<input type="text" size="32" name="address" id="profile-edit-address" value="$address" />
+</div>
+<div id="profile-edit-address-end"></div>
+
+<div id="profile-edit-locality-wrapper" >
+<label id="profile-edit-locality-label" for="profile-edit-locality" >Locality/City: </label>
+<input type="text" size="32" name="locality" id="profile-edit-locality" value="$locality" />
+</div>
+<div id="profile-edit-locality-end"></div>
+
+
+<div id="profile-edit-postal-code-wrapper" >
+<label id="profile-edit-postal-code-label" for="profile-edit-postal-code" >Postal/Zip Code: </label>
+<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="$postal_code" />
+</div>
+<div id="profile-edit-postal-code-end"></div>
+
+<div id="profile-edit-country-name-wrapper" >
+<label id="profile-edit-country-name-label" for="profile-edit-country-name" >Country: </label>
+<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('$region');">
+<option selected="selected" >$country_name</option>
+<option>temp</option>
+</select>
+</div>
+<div id="profile-edit-country-name-end"></div>
+
+<div id="profile-edit-region-wrapper" >
+<label id="profile-edit-region-label" for="profile-edit-region" >Region/State: </label>
+<select name="region" id="profile-edit-region" onChange="Update_Globals();" >
+<option selected="selected" >$region</option>
+<option>temp</option>
+</select>
+</div>
+<div id="profile-edit-region-end"></div>
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+<div id="profile-edit-marital-wrapper" >
+<label id="profile-edit-marital-label" for="profile-edit-marital" ><span class="heart">&hearts;</span> (Marital) Status: </label>
+$marital
+</div>
+<label id="profile-edit-with-label" for="profile-edit-with" > Who: (if applicable) </label>
+<input type="text" size="32" name="with" id="profile-edit-with" value="$with" />
+<div id="profile-edit-marital-end"></div>
+
+<div id="profile-edit-sexual-wrapper" >
+<label id="profile-edit-sexual-label" for="sexual-select" >Sexual Preference: </label>
+$sexual
+</div>
+<div id="profile-edit-sexual-end"></div>
+
+
+
+<div id="profile-edit-homepage-wrapper" >
+<label id="profile-edit-homepage-label" for="profile-edit-homepage" >Homepage URL: </label>
+<input type="text" size="32" name="homepage" id="profile-edit-homepage" value="$homepage" />
+</div>
+<div id="profile-edit-homepage-end"></div>
+
+<div id="profile-edit-politic-wrapper" >
+<label id="profile-edit-politic-label" for="profile-edit-politic" >Political Views: </label>
+<input type="text" size="32" name="politic" id="profile-edit-politic" value="$politic" />
+</div>
+<div id="profile-edit-politic-end"></div>
+
+<div id="profile-edit-religion-wrapper" >
+<label id="profile-edit-religion-label" for="profile-edit-religion" >Religion: </label>
+<input type="text" size="32" name="religion" id="profile-edit-religion" value="$religion" />
+</div>
+<div id="profile-edit-religion-end"></div>
+
+<div id="profile-edit-keywords-wrapper" >
+<label id="profile-edit-keywords-label" for="profile-edit-keywords" >Keywords: </label>
+<input type="text" size="32" name="keywords" id="profile-edit-keywords" title="Example: fishing photography software" value="$keywords" />
+</div><div id="profile-edit-keywords-desc">(Used for searching public profiles, never shown to others)</div>
+<div id="profile-edit-keywords-end"></div>
+
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+<div id="about-jot-wrapper" >
+<p id="about-jot-desc" >
+Tell us about yourself... 
+</p>
+
+<textarea rows="10" cols="72" id="profile-jot-text" name="about" >$about</textarea>
+
+</div>
+<div id="about-jot-end"></div>
+</div>
+
+
+<div id="interest-jot-wrapper" >
+<p id="interest-jot-desc" >
+Hobbies/Interests 
+</p>
+
+<textarea rows="10" cols="72" id="interest-jot-text" name="interest" >$interest</textarea>
+
+</div>
+<div id="interest-jot-end"></div>
+</div>
+
+
+<div id="contact-jot-wrapper" >
+<p id="contact-jot-desc" >
+Contact information and Social Networks 
+</p>
+
+<textarea rows="10" cols="72" id="contact-jot-text" name="contact" >$contact</textarea>
+
+</div>
+<div id="contact-jot-end"></div>
+</div>
+
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+
+<div id="music-jot-wrapper" >
+<p id="music-jot-desc" >
+Musical interests 
+</p>
+
+<textarea rows="10" cols="72" id="music-jot-text" name="music" >$music</textarea>
+
+</div>
+<div id="music-jot-end"></div>
+</div>
+
+<div id="book-jot-wrapper" >
+<p id="book-jot-desc" >
+Books, literature 
+</p>
+
+<textarea rows="10" cols="72" id="book-jot-text" name="book" >$book</textarea>
+
+</div>
+<div id="book-jot-end"></div>
+</div>
+
+
+
+<div id="tv-jot-wrapper" >
+<p id="tv-jot-desc" >
+Television 
+</p>
+
+<textarea rows="10" cols="72" id="tv-jot-text" name="tv" >$tv</textarea>
+
+</div>
+<div id="tv-jot-end"></div>
+</div>
+
+
+
+<div id="film-jot-wrapper" >
+<p id="film-jot-desc" >
+Film/dance/culture/entertainment 
+</p>
+
+<textarea rows="10" cols="72" id="film-jot-text" name="film" >$film</textarea>
+
+</div>
+<div id="film-jot-end"></div>
+</div>
+
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+
+<div id="romance-jot-wrapper" >
+<p id="romance-jot-desc" >
+Love/romance 
+</p>
+
+<textarea rows="10" cols="72" id="romance-jot-text" name="romance" >$romance</textarea>
+
+</div>
+<div id="romance-jot-end"></div>
+</div>
+
+
+
+<div id="work-jot-wrapper" >
+<p id="work-jot-desc" >
+Work/employment 
+</p>
+
+<textarea rows="10" cols="72" id="work-jot-text" name="work" >$work</textarea>
+
+</div>
+<div id="work-jot-end"></div>
+</div>
+
+
+
+<div id="education-jot-wrapper" >
+<p id="education-jot-desc" >
+School/education 
+</p>
+
+<textarea rows="10" cols="72" id="education-jot-text" name="education" >$education</textarea>
+
+</div>
+<div id="education-jot-end"></div>
+</div>
+
+
+
+<div class="profile-edit-submit-wrapper" >
+<input type="submit" name="submit" class="profile-edit-submit-button" value="Submit" />
+</div>
+<div class="profile-edit-submit-end"></div>
+
+
+</form>
+</div>
+<script type="text/javascript">Fill_Country('$country_name');Fill_States('$region');</script>
\ No newline at end of file
diff --git a/view/de/profile_entry_default.tpl b/view/de/profile_entry_default.tpl
new file mode 100644 (file)
index 0000000..dff6b53
--- /dev/null
@@ -0,0 +1,9 @@
+
+<div class="profile-listing" >
+<div class="profile-listing-photo-wrapper" >
+<a href="profiles/$id" class="profile-listing-edit-link" ><img class="profile-listing-photo" id="profile-listing-photo-$id" src="$photo" alt="Profilbild" /></a>
+</div>
+<div class="profile-listing-photo-end" ></div>
+<div class="profile-listing-name" id="profile-listing-name-$id"><a href="profiles/$id" class="profile-listing-edit-link" >$profile_name</a></div>
+</div>
+<div class="profile-listing-end"></div>
diff --git a/view/de/profile_listing_header.tpl b/view/de/profile_listing_header.tpl
new file mode 100644 (file)
index 0000000..3be77ba
--- /dev/null
@@ -0,0 +1,8 @@
+<h1>Profile</h1>
+<p id="profile-listing-desc" >
+<a href="profile_photo" >Profilbild ändern</a>
+</p>
+<div id="profile-listing-new-link-wrapper" >
+<a href="profiles/new" id="profile-listing-new-link" name="Neues Profil anlegen" >Neues Profil anlegen</a>
+</div>
+
diff --git a/view/de/profile_photo.tpl b/view/de/profile_photo.tpl
new file mode 100644 (file)
index 0000000..9589522
--- /dev/null
@@ -0,0 +1,14 @@
+<h1>Profilbild Hochladen</h1>
+
+<form enctype="multipart/form-data" action="profile_photo" method="post">
+
+<div id="profile-photo-upload-wrapper">
+<label id="profile-photo-upload-label" for="profile-photo-upload">Datei hochladen: </label>
+<input name="userfile" type="file" id="profile-photo-upload" size="48" />
+</div>
+
+<div id="profile-photo-submit-wrapper">
+<input type="submit" name="submit" id="profile-photo-submit" value="Upload">
+</div>
+
+</form>
\ No newline at end of file
diff --git a/view/de/profile_tabs.tpl b/view/de/profile_tabs.tpl
new file mode 100644 (file)
index 0000000..56e7d62
--- /dev/null
@@ -0,0 +1,7 @@
+
+<div id="profile-tabs-wrapper" >
+       <a href="$url" id="profile-tab-status-link" class="profile-tabs" >Status</a>
+       <a href="$url?tab=profile" id="profile-tab-profile-link" class="profile-tabs" >Profil</a>
+       <a href="$phototab" id="profile-tab-photos-link" class="profile-tabs" >Fotos</a>
+<div id="profile-tabs-end"></div>
+</div>
\ No newline at end of file
diff --git a/view/de/pwdreset.tpl b/view/de/pwdreset.tpl
new file mode 100644 (file)
index 0000000..30aca07
--- /dev/null
@@ -0,0 +1,16 @@
+<h3>Zurücksetzen des Passworts</h3>
+
+<p>
+Dein Passwort wurde wie gewünscht zurück gesetzt.
+</p>
+<p>
+Dein neues Passwort lautet:
+</p>
+<p>
+$newpass
+</p>
+<p>
+Sichere oder kopiere dein neues Passwort und melde dich <a href="$baseurl" >dann hier an</a>.
+</p>
+<p>
+Nachdem du dich angemeldet hast kannst du dein Passwort auf der "Einstellungen" Seite ändern.
\ No newline at end of file
diff --git a/view/de/register-link.tpl b/view/de/register-link.tpl
new file mode 100644 (file)
index 0000000..cf9d797
--- /dev/null
@@ -0,0 +1 @@
+       <a href="register" name="Neuen Account anlegen" id="register-link" >Registrieren</a>
diff --git a/view/de/register_open_eml.tpl b/view/de/register_open_eml.tpl
new file mode 100644 (file)
index 0000000..2addf32
--- /dev/null
@@ -0,0 +1,22 @@
+
+Lieber $username,
+danke für die Registrierung bei $sitename. Dein neuer Account wurde angelegt.
+Die Anmeldedetails sind die Folgenden.
+
+Adresse der Seite: $siteurl
+Anmelde Name: $email
+Passwort: $password
+
+Du kannst dein Passwort auf der "Einstellungen" Seite deines Accounts ändern
+nachdem du dich angemeldet hast.
+
+Nimm dir bitte ein paar Augenblicke Zeit um die anderen Einstellungen deines
+Accounts zu bearbeiten. Standardmäßig ist dein Account privat und versteckt
+(unsichtbar für andere Personen). Falls du möchtest kannst du dein Profil
+veröffentlichen, damit andere Leute dich im Verzeichnis finden.
+
+
+Vielen Dank und Willkommen auf $sitename.
+
+Mit freundlichem Gruß,
+       $sitename Administrator
diff --git a/view/de/register_verify_eml.tpl b/view/de/register_verify_eml.tpl
new file mode 100644 (file)
index 0000000..7ae432d
--- /dev/null
@@ -0,0 +1,21 @@
+
+Ein neuer Nutzer hat sich auf $sitename registriert. Diese Registration
+benötigt noch deine Zustimmung.
+
+Die Anmeldedetails sind Folgende:
+
+Kompletter Name: $username
+Adresse der Seite: $siteurl
+Anmelde Name: $email
+
+
+Um dieser Anmeldung zuzustimmen folge bitte diesem Link:
+
+$siteurl/regmod/allow/$hash 
+
+
+Um die Anfrage abzulehen und den Account zu entfernen folge diesem Link:
+
+$siteurl/regmod/deny/$hash
+
+Besten Dank!
diff --git a/view/de/registrations-top.tpl b/view/de/registrations-top.tpl
new file mode 100644 (file)
index 0000000..d788b51
--- /dev/null
@@ -0,0 +1,3 @@
+<h1>Schwebende Neuanmeldungen</h1>
+
+
diff --git a/view/de/request_notify_eml.tpl b/view/de/request_notify_eml.tpl
new file mode 100644 (file)
index 0000000..15b83f6
--- /dev/null
@@ -0,0 +1,14 @@
+
+Lieber $myname,
+
+du hast gerade eine Kontaktanfrage von '$requestor' auf $sitename erhalten.
+
+Du kannst dir das Profil unter $url ansehen.
+
+Bitte melde dich auf deiner Seite an um die komplette Vorstellung anzusehen
+und bestätige oder ignoriere die Anfrage.
+
+$siteurl
+
+Schöne Grüße,
+       $sitename Administrator
diff --git a/view/de/settings.tpl b/view/de/settings.tpl
new file mode 100644 (file)
index 0000000..0ef5054
--- /dev/null
@@ -0,0 +1,163 @@
+<h1>Account Einstellungen</h1>
+
+<div id="plugin-settings-link"><a href="settings/addon">Plugin Einstellungen</a></div>
+
+$nickname_block
+
+
+<form action="settings" id="settings-form" method="post" autocomplete="off" >
+
+
+<h3 class="settings-heading">Grundeinstellungen</h3>
+
+<div id="settings-username-wrapper" >
+<label id="settings-username-label" for="settings-username" >Kompletter Name: </label>
+<input type="text" name="username" id="settings-username" value="$username" />
+</div>
+<div id="settings-username-end" ></div>
+
+<div id="settings-email-wrapper" >
+<label id="settings-email-label" for="settings-email" >EMail Adresse: </label>
+<input type="text" name="email" id="settings-email" value="$email" />
+</div>
+<div id="settings-email-end" ></div>
+
+
+
+<div id="settings-timezone-wrapper" >
+<label id="settings-timezone-label" for="timezone_select" >Deine Zeitzone: </label>
+$zoneselect
+</div>
+<div id="settings-timezone-end" ></div>
+
+<div id="settings-defloc-wrapper" >
+<label id="settings-defloc-label" for="settings-defloc" >Standardwert Sendestandort: </label>
+<input type="text" name="defloc" id="settings-defloc" value="$defloc" />
+</div>
+<div id="settings-defloc-end" ></div>
+
+<div id="settings-allowloc-wrapper" >
+<label id="settings-allowloc-label" for="settings-allowloc" >Browser Standort verwenden: </label>
+<input type="checkbox" name="allow_location" id="settings-allowloc" value="1" $loc_checked />
+</div>
+<div id="settings-allowloc-end" ></div>
+
+
+
+
+<div id="settings-theme-select">
+<label id="settings-theme-label" for="theme-select" >Anzeige Thema: </label>
+$theme
+</div>
+<div id="settings-theme-end"></div>
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="submit" class="settings-submit" value="Submit" />
+</div>
+
+
+<h3 class="settings-heading">Sicherheits und Privatsphären Einstellungen</h3>
+
+
+<input type="hidden" name="visibility" value="$visibility" />
+
+<div id="settings-maxreq-wrapper">
+<label id="settings-maxreq-label" for="settings-maxreq" >Maximale Anzahl an Freundschaftsanfragen pro Tagy</label>
+<input id="settings-maxreq" name="maxreq" value="$maxreq" />
+<div id="settings-maxreq-desc">(um SPAM zu verhindern)</div>
+</div>
+<div id="settings-maxreq-end"></div>
+
+
+
+
+$profile_in_dir
+
+$profile_in_net_dir
+
+
+
+<div id="settings-default-perms" class="settings-default-perms" >
+       <div id="settings-default-perms-menu" class="fakelink" onClick="openClose('settings-default-perms-select');" >&#x21e9; $permissions</div>
+       <div id="settings-default-perms-menu-end"></div>
+
+       <div id="settings-default-perms-select" style="display: none;" >
+       
+               $aclselect
+
+       </div>
+</div>
+<div id="settings-default-perms-end"></div>
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="submit" class="settings-submit" value="Submit" />
+</div>
+
+
+
+<h3 class="settings-heading">Benachrichtigungs Einstellungen</h3>
+
+
+<div id="settings-notify-wrapper">
+<div id="settings-notify-desc">Benachrichtigungsemail senden wenn: </div>
+<label for="notify1" id="settings-label-notify1">Du eine Vorstellung empfängst</label>
+<input id="notify1" type="checkbox" $sel_notify1 name="notify1" value="1" />
+<div id="notify1-end"></div>
+<label for="notify2" id="settings-label-notify2">Deine Vorstellung bestätigt wurde</label>
+<input id="notify2" type="checkbox" $sel_notify2 name="notify2" value="2" />
+<div id="notify2-end"></div>
+<label for="notify3" id="settings-label-notify3">Jemand etwas auf deiner Profilwand postet</label>
+<input id="notify3" type="checkbox" $sel_notify3 name="notify3" value="4" />
+<div id="notify3-end"></div>
+<label for="notify4" id="settings-label-notify4">Jemand einen Folgebeitrag schreibt</label>
+<input id="notify4" type="checkbox" $sel_notify4 name="notify4" value="8" />
+<div id="notify4-end"></div>
+<label for="notify5" id="settings-label-notify5">Du eine private Nachricht erhälst</label>
+<input id="notify5" type="checkbox" $sel_notify5 name="notify5" value="16" />
+<div id="notify5-end"></div>
+</div>
+<div id="settings=notify-end"></div>
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="submit" class="settings-submit" value="Submit" />
+</div>
+
+
+<h3 class="settings-heading">Passwort Einstellungen</h3>
+
+
+<div id="settings-password-wrapper" >
+<p id="settings-password-desc" >
+Lass die Passwortfelder frei außer du willst das Passwort ändern.
+</p>
+<label id="settings-password-label" for="settings-password" >Neues Passwort: </label>
+<input type="password" id="settings-password" name="npassword" />
+</div>
+<div id="settings-password-end" ></div>
+
+<div id="settings-confirm-wrapper" >
+<label id="settings-confirm-label" for="settings-confirm" >Bestätigen: </label>
+<input type="password" id="settings-confirm" name="confirm" />
+</div>
+<div id="settings-confirm-end" ></div>
+
+<div id="settings-openid-wrapper" >
+       $oidhtml
+</div>
+<div id="settings-openid-end" ></div>
+
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="submit" class="settings-submit" value="Submit" />
+</div>
+
+
+<h3 class="settings-heading">Erweiterte Seiteneinstellungen</h3>
+
+$pagetype
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="submit" class="settings-submit" value="Submit" />
+</div>
+
+
diff --git a/view/de/settings_nick_set.tpl b/view/de/settings_nick_set.tpl
new file mode 100644 (file)
index 0000000..9336951
--- /dev/null
@@ -0,0 +1,9 @@
+
+<div id="settings-nick-wrapper" >
+<p id="settings-nickname-desc">
+<span class="error-message">Deine Profiladresse lautet <strong>'$nickname@$basepath'</strong></span>
+</p>
+$subdir
+
+</div>
+<div id="settings-nick-end" ></div>
diff --git a/view/de/settings_nick_subdir.tpl b/view/de/settings_nick_subdir.tpl
new file mode 100644 (file)
index 0000000..fa189a7
--- /dev/null
@@ -0,0 +1,9 @@
+<p>
+Es scheint so als ob deine Friendika Installation in einem Unterverzeichnis von $hostname
+liegt, es könnte deshalb unzuverlässig arbeiten.
+</p>
+<p>
+Solltest du irgendwelche Probleme haben versuche bitte folgende Profil Adresse
+'<strong>$baseurl/profile/$nickname</strong>' eventuell funktioniert es damit
+besser.
+</p>
diff --git a/view/de/settings_nick_unset.tpl b/view/de/settings_nick_unset.tpl
new file mode 100644 (file)
index 0000000..2a56fda
--- /dev/null
@@ -0,0 +1,16 @@
+
+<div id="settings-nick-wrapper" >
+<p id="settings-nickname-desc">
+Deine Profil URL ist im Moment <strong>'$baseurl/profile/$uid'</strong>.
+Wenn du einen Spitznamen wählst kann man diese URL freundlicher ausdrücken
+z.B. <strong>'spitzname@$basepath'</strong>.
+<br />
+Einmal gewählt kann der Spitzname nicht mehr geändert werden. Er
+<strong>muss</strong> mit einem Buchstaben beginnen. Es sind ausschließlich
+Buchstaben, Zahlen sowie Binde- und Unterstriche erlaubt.
+</p>
+<label id="settings-nick-label" for="settings-nick" >URL Spitzname: </label>
+<input type="text" name="nick" id="settings-nick" value="$nickname" />
+</div>
+<div id="settings-nick-end" ></div>
+
diff --git a/view/de/strings.php b/view/de/strings.php
new file mode 100644 (file)
index 0000000..f59dcf6
--- /dev/null
@@ -0,0 +1,1054 @@
+<?php
+$a->strings['Not Found'] = 'Nicht gefunden';
+$a->strings['Page not found.' ] = 'Seite nicht gefunden.' ;
+$a->strings['Permission denied'] = 'Zugriff verweigert';
+$a->strings['Permission denied.'] = 'Zugriff verweigert.';
+$a->strings['Nickname or Email address: '] = 'Spitzname oder Email-Adresse: ';
+$a->strings['Password: '] = 'Passwort: ';
+$a->strings['Login'] = 'Anmeldung';
+$a->strings['Nickname/Email/OpenID: '] = 'Spitzname/Email/OpenID: ';
+$a->strings["Password \x28if not OpenID\x29: "] = "Passwort \x28falls nicht OpenID\x29: ";
+$a->strings['Forgot your password?'] = 'Passwort vergessen?';
+$a->strings['Password Reset'] = 'Passwort zurücksetzen';
+$a->strings['prev'] = 'vorige';
+$a->strings['first'] = 'erste';
+$a->strings['last'] = 'letzte';
+$a->strings['next'] = 'nächste';
+$a->strings[' likes this.'] = ' mag dies.';
+$a->strings[' doesn\'t like this.'] = ' mag dies nicht.';
+$a->strings['people'] = 'Leute';
+$a->strings['like this.'] = 'mögen dies.';
+$a->strings['don\'t like this.'] = 'mögen dies nicht.';
+$a->strings['and'] = 'und';
+$a->strings[', and '] = ' und ';
+$a->strings[' other people'] = ' andere Leute';
+$a->strings[' like this.'] = ' mögen dies.';
+$a->strings[' don\'t like this.'] = ' mögen dies nicht.';
+$a->strings['No contacts'] = 'Keine Kontakte';
+$a->strings['Contacts'] = 'Kontakte';
+$a->strings['View Contacts'] = 'Kontakte anzeigen';
+$a->strings['Search'] = 'Suche';
+$a->strings['No profile'] = 'Kein Profil';
+$a->strings['Connect'] = 'Verbinden';
+$a->strings['Location:'] = 'Ort:';
+$a->strings[', '] = ', ';
+$a->strings['Gender:'] = 'Geschlecht:';
+$a->strings['Status:'] = 'Status:';
+$a->strings['Homepage:'] = 'Homepage:';
+$a->strings['Monday'] = 'Montag';
+$a->strings['Tuesday'] = 'Dienstag';
+$a->strings['Wednesday'] = 'Mittwoch';
+$a->strings['Thursday'] = 'Donnerstag';
+$a->strings['Friday'] = 'Freitag';
+$a->strings['Saturday'] = 'Samstag';
+$a->strings['Sunday'] = 'Sonntag';
+$a->strings['January'] = 'Januar';
+$a->strings['February'] = 'Februar';
+$a->strings['March'] = 'März';
+$a->strings['April'] = 'April';
+$a->strings['May'] = 'Mai';
+$a->strings['June'] = 'Juni';
+$a->strings['July'] = 'Juli';
+$a->strings['August'] = 'August';
+$a->strings['September'] = 'September';
+$a->strings['October'] = 'Oktober';
+$a->strings['November'] = 'November';
+$a->strings['December'] = 'Dezember';
+$a->strings['Birthdays this week:'] = 'Geburtstage diese Woche:';
+$a->strings["\x28Adjusted for local time\x29"] = "\x28an die lokale Zeit angepasst\x29";
+$a->strings['[today]'] = '[heute]';
+$a->strings["Invite Friends"] = "Freunde einladen";
+$a->strings['Connect/Follow [profile address]'] = 'Kontaktiere/Folge [Profil Adresse]';
+$a->strings['Example: bob@example.com, http://example.com/barbara'] = 'Beispiel: bob@example.com, http://example.com/barbara';
+$a->strings['Follow'] = 'Folge';
+$a->strings['Could not access contact record.'] = 'Konnte nicht auf die Kontaktdaten zugreifen.';
+$a->strings['Could not locate selected profile.'] = 'Konnte das ausgewählte Profiel nicht finden.';
+$a->strings['Contact updated.'] = 'Kontakt aktualisiert.';
+$a->strings['Failed to update contact record.'] = 'Aktualisierung der Kontaktdaten fehlgeschlagen.';
+$a->strings['Contact has been '] = 'Kontakt ';
+$a->strings['blocked'] = 'wurde blockiert';
+$a->strings['unblocked'] = 'ist nicht mehr blockiert';
+$a->strings['ignored'] = 'wurde ignoriert';
+$a->strings['unignored'] = 'wird nicht mehr ignoriert';
+$a->strings['stopped following'] = 'wird nicht mehr gefolgt';
+$a->strings['Contact has been removed.'] = 'Kontakt wurde entfernt.';
+$a->strings['Contact not found.'] = 'Kontakt nicht gefunden.';
+$a->strings['Mutual Friendship'] = 'Beidseitige Freundschaft';
+$a->strings['is a fan of yours'] = 'ist ein Fan von dir';
+$a->strings['you are a fan of'] = 'du bist Fan von';
+$a->strings['Contact Editor'] = 'Kontakt Editor';
+$a->strings['Visit $name\'s profile'] = 'Besuche das Profil von $name';
+$a->strings['Block/Unblock contact'] = 'Kontakt blockieren/freischalten';
+$a->strings['Ignore contact'] = 'Ignoriere den Kontakt';
+$a->strings['Delete contact'] = 'Lösche den Kontakt';
+$a->strings['Last updated: '] = 'Letzte Aktualisierung: ';
+$a->strings['Update public posts: '] = 'Aktualisierung öffentlicher Nachrichten: ';
+$a->strings['Never'] = 'Niemals';
+$a->strings['Update now'] = 'Jetzt aktualisieren';
+$a->strings['Unblock this contact'] = 'Blockade dieses Kontakts aufheben';
+$a->strings['Block this contact'] = 'Diesen Kontakt blockieren';
+$a->strings['Unignore this contact'] = 'Diesen Kontakt nicht mehr ignorieren';
+$a->strings['Ignore this contact'] = 'Diesen Kontakt ignorieren';
+$a->strings['Currently blocked'] = 'Derzeit geblockt';
+$a->strings['Currently ignored'] = 'Derzeit ignoriert';
+$a->strings['Show Blocked Connections'] = 'Zeige geblockte Verbindungen';
+$a->strings['Hide Blocked Connections'] = 'Verstecke geblockte Verbindungen';
+$a->strings['Finding: '] = 'Funde: ';
+$a->strings['Find'] = 'Finde';
+$a->strings['Visit '] = 'Besuche ';
+$a->strings['\'s profile'] = 's Profile';
+$a->strings['Edit contact'] = 'Kontakt bearbeiten';
+$a->strings['Profile not found.'] = 'Profil nicht gefunden.';
+$a->strings['Response from remote site was not understood.'] = 'Antwort der entfernten Gegenstelle unverständlich.';
+$a->strings['Unexpected response from remote site: '] = 'Unerwartete Antwort der Gegenstelle: ';
+$a->strings["Confirmation completed successfully."] = "Bestätigung erfolgreich abgeschlossen.";
+$a->strings['Remote site reported: '] = 'Entfernte Seite meldet: ';
+$a->strings["Temporary failure. Please wait and try again."] = "Zeitweiser Fehler. Bitte warte einige Momente und versuche es dann noch einmal.";
+$a->strings["Introduction failed or was revoked."] = "Vorstellung schlug fehl oder wurde zurück gezogen.";
+$a->strings['Unable to set contact photo.'] = 'Konnte das Bild des Kontakts nicht speichern.';
+$a->strings['is now friends with'] = 'ist jetzt ein(e) Freund(in) von';
+$a->strings['No user record found for '] = 'Kein Nutzereintrag gefunden für ';
+$a->strings['Our site encryption key is apparently messed up.'] = 'Der Verschlüsslungsschlüssel unserer Seite ist anscheinend im Arsch.';
+$a->strings['Empty site URL was provided or URL could not be decrypted by us.'] = 'Leere URL für die Seite erhalten oder die URL konnte nicht entschlüsselt werden.';
+$a->strings['Contact record was not found for you on our site.'] = 'Für diesen Kontakt wurde auf unserer Seite kein Eintrag gefunden.';
+$a->strings['The ID provided by your system is a duplicate on our system. It should work if you try again.'] = 'Die ID die uns dein System angeboten hat ist hier bereits vergeben. Bitte versuche es noch einmal.';
+$a->strings['Unable to set your contact credentials on our system.'] = 'Deine Kontaktreferenzen konnten nicht in unserm System gespeichert werden.';
+$a->strings['Unable to update your contact profile details on our system'] = 'Die Updates für dein Profil konnten nicht gespeichert werden';
+$a->strings["Connection accepted at "] = "Connection accepted at ";
+$a->strings['Administrator'] = 'Administrator';
+$a->strings['New mail received at '] = 'New mail received at ';
+$a->strings[' commented on an item at '] = ' commented on an item at ';
+$a->strings[" commented on an item at "] = " commented on an item at ";
+$a->strings[' welcomes '] = ' welcomes ';
+$a->strings["This introduction has already been accepted."] = "Diese Vorstellung wurde bereits abgeschlossen.";
+$a->strings['Profile location is not valid or does not contain profile information.'] = 'Profile location is not valid or does not contain profile information.';
+$a->strings['Warning: profile location has no identifiable owner name.'] = 'Warning: profile location has no identifiable owner name.';
+$a->strings['Warning: profile location has no profile photo.'] = 'Warning: profile location has no profile photo.';
+$a->strings[' required parameter'] = ' required parameter';
+$a->strings[" was "] = " was ";
+$a->strings["s were "] = "s were ";
+$a->strings["not found at the given location."] = "not found at the given location.";
+$a->strings["Introduction complete."] = "Vorstellung abgeschlossen.";
+$a->strings['Unrecoverable protocol error.'] = 'Nicht behebbarer Protokollfehler.';
+$a->strings['Profile unavailable.'] = 'Profil nicht verfügbar.';
+$a->strings[' has received too many connection requests today.'] = ' hat heute zu viele Nachfragen zwecks Kontaktaufnahme erhalten.';
+$a->strings['Spam protection measures have been invoked.'] = 'Maßnahmen zum Spamschutz wurden ergriffen.';
+$a->strings['Friends are advised to please try again in 24 hours.'] = 'Freunde sind angehalten es in 24 Stunden erneut zu versuchen.';
+$a->strings["Invalid locator"] = "Invalid locator";
+$a->strings["Unable to resolve your name at the provided location."] = "Unable to resolve your name at the provided location.";
+$a->strings['You have already introduced yourself here.'] = 'Du hast dich hier bereits vorgestellt.';
+$a->strings['Apparently you are already friends with .'] = 'Offenbar bist du bereits ein Freund von ';
+$a->strings['Invalid profile URL.'] = 'Ungültige Profil URL.';
+$a->strings['Disallowed profile URL.'] = 'Nicht erlaubte Profil URL.';
+$a->strings['Your introduction has been sent.'] = 'Deine Vorstellung wurde abgeschickt.';
+$a->strings["Please login to confirm introduction."] = "Bitte melde dich an um die Vorstellung zu bestätigen.";
+$a->strings["Incorrect identity currently logged in. Please login to <strong>this</strong> profile."] = "Incorrect identity currently logged in. Please login to <strong>this</strong> profile.";
+$a->strings['[Name Withheld]'] = '[Name Zurückgehalten]';
+$a->strings['Friend/Connection Request'] = 'Freundschafts/Kontakt Anfrage';
+$a->strings['Please answer the following:'] = 'Bitte beantworte folgende Fragen:';
+$a->strings['Does $name know you?'] = 'Kennt $name dich?';
+$a->strings['Yes'] = 'Ja';
+$a->strings['No'] = 'Nein';
+$a->strings['Add a personal note:'] = 'Eine persönliche Notiz anfügen:';
+$a->strings['Please enter your profile address from one of the following supported social networks:'] = 'Bitte gib deine Profil Adresse von einem der unterstützten Sozialen Netzwerken an:';
+$a->strings['Friendika'] = 'Friendika';
+$a->strings['StatusNet/Federated Social Web'] = 'StatusNet/Federated Social Web';
+$a->strings["Private \x28secure\x29 network"] = "Privates \x28sicheres\x29 Netzwerk";
+$a->strings["Public \x28insecure\x29 network"] = "Öffentliches \x28unsicheres\x29 Netzwerk";
+$a->strings['Your profile address:'] = 'Deine Profiladresse:';
+$a->strings['Submit Request'] = 'Anfrage abschicken';
+$a->strings['Cancel'] = 'Abbrechen';
+$a->strings['Global Directory'] = 'Weltweites Verzeichnis';
+$a->strings['Item not found.'] = 'Eintrag nicht gefunden.';
+$a->strings['Private Message'] = 'Private Nachricht';
+$a->strings['This is you'] = 'Das bist du';
+$a->strings['View $name\'s profile'] = 'Profile von $name';
+$a->strings['Item has been removed.'] = 'Eintrag wurde entfernt.';
+$a->strings['Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.'] = 'Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.';
+$a->strings['The profile address specified does not provide adequate information.'] = 'Die angegebene Profiladresse liefert unzureichende Informationen.';
+$a->strings['Limited profile. This person will be unable to receive direct/personal notifications from you.'] = 'Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können.';
+$a->strings['Unable to retrieve contact information.'] = 'Konnte die Kontaktinformationen nicht empfangen.';
+$a->strings['following'] = 'folgen';
+$a->strings['Group created.'] = 'Gruppe erstellt.';
+$a->strings['Could not create group.'] = 'Konnte die Gruppe nicht erstellen.';
+$a->strings['Group not found.'] = 'Gruppe nicht gefunden.';
+$a->strings['Group name changed.'] = 'Gruppenname geändert.';
+$a->strings['Membership list updated.'] = 'Mitgliedsliste aktualisiert.';
+$a->strings['Group removed.'] = 'Gruppe entfernt.';
+$a->strings['Unable to remove group.'] = 'Konnte die Gruppe nicht entfernen.';
+$a->strings['Delete'] = 'Löschen';
+$a->strings["Welcome to "] = "Willkommen zu ";
+$a->strings['Could not create/connect to database.'] = 'Konnte die Verbindung zur Datenbank nicht aufbauen bzw. die Datenbank anlegen.';
+$a->strings['Connected to database.'] = 'Mit der Datenbank verbunden.';
+$a->strings['Database import succeeded.'] = 'Import der Datenbank erfolgreich.';
+$a->strings['IMPORTANT: You will need to [manually] setup a scheduled task for the poller.'] = 'WICHTIG: Du musst [manuell] einen cron Job (o.ä.) für den Poller einrichten.';
+$a->strings['Please see the file "INSTALL.txt".'] = 'Lies bitte die "INSTALL.txt".';
+$a->strings['Database import failed.'] = 'Import der Datenbank schlug fehl.';
+$a->strings['You may need to import the file "database.sql" manually using phpmyadmin or mysql.'] = 'Möglicherweise musst du die Datei "database.sql" manuell mit phpmyadmin oder mysql importieren.';
+$a->strings['Welcome to Friendika.'] = 'Willkommen bei Friendika.';
+$a->strings['Submit'] = 'Senden';
+$a->strings['Could not find a command line version of PHP in the web server PATH.'] = 'Konnte keine Kommandozeilenversion von PHP im PATH des Servers finden.';
+$a->strings['This is required. Please adjust the configuration file .htconfig.php accordingly.'] = 'Diese wird von Friendika benötigt. Bitte passe die Konfigurationsdatei .htconfig.php entsprechend an.';
+$a->strings['The command line version of PHP on your system does not have "register_argc_argv" enabled.'] = 'Die Kommandozeilenversion von PHP auf deinem System hat "register_argc_argv" nicht aktiviert.';
+$a->strings['This is required for message delivery to work.'] = 'Dies wird für die Auslieferung von Nachrichten benötigt.';
+$a->strings['Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'] = 'Fehler: Die "openssl_pkey_new" Funktion auf diesem System ist nicht in der lage Verschlüsselungsschlüssel zu erzeugen';
+$a->strings['If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".'] = 'Wenn der Server unter Windows läuft, schau dir bitte "http://www.php.net/manual/en/openssl.installation.php" an.';
+$a->strings['Error: Apache webserver mod-rewrite module is required but not installed.'] = 'Fehler: Das Apache Modul mod-rewrite wird benötigt, es ist allerdings nicht installiert.';
+$a->strings['Error: libCURL PHP module required but not installed.'] = 'Fehler: Das libCURL PHP Modul wird benötigt ist aber nicht installiert.';
+$a->strings['Error: GD graphics PHP module with JPEG support required but not installed.'] = 'Fehler: Das GD Graphikmodul für PHP mit JPEG Unterstützung ist nicht installiert.';
+$a->strings['Error: openssl PHP module required but not installed.'] = 'Fehler: Das openssl Modul von PHP ist nict installiert.';
+$a->strings['Error: mysqli PHP module required but not installed.'] = 'Fehler: Das mysqli Modul von PHP ist nicht installiert.';
+$a->strings['The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.'] = 'Der Installationswizzard muss in der Lage sein eine Datei im Stammverzeichnis deines Webservers anzuliegen ist allerdings derzeit nicht in der Lage dies zu tun.';
+$a->strings['This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.'] = 'In den meisten Fällen ist dies ein Problem mit den Schreibrechten, der Webserver könnte keine Schreiberlaubnis haben, selbst wenn du sie hast.';
+$a->strings['Please check with your site documentation or support people to see if this situation can be corrected.'] = 'Bitte überprüfe die Einstellungen und frage im Zweifelsfall dein Support Team um diese Situations zu beheben.';
+$a->strings['If not, you may be required to perform a manual installation. Please see the file "INSTALL.txt" for instructions.'] = 'Sollte dies nicht möglich sein musst du die Installation manuell durchführen. Lies dazu bitte in der Datei "INSTALL.txt".';
+$a->strings['The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.'] = 'Die Konfigurationsdatei ".htconfig.php" konnte nicht angelegt werden. Bitte verwende den angefügten Text um die Datei im Stammverzeichnis deiner Friendika Installation zu erzeugen.';
+$a->strings['Errors encountered creating database tables.'] = 'Fehler aufgetreten wärend der Erzeugung der Datenbank Tabellen.';
+$a->strings[' : '] = ' : ';
+$a->strings['Not a valid email address.'] = 'Keine gültige EMail Adresse.';
+$a->strings['Please join my network on '] = 'Bitte trete meinem Netzwerk bei ';
+$a->strings['Message delivery failed.'] = 'Zustellung der Nachricht fehlgeschlagen.';
+$a->strings[' messages sent.'] = ' Nachrichten gesendet.';
+$a->strings['Send invitations'] = 'Einladungen senden';
+$a->strings['Enter email addresses, one per line:'] = 'EMail Adressen eingeben, eine pro Zeile:';
+$a->strings['Your message:'] = 'Deine Nachricht:';
+$a->strings['Please join my social network on '] = 'Bitte trete meinem sozialen Netzwerk bei ';
+$a->strings['To accept this invitation, please visit:'] = 'Um diese Einladung anzunehmen beuche bitte:';
+$a->strings['Once you have registered, please connect with me via my profile page at:'] = 'Sobald du registriert bist kontaktiere mich bitte auf meiner Profilseite:';
+$a->strings['Unable to locate original post.'] = 'Konnte das original Posting nicht finden.';
+$a->strings['Empty post discarded.'] = 'Leere Nachricht verworfen.';
+$a->strings['Wall Photos'] = 'Pinnwand Fotos';
+$a->strings[" commented on your item at "] = " kommentierte eines deiner Postings auf ";
+$a->strings[" posted on your profile wall at "] = " schrieb an deine Profilwand auf ";
+$a->strings['This message was sent to you by '] = 'This message was sent to you by ';
+$a->strings[', a member of the Friendika social network.'] = ', a member of the Friendika social network.';
+$a->strings['You may visit them online at'] = 'You may visit them online at';
+$a->strings['Please contact the sender by replying to this post if you do not wish to receive these messages.'] = 'Please contact the sender by replying to this post if you do not wish to receive these messages.';
+$a->strings['posted an update.'] = 'posted an update.';
+$a->strings['photo'] = 'Foto';
+$a->strings['status'] = 'Status';
+$a->strings['likes'] = 'mag es';
+$a->strings['doesn\'t like'] = 'mag es nicht';
+$a->strings['\'s'] = '\'s';
+$a->strings['Remote privacy information not available.'] = 'Entfernte Privatsphäreneinstellungen nicht verfügbar.';
+$a->strings['Visible to:'] = 'Sichtbar für:';
+$a->strings['Password reset requested at '] = 'Anfrage zum Zurücksetzen des Passworts erhalten ';
+$a->strings['No recipient selected.'] = 'Kein Empfänger gewählt.';
+$a->strings['[no subject]'] = '[kein Betreff]';
+$a->strings['Unable to locate contact information.'] = 'Konnte die Kontaktinformationen nicht finden.';
+$a->strings['Message sent.'] = 'Nachricht gesendet.';
+$a->strings['Message could not be sent.'] = 'Nachricht konnte nicht gesendet werden.';
+$a->strings['Messages'] = 'Nachrichten';
+$a->strings['Inbox'] = 'Eingang';
+$a->strings['Outbox'] = 'Ausgang';
+$a->strings['New Message'] = 'Neue Nachricht';
+$a->strings['Message deleted.'] = 'Nachricht gelöscht.';
+$a->strings['Conversation removed.'] = 'Unterhaltung gelöscht.';
+$a->strings['Send Private Message'] = 'Private Nachricht senden';
+$a->strings['To:'] = 'An:';
+$a->strings['Subject:'] = 'Betreff:';
+$a->strings['Upload photo'] = 'Foto hochladen';
+$a->strings['Insert web link'] = 'Weblink einfügen';
+$a->strings['Please wait'] = 'Bitte warten';
+$a->strings['No messages.'] = 'Keine Nachrichten.';
+$a->strings['Delete conversation'] = 'Unterhaltung löschen';
+$a->strings['Message not available.'] = 'Nachricht nicht verfügbar.';
+$a->strings['Delete message'] = 'Nachricht löschen';
+$a->strings['Send Reply'] = 'Antwort senden';
+$a->strings['Normal View'] = 'Normale Ansicht';
+$a->strings['New Item View'] = 'Neue Einträge';
+$a->strings['CC: email addresses'] = 'CC: EMail Addresse';
+$a->strings['Example: bob@example.com, mary@example.com'] = 'Z.B.: bob@example.com, mary@example.com';
+$a->strings['No such group'] = 'Es gibt keine solche Gruppe';
+$a->strings['Group is empty'] = 'Gruppe ist leer';
+$a->strings['Group: '] = 'Gruppe: ';
+$a->strings['View in context'] = 'Im Zusammenhang betrachten';
+$a->strings['Invalid request identifier.'] = 'Invalid request identifier.';
+$a->strings['Discard'] = 'Verwerfen';
+$a->strings['Ignore'] = 'Ignorieren';
+$a->strings['Show Ignored Requests'] = 'Zeige ignorierte Anfragen';
+$a->strings['Hide Ignored Requests'] = 'Verberge ignorierte Anfragen';
+$a->strings['Claims to be known to you: '] = 'Behauptet dich zu kennen: ';
+$a->strings['yes'] = 'ja';
+$a->strings['no'] = 'nein';
+$a->strings['Notification type: '] = 'Benachrichtigungs Typ: ';
+$a->strings['Friend/Connect Request'] = 'Kontakt-/Freundschaftsanfrage';
+$a->strings['New Follower'] = 'Neuer Bewunderer';
+$a->strings['Approve'] = 'Genehmigen';
+$a->strings['No notifications.'] = 'Keine Benachrichtigungen.';
+$a->strings['No registrations.'] = 'Keine Neuanmeldungen.';
+$a->strings['Login failed.'] = 'Annmeldung fehlgeschlagen.';
+$a->strings["Welcome back "] = "Willkommen zurück ";
+$a->strings['Photo Albums'] = 'Fotoalben';
+$a->strings['Contact Photos'] = 'Kontaktbilder';
+$a->strings['Contact information unavailable'] = 'Kontakt Informationen nicht verfügbar';
+$a->strings['Profile Photos'] = 'Profilbilder';
+$a->strings['Album not found.'] = 'Album nicht gefunden.';
+$a->strings['Delete Album'] = 'Album löschen';
+$a->strings['Delete Photo'] = 'Foto löschen';
+$a->strings['was tagged in a'] = 'was tagged in a';
+$a->strings['by'] = 'by';
+$a->strings['Image exceeds size limit of '] = 'Die Bildgröße übersteigt das Limit von ';
+$a->strings['Unable to process image.'] = 'Konnte das Bild nicht bearbeiten.';
+$a->strings['Image upload failed.'] = 'Hochladen des Bildes gescheitert.';
+$a->strings['No photos selected'] = 'Keine Bilder ausgewählt';
+$a->strings['Upload Photos'] = 'Bilder hochladen';
+$a->strings['New album name: '] = 'Name des neuen Albums: ';
+$a->strings['or existing album name: '] = 'oder existierender Albumname: ';
+$a->strings['Permissions'] = 'Berechtigungen';
+$a->strings['Edit Album'] = 'Album bearbeiten';
+$a->strings['View Photo'] = 'Fotos betrachten';
+$a->strings['Photo not available'] = 'Foto nicht verfügbar';
+$a->strings['Edit photo'] = 'Foto bearbeiten';
+$a->strings['View Full Size'] = 'Betrachte Originalgröße';
+$a->strings['Tags: '] = 'Tags: ';
+$a->strings['[Remove any tag]'] = '[Tag entfernen]';
+$a->strings['New album name'] = 'Name des neuen Albums';
+$a->strings['Caption'] = 'Titel';
+$a->strings['Add a Tag'] = 'Tag hinzufügen';
+$a->strings['Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'] = 'Beispiel: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping';
+$a->strings['Recent Photos'] = 'Neuste Fotos';
+$a->strings['Upload New Photos'] = 'Weitere Fotos hochladen';
+$a->strings['View Album'] = 'Album betrachten';
+$a->strings['Image uploaded but image cropping failed.'] = 'Bilder hochgeladen aber das Zuschneiden ist fehlgeschlagen.';
+$a->strings['Image size reduction [175] failed.'] = 'Image size reduction [175] failed.';
+$a->strings['Image size reduction [80] failed.'] = 'Image size reduction [80] failed.';
+$a->strings['Image size reduction [48] failed.'] = 'Image size reduction [48] failed.';
+$a->strings['Unable to process image'] = 'Bild konnte nicht verarbeitet werden';
+$a->strings['Image uploaded successfully.'] = 'Bild erfolgreich auf den Server geladen.';
+$a->strings['Image size reduction [640] failed.'] = 'Image size reduction [640] failed.';
+$a->strings['Profile Name is required.'] = 'Profilname ist erforderlich.';
+$a->strings['Profile updated.'] = 'Profil aktualisiert.';
+$a->strings['Profile deleted.'] = 'Profil gelöscht.';
+$a->strings['Profile-'] = 'Profil-';
+$a->strings['New profile created.'] = 'Neues Profil angelegt';
+$a->strings['Profile unavailable to clone.'] = 'Profil nicht zum Duplizieren verfügbar.';
+$a->strings['This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet.'] = 'Dies ist dein <strong>öffentliches</strong> Profil.<br />Es <strong>könnte</strong> für jeden Nutzer des Internets sichtbar sein.';
+$a->strings['Age: '] = 'Alter: ';
+$a->strings['Profile Image'] = 'Profilbild';
+$a->strings['Invalid OpenID url'] = 'Ungültige OpenID URL';
+$a->strings['Please enter the required information.'] = 'Bitte trage die erforderlichen Informationen ein.';
+$a->strings['Please use a shorter name.'] = 'Bitte verwende einen kürzeren Namen.';
+$a->strings['Name too short.'] = 'Der Name ist zu kurz.';
+$a->strings["That doesn\'t appear to be your full \x28First Last\x29 name."] = "Das scheint kein vollständiger Name zu sein, verwende \x28Vorname Nachname\x29.";
+$a->strings['Your email domain is not among those allowed on this site.'] = 'Die Domain deiner EMail Adresse ist nicht erlaubt auf dieser Seite.';
+$a->strings['Cannot use that email.'] = 'Konnte diese EMail Adresse nicht verwenden';
+$a->strings['Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.'] = 'Dein Spitzname darf nur aus Buchstaben und Zahlen ("a-z","0-9", "_" und "-") bestehen, außerdem muss er mit einem Buchstaben beginnen.';
+$a->strings['Nickname is already registered. Please choose another.'] = 'Dieser Spitzname ist bereits vergeben. Bitte wähle einen anderen.';
+$a->strings['SERIOUS ERROR: Generation of security keys failed.'] = 'SERIOUS ERROR: Generation of security keys failed.';
+$a->strings['An error occurred during registration. Please try again.'] = 'Wärend der Anmeldung ist ein Fehler aufgetreten. Bitte versuche es noch einmal.';
+$a->strings['An error occurred creating your default profile. Please try again.'] = 'Bei der Erstellung des Standard-Profils ist ein Fehler aufgetreten. Bitte versuche es noch einmal.';
+$a->strings['Registration details for '] = 'Details der Registrierung für ';
+$a->strings['Registration successful. Please check your email for further instructions.'] = 'Registration erfolgreich. Eine EMail mit weiteren Anweisungen wurde an dich gesendet.';
+$a->strings['Failed to send email message. Here is the message that failed.'] = 'Konnte die EMail nicht versenden. Hier ist die Nachricht die nicht gesendet werden konnte.';
+$a->strings['Your registration can not be processed.'] = 'Deine Registration konnte nicht verarbeitet werden.';
+$a->strings['Registration request at '] = 'Registrationsanfrage für ';
+$a->strings['Your registration is pending approval by the site owner.'] = 'Deine Registration muss noch vom Betreiber der Seite freigegeben werden.';
+$a->strings["You may \x28optionally\x29 fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "Du kannst dieses Formular auch \x28optional\x29 mit deiner OpenID ausfüllen indem du deine OpenID angibst und 'Registrieren' klickst.";
+$a->strings['If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.'] = 'Wenn du nicht mit OpenID vertraut bist, lass dieses Feld bitte leer und fülle die restlichen Felder aus.';
+$a->strings["Your OpenID \x28optional\x29: "] = "Deine OpenID \x28optional\x29: ";
+$a->strings['Registration'] = 'Registration';
+$a->strings['Your Full Name ' . "\x28" . 'e.g. Joe Smith' . "\x29" . ': '] = 'Vollständiger Name ' . "\x28" . 'z.B. Joe Smith' . "\x29" . ': ';
+$a->strings['Your Email Address: '] = 'Deine EMail Adresse: ';
+$a->strings['Choose a profile nickname. This must begin with a text character. Your global profile locator will then be \'<strong>nickname@$sitename</strong>\'.'] = 'Wähle eine Spitznamen, der mit einem Buchstaben beginnt. Deine globale Profiladresse wird dann \'<strong>spitzname@$sitename</strong>\' sein.';
+$a->strings['Choose a nickname: '] = 'Spitznamen wählen: ';
+$a->strings['Register'] = 'Registrieren';
+$a->strings['Please login.'] = 'Bitte melde dich an.';
+$a->strings['Registration revoked for '] = 'Registration zurückgezogen ';
+$a->strings['Account approved.'] = 'Account freigegeben.';
+$a->strings['View in context'] = 'Im Kontext betrachten';
+$a->strings['Passwords do not match. Password unchanged.'] = 'Die Passwörter stimmen nicht überein. Das Passwort bleibt unverändert.';
+$a->strings['Empty passwords are not allowed. Password unchanged.'] = 'Leere Passwörter sind nicht erlaubt. Passwort bleibt unverändert.';
+$a->strings['Password changed.'] = 'Passwort ändern.';
+$a->strings['Password update failed. Please try again.'] = 'Aktualisierung des Passworts gescheitert, bitte versuche es noch einmal';
+$a->strings[' Please use a shorter name.'] = ' Bitte verwende einen kürzeren Namen.';
+$a->strings[' Name too short.'] = ' Name ist zu kurz.';
+$a->strings[' Not valid email.'] = ' Keine gültige EMail.';
+$a->strings['Settings updated.'] = 'Einstellungen aktualisiert.';
+$a->strings['Plugin Settings'] = 'Plugin Einstellungen';
+$a->strings['Account Settings'] = 'Account Einstellungen';
+$a->strings['No Plugin settings configured'] = 'Keine Erweiterungen konfiguriert';
+$a->strings['OpenID: '] = 'OpenID: ';
+$a->strings["&nbsp;\x28Optional\x29 Allow this OpenID to login to this account."] = "&nbsp;\x28Optional\x29 Erlaube dieser OpenID sich für diesen Account anzumelden.";
+$a->strings['Profile is <strong>not published</strong>.'] = 'Profil ist <strong>nicht veröffentlicht</strong>.';
+$a->strings['Default Post Permissions'] = 'Grundeinstellung für Veröffentlichungen';
+$a->strings['Tag removed'] = 'Tag entfernt';
+$a->strings['Remove Item Tag'] = 'Gegenstands Tag entfernen';
+$a->strings['Select a tag to remove: '] = 'Wähle ein Tag zum Entfernen aus: ';
+$a->strings['Remove'] = 'Entfernen';
+$a->strings['No contacts.'] = 'Keine Kontakte.';
+$a->strings['Visible To:'] = 'Sichtbar für:';
+$a->strings['Groups'] = 'Gruppen';
+$a->strings['Except For:'] = 'Abgesehen von:';
+$a->strings['Logged out.'] = 'Abgemeldet.';
+$a->strings['Unknown | Not categorised'] = 'Unbekannt | Nicht kategorisiert';
+$a->strings['Block immediately'] = 'Sofort blockieren';
+$a->strings['Shady, spammer, self-marketer'] = 'Zwielichtig, Spammer, Selbstdarsteller';
+$a->strings['Known to me, but no opinion'] = 'Ist mir bekannt, hab aber keine Meinung';
+$a->strings['OK, probably harmless'] = 'OK, wahrscheinlich harmlos';
+$a->strings['Reputable, has my trust'] = 'Seriös, hat mein Vertrauen';
+$a->strings['Frequently'] = 'Häufig';
+$a->strings['Hourly'] = 'Stündlich';
+$a->strings['Twice daily'] = 'Zweimal Täglich';
+$a->strings['Daily'] = 'Täglich';
+$a->strings['Weekly'] = 'Wöchendlich';
+$a->strings['Monthly'] = 'Monatlich';
+$a->strings['Miscellaneous'] = 'Verschiedenes';
+$a->strings['less than a second ago'] = 'vor weniger als einer Sekunde';
+$a->strings['year'] = 'Jahr';
+$a->strings['years'] = 'Jahre';
+$a->strings['month'] = 'Monat';
+$a->strings['months'] = 'Monate';
+$a->strings['week'] = 'Woche';
+$a->strings['weeks'] = 'Wochen';
+$a->strings['day'] = 'Tag';
+$a->strings['days'] = 'Tage';
+$a->strings['hour'] = 'Stunde';
+$a->strings['hours'] = 'Stunden';
+$a->strings['minute'] = 'Minute';
+$a->strings['minutes'] = 'Minuten';
+$a->strings['second'] = 'Sekunde';
+$a->strings['seconds'] = 'Sekunden';
+$a->strings[' ago'] = ' her';
+$a->strings['Create a new group'] = 'Neue Gruppe erstellen';
+$a->strings['Everybody'] = 'Alle Kontakte';
+$a->strings['Birthday:'] = 'Geburtstag:';
+$a->strings['Logout'] = 'Abmelden';
+$a->strings['Home'] = 'Persönlich';
+$a->strings['Directory'] = 'Verzeichnis';
+$a->strings['Network'] = 'Netzwerk';
+$a->strings['Notifications'] = 'Benachrichtigungen';
+$a->strings['Settings'] = 'Einstellungen';
+$a->strings['Profiles'] = 'Profile';
+$a->strings['Embedding disabled'] = 'Einbettungen deaktiviert';
+$a->strings['Male'] = 'Männlich';
+$a->strings['Female'] = 'Weiblich';
+$a->strings['Currently Male'] = 'Momentan Männlich';
+$a->strings['Currently Female'] = 'Momentan Weiblich';
+$a->strings['Mostly Male'] = 'Hauptsächlich Männlich';
+$a->strings['Mostly Female'] = 'Hauptsächlich Weiblich';
+$a->strings['Transgender'] = 'Transgender';
+$a->strings['Intersex'] = 'Intersex';
+$a->strings['Transsexual'] = 'Transsexuel';
+$a->strings['Hermaphrodite'] = 'Hermaphrodit';
+$a->strings['Neuter'] = 'Neuter';
+$a->strings['Non-specific'] = 'Nicht spezifiziert';
+$a->strings['Other'] = 'Andere';
+$a->strings['Undecided'] = 'Unentschieden';
+$a->strings['Males'] = 'Männer';
+$a->strings['Females'] = 'Frauen';
+$a->strings['Gay'] = 'Schwul';
+$a->strings['Lesbian'] = 'Lesbisch';
+$a->strings['No Preference'] = 'Keine Vorlieben';
+$a->strings['Bisexual'] = 'Bisexuel';
+$a->strings['Autosexual'] = 'Autosexual';
+$a->strings['Abstinent'] = 'Abstinent';
+$a->strings['Virgin'] = 'Jungfrau';
+$a->strings['Deviant'] = 'Deviant';
+$a->strings['Fetish'] = 'Fetish';
+$a->strings['Oodles'] = 'Oodles';
+$a->strings['Nonsexual'] = 'Nonsexual';
+$a->strings['Single'] = 'Single';
+$a->strings['Lonely'] = 'Einsam';
+$a->strings['Available'] = 'Verfügbar';
+$a->strings['Unavailable'] = 'Nichtverfügbar';
+$a->strings['Dating'] = 'Dating';
+$a->strings['Unfaithful'] = 'Untreu';
+$a->strings['Sex Addict'] = 'Sex Besessen';
+$a->strings['Friends'] = 'Freunde';
+$a->strings['Friends/Benefits'] = 'Friends/Benefits';
+$a->strings['Casual'] = 'Casual';
+$a->strings['Engaged'] = 'Verlobt';
+$a->strings['Married'] = 'Verheiratet';
+$a->strings['Partners'] = 'Partner';
+$a->strings['Cohabiting'] = 'kohabitierend';
+$a->strings['Happy'] = 'Glücklich';
+$a->strings['Not Looking'] = 'Nicht auf der Suche';
+$a->strings['Swinger'] = 'Swinger';
+$a->strings['Betrayed'] = 'Betrogen';
+$a->strings['Separated'] = 'Getrennt';
+$a->strings['Unstable'] = 'Unstabil';
+$a->strings['Divorced'] = 'Geschieden';
+$a->strings['Widowed'] = 'Verwidwet';
+$a->strings['Uncertain'] = 'Unsicher';
+$a->strings['Complicated'] = 'Kompliziert';
+$a->strings['Don\'t care'] = 'Ist mir nicht wichtig';
+$a->strings['Ask me'] = 'Frag mich';
+$a->strings['Facebook status update failed.'] = 'Konnte den Facebook Status nicht aktualisieren.';
+$a->strings['Select files to upload: '] = 'Wähle Dateien zum Upload aus: ';
+$a->strings['Use the following controls only if the Java uploader [above] fails to launch.'] = 'Verwende die folgenden Kontrollen nur, wenn der Java Uploader [oben] nicht funktioniert.';
+$a->strings['Upload a file'] = 'Datei hochladen';
+$a->strings['Drop files here to upload'] = 'Ziehe die Dateien hier her die du hochladen willst';
+$a->strings['Failed'] = 'Fehlgeschlagen';
+$a->strings['No files were uploaded.'] = 'Keine Dateien hochgeladen.';
+$a->strings['Uploaded file is empty'] = 'Hochgeladene Datei ist leer';
+$a->strings['Uploaded file is too large'] = 'Hochgeladene Datei ist zu groß';
+$a->strings['File has an invalid extension, it should be one of '] = 'Die Dateiextension ist nicht erlaubt, sie muss eine der folgenden sein ';
+$a->strings['Upload was cancelled, or server error encountered'] = 'Upload abgebrochen oder Serverfehler aufgetreten';
+$a->strings['Randplace Settings'] = 'Randplace Settings';
+$a->strings['Enable Randplace Plugin'] = 'Randplace Erweiterung aktivieren';
+$a->strings['Africa/Abidjan'] = 'Africa/Abidjan';
+$a->strings['Africa/Accra'] = 'Africa/Accra';
+$a->strings['Africa/Addis_Ababa'] = 'Africa/Addis_Ababa';
+$a->strings['Africa/Algiers'] = 'Africa/Algiers';
+$a->strings['Africa/Asmara'] = 'Africa/Asmara';
+$a->strings['Africa/Asmera'] = 'Africa/Asmera';
+$a->strings['Africa/Bamako'] = 'Africa/Bamako';
+$a->strings['Africa/Bangui'] = 'Africa/Bangui';
+$a->strings['Africa/Banjul'] = 'Africa/Banjul';
+$a->strings['Africa/Bissau'] = 'Africa/Bissau';
+$a->strings['Africa/Blantyre'] = 'Africa/Blantyre';
+$a->strings['Africa/Brazzaville'] = 'Africa/Brazzaville';
+$a->strings['Africa/Bujumbura'] = 'Africa/Bujumbura';
+$a->strings['Africa/Cairo'] = 'Africa/Cairo';
+$a->strings['Africa/Casablanca'] = 'Africa/Casablanca';
+$a->strings['Africa/Ceuta'] = 'Africa/Ceuta';
+$a->strings['Africa/Conakry'] = 'Africa/Conakry';
+$a->strings['Africa/Dakar'] = 'Africa/Dakar';
+$a->strings['Africa/Dar_es_Salaam'] = 'Africa/Dar_es_Salaam';
+$a->strings['Africa/Djibouti'] = 'Africa/Djibouti';
+$a->strings['Africa/Douala'] = 'Africa/Douala';
+$a->strings['Africa/El_Aaiun'] = 'Africa/El_Aaiun';
+$a->strings['Africa/Freetown'] = 'Africa/Freetown';
+$a->strings['Africa/Gaborone'] = 'Africa/Gaborone';
+$a->strings['Africa/Harare'] = 'Africa/Harare';
+$a->strings['Africa/Johannesburg'] = 'Africa/Johannesburg';
+$a->strings['Africa/Kampala'] = 'Africa/Kampala';
+$a->strings['Africa/Khartoum'] = 'Africa/Khartoum';
+$a->strings['Africa/Kigali'] = 'Africa/Kigali';
+$a->strings['Africa/Kinshasa'] = 'Africa/Kinshasa';
+$a->strings['Africa/Lagos'] = 'Africa/Lagos';
+$a->strings['Africa/Libreville'] = 'Africa/Libreville';
+$a->strings['Africa/Lome'] = 'Africa/Lome';
+$a->strings['Africa/Luanda'] = 'Africa/Luanda';
+$a->strings['Africa/Lubumbashi'] = 'Africa/Lubumbashi';
+$a->strings['Africa/Lusaka'] = 'Africa/Lusaka';
+$a->strings['Africa/Malabo'] = 'Africa/Malabo';
+$a->strings['Africa/Maputo'] = 'Africa/Maputo';
+$a->strings['Africa/Maseru'] = 'Africa/Maseru';
+$a->strings['Africa/Mbabane'] = 'Africa/Mbabane';
+$a->strings['Africa/Mogadishu'] = 'Africa/Mogadishu';
+$a->strings['Africa/Monrovia'] = 'Africa/Monrovia';
+$a->strings['Africa/Nairobi'] = 'Africa/Nairobi';
+$a->strings['Africa/Ndjamena'] = 'Africa/Ndjamena';
+$a->strings['Africa/Niamey'] = 'Africa/Niamey';
+$a->strings['Africa/Nouakchott'] = 'Africa/Nouakchott';
+$a->strings['Africa/Ouagadougou'] = 'Africa/Ouagadougou';
+$a->strings['Africa/Porto-Novo'] = 'Africa/Porto-Novo';
+$a->strings['Africa/Sao_Tome'] = 'Africa/Sao_Tome';
+$a->strings['Africa/Timbuktu'] = 'Africa/Timbuktu';
+$a->strings['Africa/Tripoli'] = 'Africa/Tripoli';
+$a->strings['Africa/Tunis'] = 'Africa/Tunis';
+$a->strings['Africa/Windhoek'] = 'Africa/Windhoek';
+$a->strings['America/Adak'] = 'America/Adak';
+$a->strings['America/Anchorage'] = 'America/Anchorage';
+$a->strings['America/Anguilla'] = 'America/Anguilla';
+$a->strings['America/Antigua'] = 'America/Antigua';
+$a->strings['America/Araguaina'] = 'America/Araguaina';
+$a->strings['America/Argentina/Buenos_Aires'] = 'America/Argentina/Buenos_Aires';
+$a->strings['America/Argentina/Catamarca'] = 'America/Argentina/Catamarca';
+$a->strings['America/Argentina/ComodRivadavia'] = 'America/Argentina/ComodRivadavia';
+$a->strings['America/Argentina/Cordoba'] = 'America/Argentina/Cordoba';
+$a->strings['America/Argentina/Jujuy'] = 'America/Argentina/Jujuy';
+$a->strings['America/Argentina/La_Rioja'] = 'America/Argentina/La_Rioja';
+$a->strings['America/Argentina/Mendoza'] = 'America/Argentina/Mendoza';
+$a->strings['America/Argentina/Rio_Gallegos'] = 'America/Argentina/Rio_Gallegos';
+$a->strings['America/Argentina/Salta'] = 'America/Argentina/Salta';
+$a->strings['America/Argentina/San_Juan'] = 'America/Argentina/San_Juan';
+$a->strings['America/Argentina/San_Luis'] = 'America/Argentina/San_Luis';
+$a->strings['America/Argentina/Tucuman'] = 'America/Argentina/Tucuman';
+$a->strings['America/Argentina/Ushuaia'] = 'America/Argentina/Ushuaia';
+$a->strings['America/Aruba'] = 'America/Aruba';
+$a->strings['America/Asuncion'] = 'America/Asuncion';
+$a->strings['America/Atikokan'] = 'America/Atikokan';
+$a->strings['America/Atka'] = 'America/Atka';
+$a->strings['America/Bahia'] = 'America/Bahia';
+$a->strings['America/Barbados'] = 'America/Barbados';
+$a->strings['America/Belem'] = 'America/Belem';
+$a->strings['America/Belize'] = 'America/Belize';
+$a->strings['America/Blanc-Sablon'] = 'America/Blanc-Sablon';
+$a->strings['America/Boa_Vista'] = 'America/Boa_Vista';
+$a->strings['America/Bogota'] = 'America/Bogota';
+$a->strings['America/Boise'] = 'America/Boise';
+$a->strings['America/Buenos_Aires'] = 'America/Buenos_Aires';
+$a->strings['America/Cambridge_Bay'] = 'America/Cambridge_Bay';
+$a->strings['America/Campo_Grande'] = 'America/Campo_Grande';
+$a->strings['America/Cancun'] = 'America/Cancun';
+$a->strings['America/Caracas'] = 'America/Caracas';
+$a->strings['America/Catamarca'] = 'America/Catamarca';
+$a->strings['America/Cayenne'] = 'America/Cayenne';
+$a->strings['America/Cayman'] = 'America/Cayman';
+$a->strings['America/Chicago'] = 'America/Chicago';
+$a->strings['America/Chihuahua'] = 'America/Chihuahua';
+$a->strings['America/Coral_Harbour'] = 'America/Coral_Harbour';
+$a->strings['America/Cordoba'] = 'America/Cordoba';
+$a->strings['America/Costa_Rica'] = 'America/Costa_Rica';
+$a->strings['America/Cuiaba'] = 'America/Cuiaba';
+$a->strings['America/Curacao'] = 'America/Curacao';
+$a->strings['America/Danmarkshavn'] = 'America/Danmarkshavn';
+$a->strings['America/Dawson'] = 'America/Dawson';
+$a->strings['America/Dawson_Creek'] = 'America/Dawson_Creek';
+$a->strings['America/Denver'] = 'America/Denver';
+$a->strings['America/Detroit'] = 'America/Detroit';
+$a->strings['America/Dominica'] = 'America/Dominica';
+$a->strings['America/Edmonton'] = 'America/Edmonton';
+$a->strings['America/Eirunepe'] = 'America/Eirunepe';
+$a->strings['America/El_Salvador'] = 'America/El_Salvador';
+$a->strings['America/Ensenada'] = 'America/Ensenada';
+$a->strings['America/Fort_Wayne'] = 'America/Fort_Wayne';
+$a->strings['America/Fortaleza'] = 'America/Fortaleza';
+$a->strings['America/Glace_Bay'] = 'America/Glace_Bay';
+$a->strings['America/Godthab'] = 'America/Godthab';
+$a->strings['America/Goose_Bay'] = 'America/Goose_Bay';
+$a->strings['America/Grand_Turk'] = 'America/Grand_Turk';
+$a->strings['America/Grenada'] = 'America/Grenada';
+$a->strings['America/Guadeloupe'] = 'America/Guadeloupe';
+$a->strings['America/Guatemala'] = 'America/Guatemala';
+$a->strings['America/Guayaquil'] = 'America/Guayaquil';
+$a->strings['America/Guyana'] = 'America/Guyana';
+$a->strings['America/Halifax'] = 'America/Halifax';
+$a->strings['America/Havana'] = 'America/Havana';
+$a->strings['America/Hermosillo'] = 'America/Hermosillo';
+$a->strings['America/Indiana/Indianapolis'] = 'America/Indiana/Indianapolis';
+$a->strings['America/Indiana/Knox'] = 'America/Indiana/Knox';
+$a->strings['America/Indiana/Marengo'] = 'America/Indiana/Marengo';
+$a->strings['America/Indiana/Petersburg'] = 'America/Indiana/Petersburg';
+$a->strings['America/Indiana/Tell_City'] = 'America/Indiana/Tell_City';
+$a->strings['America/Indiana/Vevay'] = 'America/Indiana/Vevay';
+$a->strings['America/Indiana/Vincennes'] = 'America/Indiana/Vincennes';
+$a->strings['America/Indiana/Winamac'] = 'America/Indiana/Winamac';
+$a->strings['America/Indianapolis'] = 'America/Indianapolis';
+$a->strings['America/Inuvik'] = 'America/Inuvik';
+$a->strings['America/Iqaluit'] = 'America/Iqaluit';
+$a->strings['America/Jamaica'] = 'America/Jamaica';
+$a->strings['America/Jujuy'] = 'America/Jujuy';
+$a->strings['America/Juneau'] = 'America/Juneau';
+$a->strings['America/Kentucky/Louisville'] = 'America/Kentucky/Louisville';
+$a->strings['America/Kentucky/Monticello'] = 'America/Kentucky/Monticello';
+$a->strings['America/Knox_IN'] = 'America/Knox_IN';
+$a->strings['America/La_Paz'] = 'America/La_Paz';
+$a->strings['America/Lima'] = 'America/Lima';
+$a->strings['America/Los_Angeles'] = 'America/Los_Angeles';
+$a->strings['America/Louisville'] = 'America/Louisville';
+$a->strings['America/Maceio'] = 'America/Maceio';
+$a->strings['America/Managua'] = 'America/Managua';
+$a->strings['America/Manaus'] = 'America/Manaus';
+$a->strings['America/Marigot'] = 'America/Marigot';
+$a->strings['America/Martinique'] = 'America/Martinique';
+$a->strings['America/Matamoros'] = 'America/Matamoros';
+$a->strings['America/Mazatlan'] = 'America/Mazatlan';
+$a->strings['America/Mendoza'] = 'America/Mendoza';
+$a->strings['America/Menominee'] = 'America/Menominee';
+$a->strings['America/Merida'] = 'America/Merida';
+$a->strings['America/Mexico_City'] = 'America/Mexico_City';
+$a->strings['America/Miquelon'] = 'America/Miquelon';
+$a->strings['America/Moncton'] = 'America/Moncton';
+$a->strings['America/Monterrey'] = 'America/Monterrey';
+$a->strings['America/Montevideo'] = 'America/Montevideo';
+$a->strings['America/Montreal'] = 'America/Montreal';
+$a->strings['America/Montserrat'] = 'America/Montserrat';
+$a->strings['America/Nassau'] = 'America/Nassau';
+$a->strings['America/New_York'] = 'America/New_York';
+$a->strings['America/Nipigon'] = 'America/Nipigon';
+$a->strings['America/Nome'] = 'America/Nome';
+$a->strings['America/Noronha'] = 'America/Noronha';
+$a->strings['America/North_Dakota/Center'] = 'America/North_Dakota/Center';
+$a->strings['America/North_Dakota/New_Salem'] = 'America/North_Dakota/New_Salem';
+$a->strings['America/Ojinaga'] = 'America/Ojinaga';
+$a->strings['America/Panama'] = 'America/Panama';
+$a->strings['America/Pangnirtung'] = 'America/Pangnirtung';
+$a->strings['America/Paramaribo'] = 'America/Paramaribo';
+$a->strings['America/Phoenix'] = 'America/Phoenix';
+$a->strings['America/Port-au-Prince'] = 'America/Port-au-Prince';
+$a->strings['America/Port_of_Spain'] = 'America/Port_of_Spain';
+$a->strings['America/Porto_Acre'] = 'America/Porto_Acre';
+$a->strings['America/Porto_Velho'] = 'America/Porto_Velho';
+$a->strings['America/Puerto_Rico'] = 'America/Puerto_Rico';
+$a->strings['America/Rainy_River'] = 'America/Rainy_River';
+$a->strings['America/Rankin_Inlet'] = 'America/Rankin_Inlet';
+$a->strings['America/Recife'] = 'America/Recife';
+$a->strings['America/Regina'] = 'America/Regina';
+$a->strings['America/Resolute'] = 'America/Resolute';
+$a->strings['America/Rio_Branco'] = 'America/Rio_Branco';
+$a->strings['America/Rosario'] = 'America/Rosario';
+$a->strings['America/Santa_Isabel'] = 'America/Santa_Isabel';
+$a->strings['America/Santarem'] = 'America/Santarem';
+$a->strings['America/Santiago'] = 'America/Santiago';
+$a->strings['America/Santo_Domingo'] = 'America/Santo_Domingo';
+$a->strings['America/Sao_Paulo'] = 'America/Sao_Paulo';
+$a->strings['America/Scoresbysund'] = 'America/Scoresbysund';
+$a->strings['America/Shiprock'] = 'America/Shiprock';
+$a->strings['America/St_Barthelemy'] = 'America/St_Barthelemy';
+$a->strings['America/St_Johns'] = 'America/St_Johns';
+$a->strings['America/St_Kitts'] = 'America/St_Kitts';
+$a->strings['America/St_Lucia'] = 'America/St_Lucia';
+$a->strings['America/St_Thomas'] = 'America/St_Thomas';
+$a->strings['America/St_Vincent'] = 'America/St_Vincent';
+$a->strings['America/Swift_Current'] = 'America/Swift_Current';
+$a->strings['America/Tegucigalpa'] = 'America/Tegucigalpa';
+$a->strings['America/Thule'] = 'America/Thule';
+$a->strings['America/Thunder_Bay'] = 'America/Thunder_Bay';
+$a->strings['America/Tijuana'] = 'America/Tijuana';
+$a->strings['America/Toronto'] = 'America/Toronto';
+$a->strings['America/Tortola'] = 'America/Tortola';
+$a->strings['America/Vancouver'] = 'America/Vancouver';
+$a->strings['America/Virgin'] = 'America/Virgin';
+$a->strings['America/Whitehorse'] = 'America/Whitehorse';
+$a->strings['America/Winnipeg'] = 'America/Winnipeg';
+$a->strings['America/Yakutat'] = 'America/Yakutat';
+$a->strings['America/Yellowknife'] = 'America/Yellowknife';
+$a->strings['Antarctica/Casey'] = 'Antarctica/Casey';
+$a->strings['Antarctica/Davis'] = 'Antarctica/Davis';
+$a->strings['Antarctica/DumontDUrville'] = 'Antarctica/DumontDUrville';
+$a->strings['Antarctica/Macquarie'] = 'Antarctica/Macquarie';
+$a->strings['Antarctica/Mawson'] = 'Antarctica/Mawson';
+$a->strings['Antarctica/McMurdo'] = 'Antarctica/McMurdo';
+$a->strings['Antarctica/Palmer'] = 'Antarctica/Palmer';
+$a->strings['Antarctica/Rothera'] = 'Antarctica/Rothera';
+$a->strings['Antarctica/South_Pole'] = 'Antarctica/South_Pole';
+$a->strings['Antarctica/Syowa'] = 'Antarctica/Syowa';
+$a->strings['Antarctica/Vostok'] = 'Antarctica/Vostok';
+$a->strings['Arctic/Longyearbyen'] = 'Arctic/Longyearbyen';
+$a->strings['Asia/Aden'] = 'Asia/Aden';
+$a->strings['Asia/Almaty'] = 'Asia/Almaty';
+$a->strings['Asia/Amman'] = 'Asia/Amman';
+$a->strings['Asia/Anadyr'] = 'Asia/Anadyr';
+$a->strings['Asia/Aqtau'] = 'Asia/Aqtau';
+$a->strings['Asia/Aqtobe'] = 'Asia/Aqtobe';
+$a->strings['Asia/Ashgabat'] = 'Asia/Ashgabat';
+$a->strings['Asia/Ashkhabad'] = 'Asia/Ashkhabad';
+$a->strings['Asia/Baghdad'] = 'Asia/Baghdad';
+$a->strings['Asia/Bahrain'] = 'Asia/Bahrain';
+$a->strings['Asia/Baku'] = 'Asia/Baku';
+$a->strings['Asia/Bangkok'] = 'Asia/Bangkok';
+$a->strings['Asia/Beirut'] = 'Asia/Beirut';
+$a->strings['Asia/Bishkek'] = 'Asia/Bishkek';
+$a->strings['Asia/Brunei'] = 'Asia/Brunei';
+$a->strings['Asia/Calcutta'] = 'Asia/Calcutta';
+$a->strings['Asia/Choibalsan'] = 'Asia/Choibalsan';
+$a->strings['Asia/Chongqing'] = 'Asia/Chongqing';
+$a->strings['Asia/Chungking'] = 'Asia/Chungking';
+$a->strings['Asia/Colombo'] = 'Asia/Colombo';
+$a->strings['Asia/Dacca'] = 'Asia/Dacca';
+$a->strings['Asia/Damascus'] = 'Asia/Damascus';
+$a->strings['Asia/Dhaka'] = 'Asia/Dhaka';
+$a->strings['Asia/Dili'] = 'Asia/Dili';
+$a->strings['Asia/Dubai'] = 'Asia/Dubai';
+$a->strings['Asia/Dushanbe'] = 'Asia/Dushanbe';
+$a->strings['Asia/Gaza'] = 'Asia/Gaza';
+$a->strings['Asia/Harbin'] = 'Asia/Harbin';
+$a->strings['Asia/Ho_Chi_Minh'] = 'Asia/Ho_Chi_Minh';
+$a->strings['Asia/Hong_Kong'] = 'Asia/Hong_Kong';
+$a->strings['Asia/Hovd'] = 'Asia/Hovd';
+$a->strings['Asia/Irkutsk'] = 'Asia/Irkutsk';
+$a->strings['Asia/Istanbul'] = 'Asia/Istanbul';
+$a->strings['Asia/Jakarta'] = 'Asia/Jakarta';
+$a->strings['Asia/Jayapura'] = 'Asia/Jayapura';
+$a->strings['Asia/Jerusalem'] = 'Asia/Jerusalem';
+$a->strings['Asia/Kabul'] = 'Asia/Kabul';
+$a->strings['Asia/Kamchatka'] = 'Asia/Kamchatka';
+$a->strings['Asia/Karachi'] = 'Asia/Karachi';
+$a->strings['Asia/Kashgar'] = 'Asia/Kashgar';
+$a->strings['Asia/Kathmandu'] = 'Asia/Kathmandu';
+$a->strings['Asia/Katmandu'] = 'Asia/Katmandu';
+$a->strings['Asia/Kolkata'] = 'Asia/Kolkata';
+$a->strings['Asia/Krasnoyarsk'] = 'Asia/Krasnoyarsk';
+$a->strings['Asia/Kuala_Lumpur'] = 'Asia/Kuala_Lumpur';
+$a->strings['Asia/Kuching'] = 'Asia/Kuching';
+$a->strings['Asia/Kuwait'] = 'Asia/Kuwait';
+$a->strings['Asia/Macao'] = 'Asia/Macao';
+$a->strings['Asia/Macau'] = 'Asia/Macau';
+$a->strings['Asia/Magadan'] = 'Asia/Magadan';
+$a->strings['Asia/Makassar'] = 'Asia/Makassar';
+$a->strings['Asia/Manila'] = 'Asia/Manila';
+$a->strings['Asia/Muscat'] = 'Asia/Muscat';
+$a->strings['Asia/Nicosia'] = 'Asia/Nicosia';
+$a->strings['Asia/Novokuznetsk'] = 'Asia/Novokuznetsk';
+$a->strings['Asia/Novosibirsk'] = 'Asia/Novosibirsk';
+$a->strings['Asia/Omsk'] = 'Asia/Omsk';
+$a->strings['Asia/Oral'] = 'Asia/Oral';
+$a->strings['Asia/Phnom_Penh'] = 'Asia/Phnom_Penh';
+$a->strings['Asia/Pontianak'] = 'Asia/Pontianak';
+$a->strings['Asia/Pyongyang'] = 'Asia/Pyongyang';
+$a->strings['Asia/Qatar'] = 'Asia/Qatar';
+$a->strings['Asia/Qyzylorda'] = 'Asia/Qyzylorda';
+$a->strings['Asia/Rangoon'] = 'Asia/Rangoon';
+$a->strings['Asia/Riyadh'] = 'Asia/Riyadh';
+$a->strings['Asia/Saigon'] = 'Asia/Saigon';
+$a->strings['Asia/Sakhalin'] = 'Asia/Sakhalin';
+$a->strings['Asia/Samarkand'] = 'Asia/Samarkand';
+$a->strings['Asia/Seoul'] = 'Asia/Seoul';
+$a->strings['Asia/Shanghai'] = 'Asia/Shanghai';
+$a->strings['Asia/Singapore'] = 'Asia/Singapore';
+$a->strings['Asia/Taipei'] = 'Asia/Taipei';
+$a->strings['Asia/Tashkent'] = 'Asia/Tashkent';
+$a->strings['Asia/Tbilisi'] = 'Asia/Tbilisi';
+$a->strings['Asia/Tehran'] = 'Asia/Tehran';
+$a->strings['Asia/Tel_Aviv'] = 'Asia/Tel_Aviv';
+$a->strings['Asia/Thimbu'] = 'Asia/Thimbu';
+$a->strings['Asia/Thimphu'] = 'Asia/Thimphu';
+$a->strings['Asia/Tokyo'] = 'Asia/Tokyo';
+$a->strings['Asia/Ujung_Pandang'] = 'Asia/Ujung_Pandang';
+$a->strings['Asia/Ulaanbaatar'] = 'Asia/Ulaanbaatar';
+$a->strings['Asia/Ulan_Bator'] = 'Asia/Ulan_Bator';
+$a->strings['Asia/Urumqi'] = 'Asia/Urumqi';
+$a->strings['Asia/Vientiane'] = 'Asia/Vientiane';
+$a->strings['Asia/Vladivostok'] = 'Asia/Vladivostok';
+$a->strings['Asia/Yakutsk'] = 'Asia/Yakutsk';
+$a->strings['Asia/Yekaterinburg'] = 'Asia/Yekaterinburg';
+$a->strings['Asia/Yerevan'] = 'Asia/Yerevan';
+$a->strings['Atlantic/Azores'] = 'Atlantic/Azores';
+$a->strings['Atlantic/Bermuda'] = 'Atlantic/Bermuda';
+$a->strings['Atlantic/Canary'] = 'Atlantic/Canary';
+$a->strings['Atlantic/Cape_Verde'] = 'Atlantic/Cape_Verde';
+$a->strings['Atlantic/Faeroe'] = 'Atlantic/Faeroe';
+$a->strings['Atlantic/Faroe'] = 'Atlantic/Faroe';
+$a->strings['Atlantic/Jan_Mayen'] = 'Atlantic/Jan_Mayen';
+$a->strings['Atlantic/Madeira'] = 'Atlantic/Madeira';
+$a->strings['Atlantic/Reykjavik'] = 'Atlantic/Reykjavik';
+$a->strings['Atlantic/South_Georgia'] = 'Atlantic/South_Georgia';
+$a->strings['Atlantic/St_Helena'] = 'Atlantic/St_Helena';
+$a->strings['Atlantic/Stanley'] = 'Atlantic/Stanley';
+$a->strings['Australia/ACT'] = 'Australia/ACT';
+$a->strings['Australia/Adelaide'] = 'Australia/Adelaide';
+$a->strings['Australia/Brisbane'] = 'Australia/Brisbane';
+$a->strings['Australia/Broken_Hill'] = 'Australia/Broken_Hill';
+$a->strings['Australia/Canberra'] = 'Australia/Canberra';
+$a->strings['Australia/Currie'] = 'Australia/Currie';
+$a->strings['Australia/Darwin'] = 'Australia/Darwin';
+$a->strings['Australia/Eucla'] = 'Australia/Eucla';
+$a->strings['Australia/Hobart'] = 'Australia/Hobart';
+$a->strings['Australia/LHI'] = 'Australia/LHI';
+$a->strings['Australia/Lindeman'] = 'Australia/Lindeman';
+$a->strings['Australia/Lord_Howe'] = 'Australia/Lord_Howe';
+$a->strings['Australia/Melbourne'] = 'Australia/Melbourne';
+$a->strings['Australia/North'] = 'Australia/North';
+$a->strings['Australia/NSW'] = 'Australia/NSW';
+$a->strings['Australia/Perth'] = 'Australia/Perth';
+$a->strings['Australia/Queensland'] = 'Australia/Queensland';
+$a->strings['Australia/South'] = 'Australia/South';
+$a->strings['Australia/Sydney'] = 'Australia/Sydney';
+$a->strings['Australia/Tasmania'] = 'Australia/Tasmania';
+$a->strings['Australia/Victoria'] = 'Australia/Victoria';
+$a->strings['Australia/West'] = 'Australia/West';
+$a->strings['Australia/Yancowinna'] = 'Australia/Yancowinna';
+$a->strings['Brazil/Acre'] = 'Brazil/Acre';
+$a->strings['Brazil/DeNoronha'] = 'Brazil/DeNoronha';
+$a->strings['Brazil/East'] = 'Brazil/East';
+$a->strings['Brazil/West'] = 'Brazil/West';
+$a->strings['Canada/Atlantic'] = 'Canada/Atlantic';
+$a->strings['Canada/Central'] = 'Canada/Central';
+$a->strings['Canada/East-Saskatchewan'] = 'Canada/East-Saskatchewan';
+$a->strings['Canada/Eastern'] = 'Canada/Eastern';
+$a->strings['Canada/Mountain'] = 'Canada/Mountain';
+$a->strings['Canada/Newfoundland'] = 'Canada/Newfoundland';
+$a->strings['Canada/Pacific'] = 'Canada/Pacific';
+$a->strings['Canada/Saskatchewan'] = 'Canada/Saskatchewan';
+$a->strings['Canada/Yukon'] = 'Canada/Yukon';
+$a->strings['CET'] = 'CET';
+$a->strings['Chile/Continental'] = 'Chile/Continental';
+$a->strings['Chile/EasterIsland'] = 'Chile/EasterIsland';
+$a->strings['CST6CDT'] = 'CST6CDT';
+$a->strings['Cuba'] = 'Cuba';
+$a->strings['EET'] = 'EET';
+$a->strings['Egypt'] = 'Egypt';
+$a->strings['Eire'] = 'Eire';
+$a->strings['EST'] = 'EST';
+$a->strings['EST5EDT'] = 'EST5EDT';
+$a->strings['Etc/GMT'] = 'Etc/GMT';
+$a->strings['Etc/GMT+0'] = 'Etc/GMT+0';
+$a->strings['Etc/GMT+1'] = 'Etc/GMT+1';
+$a->strings['Etc/GMT+10'] = 'Etc/GMT+10';
+$a->strings['Etc/GMT+11'] = 'Etc/GMT+11';
+$a->strings['Etc/GMT+12'] = 'Etc/GMT+12';
+$a->strings['Etc/GMT+2'] = 'Etc/GMT+2';
+$a->strings['Etc/GMT+3'] = 'Etc/GMT+3';
+$a->strings['Etc/GMT+4'] = 'Etc/GMT+4';
+$a->strings['Etc/GMT+5'] = 'Etc/GMT+5';
+$a->strings['Etc/GMT+6'] = 'Etc/GMT+6';
+$a->strings['Etc/GMT+7'] = 'Etc/GMT+7';
+$a->strings['Etc/GMT+8'] = 'Etc/GMT+8';
+$a->strings['Etc/GMT+9'] = 'Etc/GMT+9';
+$a->strings['Etc/GMT-0'] = 'Etc/GMT-0';
+$a->strings['Etc/GMT-1'] = 'Etc/GMT-1';
+$a->strings['Etc/GMT-10'] = 'Etc/GMT-10';
+$a->strings['Etc/GMT-11'] = 'Etc/GMT-11';
+$a->strings['Etc/GMT-12'] = 'Etc/GMT-12';
+$a->strings['Etc/GMT-13'] = 'Etc/GMT-13';
+$a->strings['Etc/GMT-14'] = 'Etc/GMT-14';
+$a->strings['Etc/GMT-2'] = 'Etc/GMT-2';
+$a->strings['Etc/GMT-3'] = 'Etc/GMT-3';
+$a->strings['Etc/GMT-4'] = 'Etc/GMT-4';
+$a->strings['Etc/GMT-5'] = 'Etc/GMT-5';
+$a->strings['Etc/GMT-6'] = 'Etc/GMT-6';
+$a->strings['Etc/GMT-7'] = 'Etc/GMT-7';
+$a->strings['Etc/GMT-8'] = 'Etc/GMT-8';
+$a->strings['Etc/GMT-9'] = 'Etc/GMT-9';
+$a->strings['Etc/GMT0'] = 'Etc/GMT0';
+$a->strings['Etc/Greenwich'] = 'Etc/Greenwich';
+$a->strings['Etc/UCT'] = 'Etc/UCT';
+$a->strings['Etc/Universal'] = 'Etc/Universal';
+$a->strings['Etc/UTC'] = 'Etc/UTC';
+$a->strings['Etc/Zulu'] = 'Etc/Zulu';
+$a->strings['Europe/Amsterdam'] = 'Europe/Amsterdam';
+$a->strings['Europe/Andorra'] = 'Europe/Andorra';
+$a->strings['Europe/Athens'] = 'Europe/Athens';
+$a->strings['Europe/Belfast'] = 'Europe/Belfast';
+$a->strings['Europe/Belgrade'] = 'Europe/Belgrade';
+$a->strings['Europe/Berlin'] = 'Europe/Berlin';
+$a->strings['Europe/Bratislava'] = 'Europe/Bratislava';
+$a->strings['Europe/Brussels'] = 'Europe/Brussels';
+$a->strings['Europe/Bucharest'] = 'Europe/Bucharest';
+$a->strings['Europe/Budapest'] = 'Europe/Budapest';
+$a->strings['Europe/Chisinau'] = 'Europe/Chisinau';
+$a->strings['Europe/Copenhagen'] = 'Europe/Copenhagen';
+$a->strings['Europe/Dublin'] = 'Europe/Dublin';
+$a->strings['Europe/Gibraltar'] = 'Europe/Gibraltar';
+$a->strings['Europe/Guernsey'] = 'Europe/Guernsey';
+$a->strings['Europe/Helsinki'] = 'Europe/Helsinki';
+$a->strings['Europe/Isle_of_Man'] = 'Europe/Isle_of_Man';
+$a->strings['Europe/Istanbul'] = 'Europe/Istanbul';
+$a->strings['Europe/Jersey'] = 'Europe/Jersey';
+$a->strings['Europe/Kaliningrad'] = 'Europe/Kaliningrad';
+$a->strings['Europe/Kiev'] = 'Europe/Kiev';
+$a->strings['Europe/Lisbon'] = 'Europe/Lisbon';
+$a->strings['Europe/Ljubljana'] = 'Europe/Ljubljana';
+$a->strings['Europe/London'] = 'Europe/London';
+$a->strings['Europe/Luxembourg'] = 'Europe/Luxembourg';
+$a->strings['Europe/Madrid'] = 'Europe/Madrid';
+$a->strings['Europe/Malta'] = 'Europe/Malta';
+$a->strings['Europe/Mariehamn'] = 'Europe/Mariehamn';
+$a->strings['Europe/Minsk'] = 'Europe/Minsk';
+$a->strings['Europe/Monaco'] = 'Europe/Monaco';
+$a->strings['Europe/Moscow'] = 'Europe/Moscow';
+$a->strings['Europe/Nicosia'] = 'Europe/Nicosia';
+$a->strings['Europe/Oslo'] = 'Europe/Oslo';
+$a->strings['Europe/Paris'] = 'Europe/Paris';
+$a->strings['Europe/Podgorica'] = 'Europe/Podgorica';
+$a->strings['Europe/Prague'] = 'Europe/Prague';
+$a->strings['Europe/Riga'] = 'Europe/Riga';
+$a->strings['Europe/Rome'] = 'Europe/Rome';
+$a->strings['Europe/Samara'] = 'Europe/Samara';
+$a->strings['Europe/San_Marino'] = 'Europe/San_Marino';
+$a->strings['Europe/Sarajevo'] = 'Europe/Sarajevo';
+$a->strings['Europe/Simferopol'] = 'Europe/Simferopol';
+$a->strings['Europe/Skopje'] = 'Europe/Skopje';
+$a->strings['Europe/Sofia'] = 'Europe/Sofia';
+$a->strings['Europe/Stockholm'] = 'Europe/Stockholm';
+$a->strings['Europe/Tallinn'] = 'Europe/Tallinn';
+$a->strings['Europe/Tirane'] = 'Europe/Tirane';
+$a->strings['Europe/Tiraspol'] = 'Europe/Tiraspol';
+$a->strings['Europe/Uzhgorod'] = 'Europe/Uzhgorod';
+$a->strings['Europe/Vaduz'] = 'Europe/Vaduz';
+$a->strings['Europe/Vatican'] = 'Europe/Vatican';
+$a->strings['Europe/Vienna'] = 'Europe/Vienna';
+$a->strings['Europe/Vilnius'] = 'Europe/Vilnius';
+$a->strings['Europe/Volgograd'] = 'Europe/Volgograd';
+$a->strings['Europe/Warsaw'] = 'Europe/Warsaw';
+$a->strings['Europe/Zagreb'] = 'Europe/Zagreb';
+$a->strings['Europe/Zaporozhye'] = 'Europe/Zaporozhye';
+$a->strings['Europe/Zurich'] = 'Europe/Zurich';
+$a->strings['Factory'] = 'Factory';
+$a->strings['GB'] = 'GB';
+$a->strings['GB-Eire'] = 'GB-Eire';
+$a->strings['GMT'] = 'GMT';
+$a->strings['GMT+0'] = 'GMT+0';
+$a->strings['GMT-0'] = 'GMT-0';
+$a->strings['GMT0'] = 'GMT0';
+$a->strings['Greenwich'] = 'Greenwich';
+$a->strings['Hongkong'] = 'Hongkong';
+$a->strings['HST'] = 'HST';
+$a->strings['Iceland'] = 'Iceland';
+$a->strings['Indian/Antananarivo'] = 'Indian/Antananarivo';
+$a->strings['Indian/Chagos'] = 'Indian/Chagos';
+$a->strings['Indian/Christmas'] = 'Indian/Christmas';
+$a->strings['Indian/Cocos'] = 'Indian/Cocos';
+$a->strings['Indian/Comoro'] = 'Indian/Comoro';
+$a->strings['Indian/Kerguelen'] = 'Indian/Kerguelen';
+$a->strings['Indian/Mahe'] = 'Indian/Mahe';
+$a->strings['Indian/Maldives'] = 'Indian/Maldives';
+$a->strings['Indian/Mauritius'] = 'Indian/Mauritius';
+$a->strings['Indian/Mayotte'] = 'Indian/Mayotte';
+$a->strings['Indian/Reunion'] = 'Indian/Reunion';
+$a->strings['Iran'] = 'Iran';
+$a->strings['Israel'] = 'Israel';
+$a->strings['Jamaica'] = 'Jamaica';
+$a->strings['Japan'] = 'Japan';
+$a->strings['Kwajalein'] = 'Kwajalein';
+$a->strings['Libya'] = 'Libya';
+$a->strings['MET'] = 'MET';
+$a->strings['Mexico/BajaNorte'] = 'Mexico/BajaNorte';
+$a->strings['Mexico/BajaSur'] = 'Mexico/BajaSur';
+$a->strings['Mexico/General'] = 'Mexico/General';
+$a->strings['MST'] = 'MST';
+$a->strings['MST7MDT'] = 'MST7MDT';
+$a->strings['Navajo'] = 'Navajo';
+$a->strings['NZ'] = 'NZ';
+$a->strings['NZ-CHAT'] = 'NZ-CHAT';
+$a->strings['Pacific/Apia'] = 'Pacific/Apia';
+$a->strings['Pacific/Auckland'] = 'Pacific/Auckland';
+$a->strings['Pacific/Chatham'] = 'Pacific/Chatham';
+$a->strings['Pacific/Easter'] = 'Pacific/Easter';
+$a->strings['Pacific/Efate'] = 'Pacific/Efate';
+$a->strings['Pacific/Enderbury'] = 'Pacific/Enderbury';
+$a->strings['Pacific/Fakaofo'] = 'Pacific/Fakaofo';
+$a->strings['Pacific/Fiji'] = 'Pacific/Fiji';
+$a->strings['Pacific/Funafuti'] = 'Pacific/Funafuti';
+$a->strings['Pacific/Galapagos'] = 'Pacific/Galapagos';
+$a->strings['Pacific/Gambier'] = 'Pacific/Gambier';
+$a->strings['Pacific/Guadalcanal'] = 'Pacific/Guadalcanal';
+$a->strings['Pacific/Guam'] = 'Pacific/Guam';
+$a->strings['Pacific/Honolulu'] = 'Pacific/Honolulu';
+$a->strings['Pacific/Johnston'] = 'Pacific/Johnston';
+$a->strings['Pacific/Kiritimati'] = 'Pacific/Kiritimati';
+$a->strings['Pacific/Kosrae'] = 'Pacific/Kosrae';
+$a->strings['Pacific/Kwajalein'] = 'Pacific/Kwajalein';
+$a->strings['Pacific/Majuro'] = 'Pacific/Majuro';
+$a->strings['Pacific/Marquesas'] = 'Pacific/Marquesas';
+$a->strings['Pacific/Midway'] = 'Pacific/Midway';
+$a->strings['Pacific/Nauru'] = 'Pacific/Nauru';
+$a->strings['Pacific/Niue'] = 'Pacific/Niue';
+$a->strings['Pacific/Norfolk'] = 'Pacific/Norfolk';
+$a->strings['Pacific/Noumea'] = 'Pacific/Noumea';
+$a->strings['Pacific/Pago_Pago'] = 'Pacific/Pago_Pago';
+$a->strings['Pacific/Palau'] = 'Pacific/Palau';
+$a->strings['Pacific/Pitcairn'] = 'Pacific/Pitcairn';
+$a->strings['Pacific/Ponape'] = 'Pacific/Ponape';
+$a->strings['Pacific/Port_Moresby'] = 'Pacific/Port_Moresby';
+$a->strings['Pacific/Rarotonga'] = 'Pacific/Rarotonga';
+$a->strings['Pacific/Saipan'] = 'Pacific/Saipan';
+$a->strings['Pacific/Samoa'] = 'Pacific/Samoa';
+$a->strings['Pacific/Tahiti'] = 'Pacific/Tahiti';
+$a->strings['Pacific/Tarawa'] = 'Pacific/Tarawa';
+$a->strings['Pacific/Tongatapu'] = 'Pacific/Tongatapu';
+$a->strings['Pacific/Truk'] = 'Pacific/Truk';
+$a->strings['Pacific/Wake'] = 'Pacific/Wake';
+$a->strings['Pacific/Wallis'] = 'Pacific/Wallis';
+$a->strings['Pacific/Yap'] = 'Pacific/Yap';
+$a->strings['Poland'] = 'Poland';
+$a->strings['Portugal'] = 'Portugal';
+$a->strings['PRC'] = 'PRC';
+$a->strings['PST8PDT'] = 'PST8PDT';
+$a->strings['ROC'] = 'ROC';
+$a->strings['ROK'] = 'ROK';
+$a->strings['Singapore'] = 'Singapore';
+$a->strings['Turkey'] = 'Turkey';
+$a->strings['UCT'] = 'UCT';
+$a->strings['Universal'] = 'Universal';
+$a->strings['US/Alaska'] = 'US/Alaska';
+$a->strings['US/Aleutian'] = 'US/Aleutian';
+$a->strings['US/Arizona'] = 'US/Arizona';
+$a->strings['US/Central'] = 'US/Central';
+$a->strings['US/East-Indiana'] = 'US/East-Indiana';
+$a->strings['US/Eastern'] = 'US/Eastern';
+$a->strings['US/Hawaii'] = 'US/Hawaii';
+$a->strings['US/Indiana-Starke'] = 'US/Indiana-Starke';
+$a->strings['US/Michigan'] = 'US/Michigan';
+$a->strings['US/Mountain'] = 'US/Mountain';
+$a->strings['US/Pacific'] = 'US/Pacific';
+$a->strings['US/Pacific-New'] = 'US/Pacific-New';
+$a->strings['US/Samoa'] = 'US/Samoa';
+$a->strings['UTC'] = 'UTC';
+$a->strings['W-SU'] = 'W-SU';
+$a->strings['WET'] = 'WET';
+$a->strings['Zulu'] = 'Zulu';
diff --git a/view/de/wall_item_drop.tpl b/view/de/wall_item_drop.tpl
new file mode 100644 (file)
index 0000000..7b267f3
--- /dev/null
@@ -0,0 +1,4 @@
+<div class="wall-item-delete-wrapper" id="wall-item-delete-wrapper-$id" ><a
+href="item/drop/$id" onclick="return confirmDelete();" ><img
+src="images/b_drophide.gif" alt="Löschen" title="Löschen" id="wall-item-delete-icon-$id" class="wall-item-delete-icon" onmouseover="imgbright(this);" onmouseout="imgdull(this);" ></a></div>
+               <div class="wall-item-delete-end"></div>
diff --git a/view/de/wall_received_eml.tpl b/view/de/wall_received_eml.tpl
new file mode 100644 (file)
index 0000000..b0ca45b
--- /dev/null
@@ -0,0 +1,18 @@
+
+Hallo $username,
+
+'$from' hat etwas auf deiner Profilwand gepostet.
+
+-----
+$body
+-----
+
+Bitte melde dich unter $siteurl an um den Eintrag anzusehen oder zu löschen.
+
+$display
+
+Besten Dank!
+        $sitename Administrator
+
+
diff --git a/view/de/wallwall_item.tpl b/view/de/wallwall_item.tpl
new file mode 100644 (file)
index 0000000..fd05a74
--- /dev/null
@@ -0,0 +1,36 @@
+<div class="wall-item-outside-wrapper$indent" id="wall-item-outside-wrapper-$id" >
+       <div class="wall-item-content-wrapper$indent" id="wall-item-content-wrapper-$id" >
+               <div class="wall-item-photo-wrapper" id="wall-item-ownerphoto-wrapper-$id" >
+                       <a href="$owner_url" title="Gehe zum Profil von $owner_name" class="wall-item-photo-link" id="wall-item-ownerphoto-link-$id">
+                       <img src="$owner_photo" class="wall-item-photo$osparkle" id="wall-item-ownerphoto-$id" height="80" width="80" alt="$owner_name" /></a>
+               </div>
+               <div class="wall-item-arrowphoto-wrapper" ><img src="images/larrow.gif" alt="Wall-To-Wall" /></div>
+               <div class="wall-item-photo-wrapper" id="wall-item-photo-wrapper-$id" >
+                       <a href="$profile_url" title="Betrachte das Profil von $name" class="wall-item-photo-link" id="wall-item-photo-link-$id">
+                       <img src="$thumb" class="wall-item-photo$sparkle" id="wall-item-photo-$id" height="80" width="80" alt="$name" /></a>
+               </div>
+       
+               <div class="wall-item-wrapper" id="wall-item-wrapper-$id" >
+                       $lock
+                       <a href="$profile_url" title="Betrachte das Profil von $name" class="wall-item-name-link"><span class="wall-item-name$sparkle" id="wall-item-name-$id" >$name</span></a> to <a href="$owner_url" title="View $owner_name's profile" class="wall-item-name-link"><span class="wall-item-name$osparkle" id="wall-item-ownername-$id">$owner_name</span></a> via Wall-To-Wall:<br />
+                       <div class="wall-item-ago"  id="wall-item-ago-$id">$ago</div>
+                       <div class="wall-item-location" id="wall-item-location-$id">$location</div>
+                       $vote
+               </div>
+               <div class="wall-item-content" id="wall-item-content-$id" >
+                       <div class="wall-item-title" id="wall-item-title-$id">$title</div>
+                       <div class="wall-item-body" id="wall-item-body-$id" >$body</div>
+               </div>
+               $drop
+       </div>  
+       <div class="wall-item-wrapper-end"></div>
+       <div class="wall-item-like" id="wall-item-like-$id">$like</div>
+       <div class="wall-item-dislike" id="wall-item-dislike-$id">$dislike</div>
+       <div class="wall-item-comment-separator"></div>
+       <div class="wall-item-comment-wrapper" >
+       $comment
+       </div>
+</div>
+
+<div class="wall-item-outside-wrapper-end$indent" ></div>
+
index 79a7651c1c754aa9d8695472526da0889a0115e9..9aca60188c123a04a0f2b4aa597ed6633007e6a0 100644 (file)
@@ -3,6 +3,8 @@
 
 <div id="contact-edit-banner-name">$name</div>
 
+<form action="contacts/$contact_id" method="post" >
+<input type="hidden" name="contact_id" value="$contact_id">
 
 <div id="contact-edit-wrapper" >
 
                        <a href="contacts/$contact_id/drop" id="contact-edit-drop-link" onclick="return confirmDelete();" ><img src="images/b_drophide.gif" alt="$delete" title="$delete" onmouseover="imgbright(this);" onmouseout="imgdull(this);" /></a>
                </div>
                <div id="contact-edit-nav-end"></div>
+
+
                <div id="contact-edit-poll-wrapper">
                        <div id="contact-edit-last-update-text">$lastupdtext<span id="contact-edit-last-updated">$last_update</span</div>
                        <div id="contact-edit-poll-text">$updpub</div>
                        $poll_interval
+                       <div id="contact-edit-update-now"><a href="contacts/$contact_id/update">$udnow</a></div>
                </div>
        </div>
        <div id="contact-edit-end" ></div>
@@ -35,9 +40,6 @@ $insecure
 $blocked
 $ignored
 
-<form action="contacts/$contact_id" method="post" >
-<input type="hidden" name="contact_id" value="$contact_id">
-
 <div id="contact-edit-info-wrapper">
 <h4>Contact Information / Notes</h4>
 <textarea id="contact-edit-info" rows="10" cols="72" name="info" >$info</textarea>
index c7c19bf69e1c69c94869d52da85fc2aad67a12f4..0182dbe5c034e6fee9176285ef988bba833791f9 100644 (file)
@@ -62,3 +62,9 @@ $a->config['system']['huburl'] = 'http://pubsubhubbub.appspot.com';
 
 $a->config['system']['rino_encrypt'] = true;
 
+// Addons or plugins are configured here.
+// This is a comma seperated list of addons to enable. Example:
+// $a->config['system']['addon'] = 'js_upload,randplace,oembed';
+
+$a->config['system']['addon'] = 'js_upload';
+
index b687f65a69d70ee8512df188185f33c3021e22fc..d0c956a020d63abcc62373eb6b68654821a0206e 100644 (file)
@@ -2,17 +2,20 @@
 <script language="javascript" type="text/javascript" src="$baseurl/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
 <script language="javascript" type="text/javascript">
 
+var editor;
+
 tinyMCE.init({
        theme : "advanced",
        mode : "specific_textareas",
        editor_selector: /(profile-jot-text|prvmail-text)/,
-       plugins : "bbcode",
-       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect",
+       plugins : "bbcode,paste",
+       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
        theme_advanced_buttons2 : "",
        theme_advanced_buttons3 : "",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "center",
        theme_advanced_blockformats : "blockquote,code",
+       paste_text_sticky : true,
        entity_encoding : "raw",
        add_unload_trigger : false,
        remove_linebreaks : false,
@@ -43,8 +46,13 @@ tinyMCE.init({
                                $('#character-counter').addClass('red');
                        }
                        $('#character-counter').text(text);
-               });
-       }
+       });
+
+               ed.onInit.add(function(ed) {
+                       ed.pasteAsPlainText = true;
+               });
+
+       }
 });
 
 </script>
index 6590cace8f086dca413404247bbe0ce1664006d4..5f99357780d23a92a81caefded93bc45d6a86e18 100644 (file)
@@ -15,6 +15,7 @@
 
                <textarea rows="5" cols="64" class="profile-jot-text" id="profile-jot-text" name="body" ></textarea>
 
+
 <div id="profile-jot-submit-wrapper" >
 <input type="submit" id="profile-jot-submit" name="submit" value="Share" />
        <div id="profile-upload-wrapper" style="display: $visitor;" >
        <div id="profile-nolocation-wrapper" style="display: none;" >
                <img id="profile-nolocation" src="images/noglobe.gif" alt="Clear Browser Location" title="Clear Browser Location" onclick="jotClearLocation();" />
        </div> 
+       <div id="profile-jot-plugin-wrapper">
+       $jotplugins
+       </div>
+
        <div id="profile-rotator-wrapper" style="display: $visitor;" >
                <img id="profile-rotator" src="images/rotator.gif" alt="Please wait" title="Please wait" style="display: none;" />
        </div> 
-       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Permission Settings" title="Permission Settings" onClick="openClose('profile-jot-acl-wrapper');" />$bang</div>
+       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Permission Settings" title="Permission Settings" onClick="openClose('profile-jot-acl-wrapper'); openClose('profile-jot-email-wrapper');" />$bang</div>
        <div id="profile-jot-perms-end"></div>
+       <div id="profile-jot-email-wrapper" style="display: none;" >
+       <div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle">
+       <div id="profile-jot-email-end"></div>
+       </div>
        <div id="profile-jot-acl-wrapper" style="display: none;" >$acl</div>
 </div>
 
index 5e1bfabf4c1876dc159df31fc6c73973c7170366..97d67cbf61679d07f8303bc6df2f27e452560bbf 100644 (file)
@@ -5,7 +5,7 @@
 $nickname_block
 
 
-<form action="settings" id="settings-form" method="post" autocomplete="false" >
+<form action="settings" id="settings-form" method="post" autocomplete="off" >
 
 
 <h3 class="settings-heading">Basic Settings</h3>
index 79a7651c1c754aa9d8695472526da0889a0115e9..9f36ddcc4283bbe0344b352ea3ce07776d7e6902 100644 (file)
@@ -3,6 +3,8 @@
 
 <div id="contact-edit-banner-name">$name</div>
 
+<form action="contacts/$contact_id" method="post" >
+<input type="hidden" name="contact_id" value="$contact_id">
 
 <div id="contact-edit-wrapper" >
 
                        <a href="contacts/$contact_id/drop" id="contact-edit-drop-link" onclick="return confirmDelete();" ><img src="images/b_drophide.gif" alt="$delete" title="$delete" onmouseover="imgbright(this);" onmouseout="imgdull(this);" /></a>
                </div>
                <div id="contact-edit-nav-end"></div>
+
+
+
                <div id="contact-edit-poll-wrapper">
                        <div id="contact-edit-last-update-text">$lastupdtext<span id="contact-edit-last-updated">$last_update</span</div>
                        <div id="contact-edit-poll-text">$updpub</div>
                        $poll_interval
+                       <div id="contact-edit-update-now"><a href="contacts/$contact_id/update">$udnow</a></div>
                </div>
        </div>
        <div id="contact-edit-end" ></div>
@@ -35,8 +41,6 @@ $insecure
 $blocked
 $ignored
 
-<form action="contacts/$contact_id" method="post" >
-<input type="hidden" name="contact_id" value="$contact_id">
 
 <div id="contact-edit-info-wrapper">
 <h4>Contact Information / Notes</h4>
index b687f65a69d70ee8512df188185f33c3021e22fc..d0c956a020d63abcc62373eb6b68654821a0206e 100644 (file)
@@ -2,17 +2,20 @@
 <script language="javascript" type="text/javascript" src="$baseurl/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
 <script language="javascript" type="text/javascript">
 
+var editor;
+
 tinyMCE.init({
        theme : "advanced",
        mode : "specific_textareas",
        editor_selector: /(profile-jot-text|prvmail-text)/,
-       plugins : "bbcode",
-       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect",
+       plugins : "bbcode,paste",
+       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
        theme_advanced_buttons2 : "",
        theme_advanced_buttons3 : "",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "center",
        theme_advanced_blockformats : "blockquote,code",
+       paste_text_sticky : true,
        entity_encoding : "raw",
        add_unload_trigger : false,
        remove_linebreaks : false,
@@ -43,8 +46,13 @@ tinyMCE.init({
                                $('#character-counter').addClass('red');
                        }
                        $('#character-counter').text(text);
-               });
-       }
+       });
+
+               ed.onInit.add(function(ed) {
+                       ed.pasteAsPlainText = true;
+               });
+
+       }
 });
 
 </script>
index 6590cace8f086dca413404247bbe0ce1664006d4..720cb0d1bcad02117a76f968db6ef9bd97fb9d00 100644 (file)
@@ -15,6 +15,8 @@
 
                <textarea rows="5" cols="64" class="profile-jot-text" id="profile-jot-text" name="body" ></textarea>
 
+
+
 <div id="profile-jot-submit-wrapper" >
 <input type="submit" id="profile-jot-submit" name="submit" value="Share" />
        <div id="profile-upload-wrapper" style="display: $visitor;" >
        <div id="profile-nolocation-wrapper" style="display: none;" >
                <img id="profile-nolocation" src="images/noglobe.gif" alt="Clear Browser Location" title="Clear Browser Location" onclick="jotClearLocation();" />
        </div> 
+
+       <div id="profile-jot-plugin-wrapper" >
+       $jotplugins
+       </div>
+
        <div id="profile-rotator-wrapper" style="display: $visitor;" >
                <img id="profile-rotator" src="images/rotator.gif" alt="Please wait" title="Please wait" style="display: none;" />
        </div> 
-       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Permission Settings" title="Permission Settings" onClick="openClose('profile-jot-acl-wrapper');" />$bang</div>
+       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Permission Settings" title="Permission Settings" onClick="openClose('profile-jot-acl-wrapper'); openClose('profile-jot-email-wrapper');" />$bang</div>
        <div id="profile-jot-perms-end"></div>
+       <div id="profile-jot-email-wrapper" style="display: none;" >
+       <div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle">
+       <div id="profile-jot-email-end"></div>
+       </div>
+
        <div id="profile-jot-acl-wrapper" style="display: none;" >$acl</div>
 </div>
 
index 9aee6c26278dc5758672810aeecbdb74ce568c44..f2c8913830f00b8617952de03baf3e8250444d9e 100644 (file)
@@ -39,8 +39,8 @@ EOT;
 
 $o .= '<div id="advanced-profile-dob">' 
        . ((intval($a->profile['dob'])) 
-               ? day_translate(datetime_convert('UTC',date_default_timezone_get(),$a->profile['dob'],'j F, Y'))
-               : day_translate(datetime_convert('UTC',date_default_timezone_get(),'2001-' . substr($a->profile['dob'],6),'j F'))) 
+               ? day_translate(datetime_convert('UTC','UTC',$a->profile['dob'],'j F, Y'))
+               : day_translate(datetime_convert('UTC','UTC','2001-' . substr($a->profile['dob'],6),'j F'))) 
        . "</div>\r\n</div>";
 
 $o .= '<div id="advanced-profile-dob-end"></div>';
index 5e1bfabf4c1876dc159df31fc6c73973c7170366..97d67cbf61679d07f8303bc6df2f27e452560bbf 100644 (file)
@@ -5,7 +5,7 @@
 $nickname_block
 
 
-<form action="settings" id="settings-form" method="post" autocomplete="false" >
+<form action="settings" id="settings-form" method="post" autocomplete="off" >
 
 
 <h3 class="settings-heading">Basic Settings</h3>
index 4432f496aebb9ca93a69f28d2a1f8035c9102be8..ac0f13a54dfbd718ad8715bba947e6d1885c119d 100644 (file)
@@ -3,6 +3,8 @@
 
 <div id="contact-edit-banner-name">$name</div>
 
+<form action="contacts/$contact_id" method="post" >
+<input type="hidden" name="contact_id" value="$contact_id">
 
 <div id="contact-edit-wrapper" >
 
                        <a href="contacts/$contact_id/drop" id="contact-edit-drop-link" onclick="return confirmDelete();" ><img src="images/b_drophide.gif" alt="$delete" title="$delete" onmouseover="imgbright(this);" onmouseout="imgdull(this);" /></a>
                </div>
                <div id="contact-edit-nav-end"></div>
+
+
                <div id="contact-edit-poll-wrapper">
                        <div id="contact-edit-last-update-text">$lastupdtext<span id="contact-edit-last-updated">$last_update</span</div>
                        <div id="contact-edit-poll-text">$updpub</div>
                        $poll_interval
+                       <div id="contact-edit-update-now"><a href="contacts/$contact_id/update">$udnow</a></div>
                </div>
        </div>
        <div id="contact-edit-end" ></div>
@@ -35,8 +40,6 @@ $insecure
 $blocked
 $ignored
 
-<form action="contacts/$contact_id" method="post" >
-<input type="hidden" name="contact_id" value="$contact_id">
 
 <div id="contact-edit-info-wrapper">
 <h4>Informazioni di contatto / Note</h4>
index bf655ab3705619031e6fd12b1e08b76eaafdb7e8..e55a357e8c7a78beaaff7657ae85d16b9c578128 100644 (file)
@@ -2,17 +2,20 @@
 <script language="javascript" type="text/javascript" src="$baseurl/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
 <script language="javascript" type="text/javascript">
 
+var editor;
+
 tinyMCE.init({
        theme : "advanced",
        mode : "specific_textareas",
        editor_selector: /(profile-jot-text|prvmail-text)/,
-       plugins : "bbcode",
-       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect",
+       plugins : "bbcode,paste",
+       theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
        theme_advanced_buttons2 : "",
        theme_advanced_buttons3 : "",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "center",
        theme_advanced_blockformats : "blockquote,code",
+       paste_text_sticky : true,
        entity_encoding : "raw",
        add_unload_trigger : false,
        remove_linebreaks : false,
@@ -43,8 +46,13 @@ tinyMCE.init({
                                $('#character-counter').addClass('red');
                        }
                        $('#character-counter').text(text);
-               });
-       }
+       });
+
+               ed.onInit.add(function(ed) {
+                       ed.pasteAsPlainText = true;
+               });
+
+       }
 });
 
 </script>
index 5aaf9b9232976335160229c43955ff5105ebb43f..eae3ecba8b26b3bf68a2d316009ca5b04e9d51c1 100644 (file)
@@ -15,6 +15,7 @@
 
                <textarea rows="5" cols="64" class="profile-jot-text" id="profile-jot-text" name="body" ></textarea>
 
+
 <div id="profile-jot-submit-wrapper" >
 <input type="submit" id="profile-jot-submit" name="submit" value="Condividi" />
        <div id="profile-upload-wrapper" style="display: $visitor;" >
        <div id="profile-nolocation-wrapper" style="display: none;" >
                <img id="profile-nolocation" src="images/noglobe.gif" alt="Cancella la tua posizione data dal browser" title="Cancella la tua posizione data dal browser" onclick="jotClearLocation();" />
        </div> 
+
+       <div id="profile-jot-plugin-wrapper" >
+       $jotplugins
+       </div>
+
        <div id="profile-rotator-wrapper" style="display: $visitor;" >
                <img id="profile-rotator" src="images/rotator.gif" alt="Attendi" title="Attendi" style="display: none;" />
        </div> 
-       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Impostazione permessi" title="Impostazione permessi" onClick="openClose('profile-jot-acl-wrapper');" />$bang</div>
+       <div id="profile-jot-perms" class="profile-jot-perms" style="display: $visitor;" ><img id="jot-perms-icon" src="images/$lockstate_icon.gif"  alt="Impostazione permessi" title="Impostazione permessi" onClick="openClose('profile-jot-acl-wrapper'); openClose('profile-jot-email-wrapper');" />$bang</div>
        <div id="profile-jot-perms-end"></div>
+       <div id="profile-jot-email-wrapper" style="display: none;" >
+       <div id="profile-jot-email-label">$emailcc</div><input type="text" name="emailcc" id="profile-jot-email" title="$emtitle">
+       <div id="profile-jot-email-end"></div>
+       </div>
+
        <div id="profile-jot-acl-wrapper" style="display: none;" >$acl</div>
 </div>
 
+
+
 <div id="profile-jot-end"></div>
 </form>
 </div>
index d941743d4ef47c19b4372fcedf144443ec6fa439..4d77e87cf1e75763d36beb750633dfac39422253 100644 (file)
@@ -1,4 +1,4 @@
-<h1>Upload Profile Photo</h1>
+<h1>Carica foto del profilo</h1>
 
 <form enctype="multipart/form-data" action="profile_photo" method="post">
 
@@ -12,3 +12,7 @@
 </div>
 
 </form>
+
+<div id="profile-photo-link-select-wrapper">
+o <a href='photos/$user'>seleziona una foto da un album</a>
+</div>
\ No newline at end of file
index 2ff259acc8904d516de53383b7c3f19493dd92cc..3b68923cf45ba470a53cf2eb4a7860b3f3716426 100644 (file)
@@ -6,7 +6,7 @@
 $nickname_block
 
 
-<form action="settings" id="settings-form" method="post" autocomplete="false" >
+<form action="settings" id="settings-form" method="post" autocomplete="off" >
 
 
 <h3 class="settings-heading">Impostazioni base</h3>
index eb76a8fde41337c65edcbc91b30d6280c2c9b574..2c429cc8a963c00d04c8064727a2f3c6b6f98a42 100644 (file)
@@ -44,16 +44,16 @@ $a->strings['Could not access contact record.'] = 'Non si puo\' accedere al cont
 $a->strings['Could not locate selected profile.'] = 'Non riesco a trovare il profilo selezionato.';
 $a->strings['Contact updated.'] = 'Contatto aggiornato.';
 $a->strings['Failed to update contact record.'] = 'Errore aggiornando il contatto.';
-$a->strings['Contact has been '] = 'Il contatto &egrave; stato ';
+$a->strings['Contact has been '] = 'Il contatto è stato ';
 $a->strings['blocked'] = 'bloccato';
 $a->strings['unblocked'] = 'sbloccato';
 $a->strings['ignored'] = 'aggiunto ai contatti ignorati';
 $a->strings['unignored'] = 'rimosso dai contatti ignorati';
 $a->strings['stopped following'] = 'tolto dai seguiti';
-$a->strings['Contact has been removed.'] = 'Il contatto &egrave; stato rimosso.';
+$a->strings['Contact has been removed.'] = 'Il contatto è stato rimosso.';
 $a->strings['Contact not found.'] = 'Contatto non trovato.';
 $a->strings['Mutual Friendship'] = 'Reciproca amicizia';
-$a->strings['is a fan of yours'] = '&egrave; un tuo fan';
+$a->strings['is a fan of yours'] = 'è un tuo fan';
 $a->strings['you are a fan of'] = 'sei un fan di';
 $a->strings['Contact Editor'] = 'Editor dei Contatti';
 $a->strings['Visit $name\'s profile'] = 'Visita il profilo di $name';
@@ -77,19 +77,19 @@ $a->strings['Visit '] = 'Visita ';
 $a->strings['\'s profile'] = 'profilo';
 $a->strings['Edit contact'] = 'Modifca contatto';
 $a->strings['Profile not found.'] = 'Profilo non trovato.';
-$a->strings['Response from remote site was not understood.'] = 'La risposta dal sito remota non &egrave; stata capita.';
+$a->strings['Response from remote site was not understood.'] = 'La risposta dal sito remota non è stata capita.';
 $a->strings['Unexpected response from remote site: '] = 'Risposta dal sito remoto inaspettata: ';
 $a->strings['Confirmation completed successfully.'] = 'Conferma completata con successo.';
 $a->strings['Remote site reported: '] = 'Il sito remoto riporta: ';
 $a->strings['Temporary failure. Please wait and try again.'] = 'Errore temporaneo. Attendi e riprova.';
-$a->strings['Introduction failed or was revoked.'] = 'La presentazione &egrave; fallita o &egrave; stata revocata.';
+$a->strings['Introduction failed or was revoked.'] = 'La presentazione è fallita o è stata revocata.';
 $a->strings['Unable to set contact photo.'] = 'Impossibile impostare la foto del contatto.';
-$a->strings['is now friends with'] = 'ora &egrave; amico di';
+$a->strings['is now friends with'] = 'ora è amico di';
 $a->strings['No user record found for '] = 'Nessun utente trovato per ';
-$a->strings['Our site encryption key is apparently messed up.'] = 'La nostra chiave di criptazione del sito e\' apparentemente incasinata.';
+$a->strings['Our site encryption key is apparently messed up.'] = 'La nostra chiave di criptazione del sito è apparentemente incasinata.';
 $a->strings['Empty site URL was provided or URL could not be decrypted by us.'] = 'E\' stato fornito un indirizzo vuoto o non possiamo decriptare l\'indirizzo.';
-$a->strings['Contact record was not found for you on our site.'] = 'Il contatto non &egrave; stato trovato sul nostro sito.';
-$a->strings['The ID provided by your system is a duplicate on our system. It should work if you try again.'] = 'L\'ID fornito dal tuo sistema e\' duplicato sul nostro sistema. Dovrebbe funzionare se provi ancora.';
+$a->strings['Contact record was not found for you on our site.'] = 'Il contatto non è stato trovato sul nostro sito.';
+$a->strings['The ID provided by your system is a duplicate on our system. It should work if you try again.'] = 'L\'ID fornito dal tuo sistema è duplicato sul nostro sistema. Dovrebbe funzionare se provi ancora.';
 $a->strings['Unable to set your contact credentials on our system.'] = 'Impossibile impostare le credenziali del tuo contatto sul nostro sistema.';
 $a->strings['Unable to update your contact profile details on our system'] = 'Impossibile aggiornare i dettagli del tuo contatto sul nostro sistema';
 $a->strings['Connection accepted at '] = 'Connessione accettata su ';
@@ -97,8 +97,8 @@ $a->strings['Administrator'] = 'Amministratore';
 $a->strings['New mail received at '] = 'Nuova mail ricevuta su ';
 $a->strings[' commented on an item at '] = ' commentato un elemento su ';
 $a->strings[' welcomes '] = ' accoglie ';
-$a->strings['This introduction has already been accepted.'] = 'Questa presentazione &egrave; già stata accettata.';
-$a->strings['Profile location is not valid or does not contain profile information.'] = 'La posizione del profilo non &egrave; valida o non contiene informazioni di profilo.';
+$a->strings['This introduction has already been accepted.'] = 'Questa presentazione è già stata accettata.';
+$a->strings['Profile location is not valid or does not contain profile information.'] = 'La posizione del profilo non è valida o non contiene informazioni di profilo.';
 $a->strings['Warning: profile location has no identifiable owner name.'] = 'Attenzione: la posizione del profilo non ha un identificabile proprietario';
 $a->strings['Warning: profile location has no profile photo.'] = 'Attenzione: la posizione del profilo non ha una foto.';
 $a->strings[' required parameter'] = ' parametro richiesto';
@@ -117,7 +117,7 @@ $a->strings['You have already introduced yourself here.'] = 'Ti sei già present
 $a->strings['Apparently you are already friends with .'] = 'Apparentemente sei già amico con .';
 $a->strings['Invalid profile URL.'] = 'Indirizzo profilo invalido.';
 $a->strings['Disallowed profile URL.'] = 'Indirizzo profilo non permesso.';
-$a->strings['Your introduction has been sent.'] = 'La tua presentazione &egrave; stata inviata.';
+$a->strings['Your introduction has been sent.'] = 'La tua presentazione è stata inviata.';
 $a->strings['Please login to confirm introduction.'] = 'Accedi per confermare la presentazione.';
 $a->strings['Incorrect identity currently logged in. Please login to <strong>this</strong> profile.'] = 'Accesso con identà incorretta. Accedi a <strong>questo</strong> profilo.';
 $a->strings['[Name Withheld]'] = '[Nome Nascosto]';
@@ -140,7 +140,7 @@ $a->strings['Item not found.'] = 'Elemento non trovato.';
 $a->strings['Private Message'] = 'Messaggio privato';
 $a->strings['This is you'] = 'Questo sei tu';
 $a->strings['View $name\'s profile'] = 'Guarda il profilo di $name';
-$a->strings['Item has been removed.'] = 'L\'elemento &egrave; stato rimosso.';
+$a->strings['Item has been removed.'] = 'L\'elemento è stato rimosso.';
 $a->strings['The profile address specified does not provide adequate information.'] = 'L\'indirizzo del profilo specificato non fornisce adeguate informazioni';
 $a->strings['Limited profile. This person will be unable to receive direct/personal notifications from you.'] = 'Profilo limitato. Questa persona non sara\' in grado di ricevere nofiche dirette/personali da te.';
 $a->strings['Unable to retrieve contact information.'] = 'Impossibile recuperare informazioni sul contatto.';
@@ -148,7 +148,7 @@ $a->strings['following'] = 'segue';
 $a->strings['Group created.'] = 'Gruppo creato.';
 $a->strings['Could not create group.'] = 'Impossibile creare il gruppo.';
 $a->strings['Group not found.'] = 'Gruppo non trovato.';
-$a->strings['Group name changed.'] = 'Il nome del gruppo e\' cambiato.';
+$a->strings['Group name changed.'] = 'Il nome del gruppo è cambiato.';
 $a->strings['Membership list updated.'] = 'Lista adesioni aggiornata.';
 $a->strings['Group removed.'] = 'Gruppo rimosso.';
 $a->strings['Unable to remove group.'] = 'Impossibile rimuovere il gruppo.';
@@ -165,16 +165,16 @@ $a->strings['Submit'] = 'Invia';
 $a->strings['Could not find a command line version of PHP in the web server PATH.'] = 'Non riesco a trovare una versione da riga di comando di PHP nel PATH del server web';
 $a->strings['This is required. Please adjust the configuration file .htconfig.php accordingly.'] = 'E\' richiesto. Aggiorna il file .htconfig.php di conseguenza.';
 $a->strings['The command line version of PHP on your system does not have "register_argc_argv" enabled.'] = 'La versione da riga di comando di PHP nel sistema non ha abilitato \"register_argc_argv\".';
-$a->strings['This is required for message delivery to work.'] = 'Ció &egrave; richiesto per far funzionare la consegna dei messaggi.';
-$a->strings['Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'] = 'Errore: la funzione \"openssl_pkey_new\" in questo sistema non &egrave; in grado di generare le chiavi di criptazione';
+$a->strings['This is required for message delivery to work.'] = 'Ciò Ã¨ richiesto per far funzionare la consegna dei messaggi.';
+$a->strings['Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'] = 'Errore: la funzione \"openssl_pkey_new\" in questo sistema non è in grado di generare le chiavi di criptazione';
 $a->strings['If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".'] = 'Se stai eseguendo friendika su windows, guarda \"http://www.php.net/manual/en/openssl.installation.php\".';
 $a->strings['Error: Apache webserver mod-rewrite module is required but not installed.'] = 'Errore: il modulo mod-rewrite di Apache &egreve; richiesto ma non installato';
-$a->strings['Error: libCURL PHP module required but not installed.'] = 'Errore: il modulo libCURL di PHP &egrave; richiesto ma non installato.';
-$a->strings['Error: GD graphics PHP module with JPEG support required but not installed.'] = 'Errore: Il modulo GD graphics di PHP con supporto a JPEG &egrave; richiesto ma non installato.';
-$a->strings['Error: openssl PHP module required but not installed.'] = 'Errore: il modulo openssl di PHP &egrave; richiesto ma non installato.';
-$a->strings['Error: mysqli PHP module required but not installed.'] = 'Errore: il modulo mysqli di PHP &egrave; richiesto ma non installato';
-$a->strings['The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.'] = 'L\'installazione web deve poter creare un file chiamato \".htconfig.php\" nella cartella principale del tuo web server ma non &egrave; in grado di farlo.';
-$a->strings['This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.'] = 'Ció &egrave; dovuto spesso a impostazioni di permessi, dato che il web server puo\' scrivere il file nella tua cartella, anche se tu puoi.';
+$a->strings['Error: libCURL PHP module required but not installed.'] = 'Errore: il modulo libCURL di PHP è richiesto ma non installato.';
+$a->strings['Error: GD graphics PHP module with JPEG support required but not installed.'] = 'Errore: Il modulo GD graphics di PHP con supporto a JPEG è richiesto ma non installato.';
+$a->strings['Error: openssl PHP module required but not installed.'] = 'Errore: il modulo openssl di PHP è richiesto ma non installato.';
+$a->strings['Error: mysqli PHP module required but not installed.'] = 'Errore: il modulo mysqli di PHP è richiesto ma non installato';
+$a->strings['The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.'] = 'L\'installazione web deve poter creare un file chiamato \".htconfig.php\" nella cartella principale del tuo web server ma non è in grado di farlo.';
+$a->strings['This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.'] = 'Ciò Ã¨ dovuto spesso a impostazioni di permessi, dato che il web server puo\' scrivere il file nella tua cartella, anche se tu puoi.';
 $a->strings['Please check with your site documentation or support people to see if this situation can be corrected.'] = 'Controlla la documentazione del tuo sito o con il personale di suporto se la situazione puo\' essere corretta.';
 $a->strings['If not, you may be required to perform a manual installation. Please see the file "INSTALL.txt" for instructions.'] = 'Altrimenti dovrai procedere con l\'installazione manuale. Guarda il file \"INSTALL.txt\" per istuzioni';
 $a->strings['The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.'] = 'Il file di configurazione del database \".htconfig.php\" non puo\' essere scritto. Usa il testo qui di seguito per creare un file di configurazione nella cartella principale del tuo sito.';
@@ -188,7 +188,6 @@ $a->strings['Send invitations'] = 'Invia inviti';
 $a->strings['Enter email addresses, one per line:'] = 'Inserisci gli indirizzi email, uno per riga:';
 $a->strings['Your message:'] = 'Il tuo messaggio:';
 $a->strings['Please join my social network on '] = 'Unisciti al mio social network su ';
-$a->strings['\r\n'] = '\r\n';
 $a->strings['To accept this invitation, please visit:'] = 'Per accettare questo invito visita:';
 $a->strings['Once you have registered, please connect with me via my profile page at:'] = 'Una volta registrato, connettiti con me sul mio profilo a:';
 $a->strings['Unable to locate original post.'] = 'Impossibile trovare il messaggio originale.';
@@ -227,7 +226,7 @@ $a->strings['Message not available.'] = 'Messaggio non disponibile.';
 $a->strings['Delete message'] = 'Cancella messaggio';
 $a->strings['Send Reply'] = 'Invia risposta';
 $a->strings['No such group'] = 'Nessun gruppo';
-$a->strings['Group is empty'] = 'Il gruppo &egrave; vuoto';
+$a->strings['Group is empty'] = 'Il gruppo è vuoto';
 $a->strings['Group: '] = 'Gruppo: ';
 $a->strings['Invalid request identifier.'] = 'Identificativo richiesta invalido.';
 $a->strings['Discard'] = 'Scarta';
@@ -252,7 +251,7 @@ $a->strings['Profile Photos'] = 'Foto del profilo';
 $a->strings['Album not found.'] = 'Album non trovato.';
 $a->strings['Delete Album'] = 'Elimina album';
 $a->strings['Delete Photo'] = 'Elimina foto';
-$a->strings['was tagged in a'] = '&egrave; stato taggato in';
+$a->strings['was tagged in a'] = 'è stato taggato in';
 $a->strings['by'] = 'da';
 $a->strings['Image exceeds size limit of '] = 'L\'immagine supera il limite di dimensione di ';
 $a->strings['Unable to process image.'] = 'Impossibile elaborare l\'immagine.';
@@ -271,51 +270,52 @@ $a->strings['Edit photo'] = 'Modifica foto';
 $a->strings['View Full Size'] = 'Vedi dimensione intera';
 $a->strings['Tags: '] = 'Tag: ';
 $a->strings['[Remove any tag]'] = '[Rimuovi tutti i tag]';
+$a->strings['New album name'] = 'Nuovo nome album';
 $a->strings['Caption'] = 'Didascalia';
 $a->strings['Add a Tag'] = 'Aggiungi un tag';
 $a->strings['Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'] = 'Esempio: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping';
 $a->strings['Recent Photos'] = 'Foto recenti';
 $a->strings['Upload New Photos'] = 'Carica nuova foto';
 $a->strings['View Album'] = 'Vedi album';
-$a->strings['Image uploaded but image cropping failed.'] = 'Immagine caricata ma il ritaglio &egrave; fallito.';
+$a->strings['Image uploaded but image cropping failed.'] = 'Immagine caricata ma il ritaglio è fallito.';
 $a->strings['Image size reduction [175] failed.'] = 'Riduzione dimensioni immagine [175] fallito.';
 $a->strings['Image size reduction [80] failed.'] = 'Riduzione dimensioni immagine [80] fallito.';
 $a->strings['Image size reduction [48] failed.'] = 'Riduzione dimensioni immagine [48] fallito.';
 $a->strings['Unable to process image'] = 'Impossibile elaborare l\'immagine';
 $a->strings['Image uploaded successfully.'] = 'Immagine caricata con successo.';
 $a->strings['Image size reduction [640] failed.'] = 'Riduzione dimensioni immagine [640] fallito.';
-$a->strings['Profile Name is required.'] = 'Il Nome Profilo &egrave; richiesto .';
+$a->strings['Profile Name is required.'] = 'Il Nome Profilo è richiesto .';
 $a->strings['Profile updated.'] = 'Profilo aggiornato.';
 $a->strings['Profile deleted.'] = 'Profilo elminato.';
 $a->strings['Profile-'] = 'Profilo-';
 $a->strings['New profile created.'] = 'Nuovo profilo creato.';
 $a->strings['Profile unavailable to clone.'] = 'Impossibile duplicare il plrofilo.';
-$a->strings['This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet.'] = 'Questo &egrave; il tuo profilo <strong>publico</strong>.<br /><strong>Potrebbe</strong> essere visto da chiunque attraverso internet.';
-$a->strings['Age: '] = 'Età: ';
+$a->strings['This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet.'] = 'Questo è il tuo profilo <strong>publico</strong>.<br /><strong>Potrebbe</strong> essere visto da chiunque attraverso internet.';
+$a->strings['Age: '] = 'Età : ';
 $a->strings['Please enter the required information.'] = 'Inserisci le informazioni richieste.';
 $a->strings['Please use a shorter name.'] = 'Usa un nome più corto.';
-$a->strings['Name too short.'] = 'Il Nome &egrave; troppo corto.';
+$a->strings['Name too short.'] = 'Il Nome è troppo corto.';
 $a->strings['That doesn\'t appear to be your full (First Last) name.'] = 'Questo non sembra essere il tuo nome completo (Nome Cognome).';
-$a->strings['Your email domain is not among those allowed on this site.'] = 'Il dominio della tua email non &egrave; tra quelli autorizzati su questo sito.';
+$a->strings['Your email domain is not among those allowed on this site.'] = 'Il dominio della tua email non è tra quelli autorizzati su questo sito.';
 $a->strings['Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.'] = 'Il tuo \"soprannome\" puo\' contenere solo \"a-z\", \"0-9\", \"-\", e \"_\", e deve cominciare con una lettera.';
 $a->strings['Nickname is already registered. Please choose another.'] = 'Soprannome già registrato. Scegline un\'altro.';
 $a->strings['SERIOUS ERROR: Generation of security keys failed.'] = 'ERRORE GRAVE: Generazione delle chiavi di sicurezza fallito.';
-$a->strings['An error occurred during registration. Please try again.'] = 'Si &egrave; verificato un errore durante la registrazione. Prova ancora.';
-$a->strings['An error occurred creating your default profile. Please try again.'] = 'Si &egrave; verificato un errore creando il tuo profilo. Prova ancora.';
+$a->strings['An error occurred during registration. Please try again.'] = 'Si è verificato un errore durante la registrazione. Prova ancora.';
+$a->strings['An error occurred creating your default profile. Please try again.'] = 'Si è verificato un errore creando il tuo profilo. Prova ancora.';
 $a->strings['Registration details for '] = 'Dettagli registrazione per ';
 $a->strings['Registration successful. Please check your email for further instructions.'] = 'Registrazione completata. Controlla la tua mail per ulteriori informazioni.';
-$a->strings['Failed to send email message. Here is the message that failed.'] = 'Errore inviando il messaggio email. Questo &egrave; il messaggio non inviato.';
+$a->strings['Failed to send email message. Here is the message that failed.'] = 'Errore inviando il messaggio email. Questo è il messaggio non inviato.';
 $a->strings['Your registration can not be processed.'] = 'La tua registrazione non puo\' essere elaborata.';
 $a->strings['Registration request at '] = 'Registrazione richiesta il ';
-$a->strings['Your registration is pending approval by the site owner.'] = 'La tua richiesta &egrave; in attesa di approvazione da parte del prorietario del sito.';
+$a->strings['Your registration is pending approval by the site owner.'] = 'La tua richiesta è in attesa di approvazione da parte del prorietario del sito.';
 $a->strings['You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking \'Register\'.'] = 'Puoi (opzionalmento) riempire questa maschera via OpenID inserendo il tuo OpenID e cliccando \'Registra\'.';
 $a->strings['If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items.'] = 'Se non hai familiarità con OpenID, lascia quel campo in bianco e riempi il resto della maschera.';
 $a->strings['Your OpenID (optional): '] = 'Il tuo OpenID (opzionale): ';
-$a->strings['Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.'] = 'Il contenuto in comune &egrave; coperto dalla licenza <a href=\"http://creativecommons.org/licenses/by/3.0/deed.it\">Creative Commons Attribuzione 3.0</a>.';
+$a->strings['Shared content is covered by the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> license.'] = 'Il contenuto in comune è coperto dalla licenza <a href=\"http://creativecommons.org/licenses/by/3.0/deed.it\">Creative Commons Attribuzione 3.0</a>.';
 $a->strings['Registration'] = 'Registrazione';
 $a->strings['Your Full Name (e.g. Joe Smith): '] = 'Il tuo Nome Completo (p.e. Mario Rossi): ';
 $a->strings['Your Email Address: '] = 'Il tuo Indirizzo Email: ';
-$a->strings['Choose a profile nickname. This must begin with a text character. Your global profile locator will then be \'<strong>nickname@$sitename</strong>\'.'] = 'Scegli un soprannome per il profilo. Deve cominciare con una lettera. L\'identificativo globale del tuo profilo sar&agrave; \'<strong>soprannome@$sitename</strong>\'.';
+$a->strings['Choose a profile nickname. This must begin with a text character. Your global profile locator will then be \'<strong>nickname@$sitename</strong>\'.'] = 'Scegli un soprannome per il profilo. Deve cominciare con una lettera. L\'identificativo globale del tuo profilo sarà \'<strong>soprannome@$sitename</strong>\'.';
 $a->strings['Choose a nickname: '] = 'Scegli un soprannome: ';
 $a->strings['Register'] = 'Regitrati';
 $a->strings['Please login.'] = 'Accedi.';
@@ -326,7 +326,7 @@ $a->strings['Passwords do not match. Password unchanged.'] = 'Le password non co
 $a->strings['Empty passwords are not allowed. Password unchanged.'] = 'Password vuote non sono consentite. Password non cambiata.';
 $a->strings['Password changed.'] = 'Password cambiata.';
 $a->strings['Password update failed. Please try again.'] = 'Aggiornamento password fallito. Prova ancora.';
-$a->strings[' Please use a shorter name.'] = ' Usa un nome pi&ugrave; corto.';
+$a->strings[' Please use a shorter name.'] = ' Usa un nome più corto.';
 $a->strings[' Name too short.'] = ' Nome troppo corto.';
 $a->strings[' Not valid email.'] = ' Email non valida.';
 $a->strings['Settings updated.'] = 'Impostazioni aggiornate.';
@@ -334,8 +334,8 @@ $a->strings['Plugin Settings'] = 'Impostazioni Plugin';
 $a->strings['Account Settings'] = 'Impostazioni Account';
 $a->strings['No Plugin settings configured'] = 'Nessuna impostazione Plugin configurata';
 $a->strings['OpenID: '] = 'OpenID: ';
-$a->strings['&nbsp;(Optional) Allow this OpenID to login to this account.'] = '&nbsp;(Opzionale) Permetti a questo OpenID di accedere a questo account.';
-$a->strings['Profile is <strong>not published</strong>.'] = 'Il profilo <strong>non &egrave; pubblicato</strong>.';
+$a->strings['&nbsp;(Optional) Allow this OpenID to login to this account.'] = ' (Opzionale) Permetti a questo OpenID di accedere a questo account.';
+$a->strings['Profile is <strong>not published</strong>.'] = 'Il profilo <strong>non è pubblicato</strong>.';
 $a->strings['Default Post Permissions'] = 'Permessi di default per i messaggi';
 $a->strings['Tag removed'] = 'TAg rimosso';
 $a->strings['Remove Item Tag'] = 'Rimuovi tag dall\'elemento';
@@ -355,7 +355,7 @@ $a->strings['OK, probably harmless'] = 'E\' ok, probabilmente innocuo';
 $a->strings['Reputable, has my trust'] = 'Rispettabile, ha la mia fiducia';
 $a->strings['Frequently'] = 'Frequentemente';
 $a->strings['Hourly'] = 'Ogni ora';
-$a->strings['Twice daily'] = 'Due volte al d&igrave;';
+$a->strings['Twice daily'] = 'Due volte al dì';
 $a->strings['Daily'] = 'Giornalmente';
 $a->strings['Weekly'] = 'Settimanalmente';
 $a->strings['Monthly'] = 'Mensilmente';
@@ -1003,11 +1003,11 @@ $a->strings['UTC'] = 'UTC';
 $a->strings['W-SU'] = 'W-SU';
 $a->strings['WET'] = 'WET';
 $a->strings['Zulu'] = 'Zulu';
-$a->strings['Monday'] = 'Luned&igrave;';
-$a->strings['Tuesday'] = 'Marted&igrave;';
-$a->strings['Wednesday'] = 'Mercoled&igrave;';
-$a->strings['Thursday'] = 'Gioved&igrave;';
-$a->strings['Friday'] = 'Venedr&igrave;';
+$a->strings['Monday'] = 'Lunedì';
+$a->strings['Tuesday'] = 'Martedì';
+$a->strings['Wednesday'] = 'Mercoledì';
+$a->strings['Thursday'] = 'Giovedì';
+$a->strings['Friday'] = 'Venerdì';
 $a->strings['Saturday'] = 'Sabato';
 $a->strings['Sunday'] = 'Domenica';
 $a->strings['January'] = 'Gennaio';
@@ -1031,4 +1031,25 @@ $a->strings['Invalid OpenID url'] = 'Url OpenID non valido';
 $a->strings['Cannot use that email.'] = 'Questa email non si puo\' usare.';
 $a->strings['Normal View'] = 'Vista normale';
 $a->strings['New Item View'] = 'Vista Nuovi Elementi';
+$a->strings[' Cannot change to that email.'] = 'Non puoi cambiare a quella email.';
+$a->strings['Birthday:'] = 'Compleanno:';
+$a->strings['Update now'] = 'Aggiorna adesso';
+$a->strings['This message was sent to you by '] = 'Questo messaggio è ti è stato inviato da ';
+$a->strings[', a member of the Friendika social network.'] = ', un membro del social network Friendika';
+$a->strings['You may visit them online at'] = 'Puoi visitarli online a ';
+$a->strings['Please contact the sender by replying to this post if you do not wish to receive these messages.'] = 'Contatta il mittente rispondendo a questo post se non vuoi ricevere questi messaggi.';
+$a->strings['posted an update.'] = 'ha inviato un aggiornamento.';
+$a->strings['CC: email addresses'] = 'CC: indirizzi email';
+$a->strings['Example: bob@example.com, mary@example.com'] = 'Esempio: bob@example.com, mary@example.com';
+$a->strings['Embedding disabled'] = 'Inclusione disabilitata';
+$a->strings['Upload a file'] = 'Carica un file';
+$a->strings['Drop files here to upload'] = 'Trascina un file qui per caricarlo';
+$a->strings['Failed'] = 'Fallito';
+$a->strings['No files were uploaded.'] = 'Nessun file è stato caricato.';
+$a->strings['Uploaded file is empty'] = 'Il file caricato è vuoto';
+$a->strings['Uploaded file is too large'] = 'Il file caricato è troppo grande';
+$a->strings['File has an invalid extension, it should be one of '] = 'Il file ha una estensione non valida, dovrebbe essere una di ';
+$a->strings['Upload was cancelled, or server error encountered'] = 'Il caricamento è stato cancellato, o si è verificato un errore sul server';
+$a->strings['Randplace Settings'] = 'Impostazioni Randplace';
+$a->strings['Enable Randplace Plugin'] = 'Abilita il plugin Randplace';
 ?>
index a40e3fef60da40b658cae407f6a4fb7b93346069..bf8563b3c252a9fcc6c56d8baeee7210ef2ab3d8 100644 (file)
@@ -3,6 +3,12 @@
 
        <input type="hidden" name="item_id" value="$item_id" />
 
+       <label id="photo-edit-albumname-label" for="photo-edit-albumname">$newalbum</label>
+       <input id="photo-edit-albumname" type="text" size="32" name="albname" value="$album" />
+
+       <div id="photo-edit-albumname-end"></div>
+
+
        <label id="photo-edit-caption-label" for="photo-edit-caption">$capt_label</label>
        <input id="photo-edit-caption" type="text" size="84" name="desc" value="$caption" />
 
index 8a9dc3c683dc931c4ae1c4d63164d2cb531234c2..2dbcddefd018d96bba63a05719c19cf0cbd7a439 100644 (file)
 
        </div>
 
-       <div id="photos-upload-select-files-text">$filestext</div>
-
-       <div id="photos_upload_applet_wrapper">
-               <applet name="jumpLoaderApplet"
-                       code="jmaster.jumploader.app.JumpLoaderApplet.class"
-                       archive="$archive"
-                       width="700"
-                       height="600"
-                       mayscript >
-                       <param name="uc_uploadUrl" value="$uploadurl" />
-                       <param name="uc_uploadFormName" value="photos-upload-form" />
-                       <param name="gc_loggingLeveL" value="FATAL" />
-                       <param name="uc_fileParameterName" value="userfile" />
-                       <param name="uc_cookie" value="PHPSESSID=$sessid; path=/;" />
-                       <param name="vc_disableLocalFileSystem" value="false" />
-                       <param name="vc_uploadViewMenuBarVisible" value="false" />
-                       <param name="vc_mainViewFileListViewVisible" value="true" />
-                       <param name="vc_mainViewFileListViewHeightPercent" value="50" />
-                       <param name="vc_mainViewFileTreeViewVisible" value="true" />
-                       <param name="vc_mainViewFileTreeViewWidthPercent" value="35" />
-                       <param name="vc_lookAndFeel" value="system" />
-       
-               </applet>
-               
-       </div>
+       <div id="photos-upload-spacer"></div>
 
-       <div id="photos-upload-no-java-message" >
-       $nojava
-       </div>  
+       $uploader
 
-       <input type="file" name="userfile" />
+       $default
 
-       <div class="photos-upload-submit-wrapper" >
-               <input type="submit" name="submit" value="$submit" id="photos-upload-submit" />
-       </div>
        <div class="photos-upload-end" ></div>
 </form>
 
diff --git a/view/removeme.tpl b/view/removeme.tpl
new file mode 100644 (file)
index 0000000..a3ca8d4
--- /dev/null
@@ -0,0 +1,20 @@
+<h1>$title</h1>
+
+<div id="remove-account-wrapper">
+
+<div id="remove-account-desc">$desc</div>
+
+<form action="$basedir/removeme" autocomplete="off" method="post" >
+<input type="hidden" name="verify" value="$hash" />
+
+<div id="remove-account-pass-wrapper">
+<label id="remove-account-pass-label" for="remove-account-pass">$passwd</label>
+<input type="password" id="remove-account-pass" name="qxz_password" />
+</div>
+<div id="remove-account-pass-end"></div>
+
+<input type="submit" name="submit" value="$submit" />
+
+</form>
+</div>
+
index e34b622c65318427a6fa79d5a24f6e8c595febcb..61782f6e37399be07f038369598c8c97117ae7f8 100644 (file)
@@ -985,6 +985,10 @@ input#dfrn-url {
        width: 450px;
        margin-left: 10px;
        margin-bottom: 20px;
+       padding: 20px;
+       max-height: 400px;
+       overflow: auto;
+
 }
 
 .wall-item-title {
@@ -1030,7 +1034,7 @@ input#dfrn-url {
        margin-left: 110px;
        margin-top: 10px;
 }
-
+#profile-jot-plugin-wrapper,
 #profile-jot-submit-wrapper {
        margin-top: 15px;
 }
@@ -1074,7 +1078,9 @@ input#dfrn-url {
 #profile-jot-perms-end {
        clear: both;
 }
-
+#profile-jot-plugin-end {
+  clear:both;
+}
 #profile-jot-end {
        clear: both;
        margin-bottom: 30px;
@@ -1327,6 +1333,9 @@ input#dfrn-url {
 #contact-edit-poll-text {
        margin-bottom: 10px;
 }
+#contact-edit-update-now {
+       margin-top: 15px;
+}
 
 #contact-edit-photo-wrapper {
        margin-bottom: 20px;
@@ -1721,6 +1730,9 @@ a.mail-list-link {
 #photos-upload-album-select {
        float: left;
 }
+#photos-upload-spacer {
+       margin-top: 25px;
+}
 #photos-upload-new-end, #photos-upload-exist-end {
        clear: both;
 }
@@ -1786,11 +1798,11 @@ a.mail-list-link {
        margin-bottom: 15px;
 }
 
-#photo-edit-caption-label, #photo-edit-tags-label {
+#photo-edit-caption-label, #photo-edit-tags-label, #photo-edit-albumname-label {
        float: left;
        width: 150px;
 }
-#photo-edit-caption, #photo-edit-newtag {
+#photo-edit-caption, #photo-edit-newtag, #photo-edit-albumname {
        float: left;
        margin-bottom: 25px;
 }
@@ -1801,7 +1813,7 @@ a.mail-list-link {
        margin-bottom: 25px;
 }
 
-#photo-edit-caption-end, #photo-edit-tags-end {
+#photo-edit-caption-end, #photo-edit-tags-end, #photo-edit-albumname-end {
        clear: both;
 }
 
@@ -1996,3 +2008,10 @@ a.mail-list-link {
        margin-bottom: 15px;
 }
 
+.tool-wrapper {
+  float: left;
+  margin-left: 20px;
+}
+.tool-link {
+  cursor: pointer;
+}
index b00f24cc28abb4e1134d515095b8059a1a4abaeb..a1098f6a46f682e15d467b9d15c9d7de12583e32 100644 (file)
@@ -809,6 +809,8 @@ input#dfrn-url {
 }
 .wall-item-wrapper {
        float: left;
+    margin-right: 5px;
+    width: 150px;
 }
 .wall-item-lock {
        height: 20px;
@@ -851,9 +853,12 @@ input#dfrn-url {
 }
 .wall-item-content {
        float: left;
-       width: 450px;
+       /*width: 450px;*/
        margin-left: 10px;
        margin-bottom: 20px;
+       padding: 20px;
+       max-height: 400px;
+       overflow: auto;
 }
 
 .wall-item-title {
@@ -902,6 +907,7 @@ input#dfrn-url {
        margin: 10px 0px 10px 110px;
 }
 
+#profile-jot-plugin-wrapper,
 #profile-jot-submit-wrapper {
        margin-top: 15px;
 }
@@ -947,6 +953,9 @@ input#dfrn-url {
        height: 30px;
 }
 
+#profile-jot-plugin-end{
+  clear: both;
+}
 #profile-jot-end {
        /*clear: both;*/
        margin-bottom: 30px;
@@ -1200,6 +1209,10 @@ input#dfrn-url {
        margin-bottom: 10px;
 }
 
+#contact-edit-update-now {
+       margin-top: 15px;
+}
+
 #contact-edit-photo-wrapper {
        margin-bottom: 20px;
 }
@@ -1453,8 +1466,9 @@ input#dfrn-url {
        margin-top: 10px;
 }
 a.mail-list-link {
-       display: block;
-       padding: 4px 5px;
+    display: block;
+    font-size: 1.3em;
+    padding: 4px 0;
 }
 
 /*
@@ -1492,8 +1506,8 @@ a.mail-list-link {
 }
 
 .mail-conv-subject {
-       font-size: 1.1em;
-       margin-top: 10px;
+    font-size: 1.4em;
+    margin: 10px 0;
 }
 
 .mail-conv-outside-wrapper-end {
@@ -1590,6 +1604,10 @@ a.mail-list-link {
 #photos-upload-album-select {
        float: left;
 }
+
+#photos-upload-spacer {
+       margin-top: 25px;
+}
 #photos-upload-new-end, #photos-upload-exist-end {
        clear: both;
 }
@@ -1655,11 +1673,11 @@ a.mail-list-link {
        margin-bottom: 15px;
 }
 
-#photo-edit-caption-label, #photo-edit-tags-label {
+#photo-edit-caption-label, #photo-edit-tags-label, #photo-edit-albumname-label {
        float: left;
        width: 150px;
 }
-#photo-edit-caption, #photo-edit-newtag {
+#photo-edit-caption, #photo-edit-newtag, #photo-edit-albumname {
        float: left;
        margin-bottom: 25px;
 }
@@ -1670,7 +1688,7 @@ a.mail-list-link {
        margin-bottom: 25px;
 }
 
-#photo-edit-caption-end, #photo-edit-tags-end {
+#photo-edit-caption-end, #photo-edit-tags-end, #photo-edit-albumname-end {
        clear: both;
 }
 
@@ -1880,3 +1898,11 @@ a.mail-list-link {
 }
 
 
+.tool-wrapper {
+  float: left;
+  margin-left: 20px;
+}
+
+.tool-link {
+  cursor: pointer;
+}
diff --git a/view/theme/greenzero/border.jpg b/view/theme/greenzero/border.jpg
new file mode 100644 (file)
index 0000000..034a1cb
Binary files /dev/null and b/view/theme/greenzero/border.jpg differ
diff --git a/view/theme/greenzero/head.jpg b/view/theme/greenzero/head.jpg
new file mode 100644 (file)
index 0000000..c697762
Binary files /dev/null and b/view/theme/greenzero/head.jpg differ
diff --git a/view/theme/greenzero/shiny.png b/view/theme/greenzero/shiny.png
new file mode 100644 (file)
index 0000000..994c0d0
Binary files /dev/null and b/view/theme/greenzero/shiny.png differ
diff --git a/view/theme/greenzero/style.css b/view/theme/greenzero/style.css
new file mode 100644 (file)
index 0000000..5a84011
--- /dev/null
@@ -0,0 +1,29 @@
+@import url('../duepuntozero/style.css');
+
+/* green variation by Tobias Diekershoff <tobias.diekershoff@gmx.net> */
+
+a, a:visited { color: #549f4f; text-decoration: none; }
+a:hover {text-decoration: underline; }
+
+
+body {         background-image: url(head.jpg); }
+aside(         background-image: url(border.jpg); }
+section {      background-image: url(border.jpg); }
+#profile-tabs-wrapper {        background-image: url(head.jpg); }
+div.wall-item-content-wrapper.shiny {  background-image: url('shiny.png'); }
+
+
+.nav-commlink, .nav-login-link {
+       background-color: #aed3b2;
+
+}
+
+.fakelink, .fakelink:visited {
+       color: #549f4f;
+}
+
+.wall-item-name-link {
+       color: #549f4f;
+}
+
+
diff --git a/view/theme/purplezero/border.jpg b/view/theme/purplezero/border.jpg
new file mode 100644 (file)
index 0000000..66c7a6f
Binary files /dev/null and b/view/theme/purplezero/border.jpg differ
diff --git a/view/theme/purplezero/head.jpg b/view/theme/purplezero/head.jpg
new file mode 100644 (file)
index 0000000..1acd2dd
Binary files /dev/null and b/view/theme/purplezero/head.jpg differ
diff --git a/view/theme/purplezero/shiny.png b/view/theme/purplezero/shiny.png
new file mode 100644 (file)
index 0000000..d3f71ee
Binary files /dev/null and b/view/theme/purplezero/shiny.png differ
diff --git a/view/theme/purplezero/style.css b/view/theme/purplezero/style.css
new file mode 100644 (file)
index 0000000..16c9dc6
--- /dev/null
@@ -0,0 +1,27 @@
+@import url('../duepuntozero/style.css');
+
+a, a:visited { color: #7433af; text-decoration: none; }
+a:hover {text-decoration: underline; }
+
+
+body {         background-image: url(head.jpg); }
+aside(         background-image: url(border.jpg); }
+section {      background-image: url(border.jpg); }
+#profile-tabs-wrapper {        background-image: url(head.jpg); }
+div.wall-item-content-wrapper.shiny {  background-image: url('shiny.png'); }
+
+
+.nav-commlink, .nav-login-link {
+       background-color: #aed3b2;
+
+}
+
+.fakelink, .fakelink:visited {
+       color: #7433af;
+}
+
+.wall-item-name-link {
+       color: #7433af;
+}
+
+