mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2010-03-08 10:25 pm

[dw-free] Move editpics to editicons

[commit: http://hg.dwscoalition.org/dw-free/rev/4f61e7788b51]

http://bugs.dwscoalition.org/show_bug.cgi?id=2398

Move /editpics to /editicons.

Patch by [personal profile] ninetydegrees.

Files modified:
  • cgi-bin/DW/Logic/MenuNav.pm
  • cgi-bin/DW/Logic/ProfilePage.pm
  • cgi-bin/LJ/CProd/UserPic.pm
  • cgi-bin/LJ/Userpic.pm
  • cgi-bin/LJ/Widget/CreateAccount.pm
  • cgi-bin/LJ/Widget/CreateAccountNextSteps.pm
  • cgi-bin/LJ/Widget/UserpicDisplay.pm
  • cgi-bin/bml/scheme/blueshift.look
  • cgi-bin/bml/scheme/celerity.look
  • cgi-bin/bml/scheme/global.look
  • cgi-bin/bml/scheme/gradation-vertical.look
  • cgi-bin/crumbs.pl
  • cgi-bin/ljprotocol.pl
  • cgi-bin/redirect.dat
  • cgi-bin/weblib.pl
  • doc/raw/build/ljconfig/ljconfig2db.pl
  • doc/raw/http-interface.txt
  • htdocs/allpics.bml
  • htdocs/editicons.bml
  • htdocs/editicons.bml.text
  • htdocs/editpics.bml
  • htdocs/editpics.bml.text
  • htdocs/js/editicons.js
  • htdocs/js/editpics.js
  • htdocs/manage/index.bml
  • htdocs/manage/profile/index.bml
  • htdocs/manage/profile/index.bml.text
  • htdocs/site/index.bml
  • htdocs/stc/blueshift/blueshift.css
  • htdocs/stc/celerity/celerity.css
  • htdocs/stc/editicons.css
  • htdocs/stc/editpics.css
  • htdocs/stc/gradation/gradation-vertical.css
  • htdocs/tools/userpicfactory.bml
--------------------------------------------------------------------------------
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/DW/Logic/MenuNav.pm
--- a/cgi-bin/DW/Logic/MenuNav.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/DW/Logic/MenuNav.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -91,7 +91,7 @@ sub get_menu_navigation {
                     display => $loggedin,
                 },
                 {
-                    url => "$LJ::SITEROOT/editpics",
+                    url => "$LJ::SITEROOT/editicons",
                     text => "menunav.create.uploaduserpics",
                     text_opts => { num => $userpic_count, max => $userpic_max },
                     display => $loggedin,
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/DW/Logic/ProfilePage.pm
--- a/cgi-bin/DW/Logic/ProfilePage.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/DW/Logic/ProfilePage.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -109,11 +109,11 @@ sub userpic {
             if ( LJ::userpic_count( $u ) ) {
                 $ret->{userpic_url} = $u->allpics_base;
                 $ret->{caption_text} = LJ::Lang::ml( '.section.edit' );
-                $ret->{caption_url} = "$LJ::SITEROOT/editpics?authas=$user"
+                $ret->{caption_url} = "$LJ::SITEROOT/editicons?authas=$user"
             } else {
-                $ret->{userpic_url} = "$LJ::SITEROOT/editpics?authas=$user";
+                $ret->{userpic_url} = "$LJ::SITEROOT/editicons?authas=$user";
                 $ret->{caption_text} = LJ::Lang::ml( '.userpic.upload' );
-                $ret->{caption_url} = "$LJ::SITEROOT/editpics?authas=$user"
+                $ret->{caption_url} = "$LJ::SITEROOT/editicons?authas=$user"
             }
         } else {
             if ( LJ::userpic_count( $u ) ) {
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/LJ/CProd/UserPic.pm
--- a/cgi-bin/LJ/CProd/UserPic.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/LJ/CProd/UserPic.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -34,7 +34,7 @@ height: 100px; border: 1px solid #000000
 }
 
 sub ml { 'cprod.userpic.text' }
-sub link { "$LJ::SITEROOT/editpics" }
+sub link { "$LJ::SITEROOT/editicons" }
 sub button_text { "Userpic" }
 
 1;
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/LJ/Userpic.pm
--- a/cgi-bin/LJ/Userpic.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/LJ/Userpic.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -1057,7 +1057,7 @@ sub as_html {
 sub as_html {
     my $self = shift;
     my $num_words = $self->number_lost;
-    return BML::ml("/editpics.bml.error.toomanykeywords", {
+    return BML::ml("/editicons.bml.error.toomanykeywords", {
         numwords => $self->number_lost,
         words    => $self->lost_keywords_as_html,
         max      => $LJ::MAX_USERPIC_KEYWORDS,
@@ -1069,9 +1069,9 @@ sub fields      { qw(size max); }
 sub fields      { qw(size max); }
 sub as_html {
     my $self = shift;
-    return BML::ml('/editpics.bml.error.filetoolarge',
+    return BML::ml('/editicons.bml.error.filetoolarge',
                    { 'maxsize' => $self->{'max'} .
-                         BML::ml('/editpics.bml.kilobytes')} );
+                         BML::ml('/editicons.bml.kilobytes')} );
 }
 
 package LJ::Error::Userpic::Dimensions;
@@ -1079,7 +1079,7 @@ sub fields      { qw(w h); }
 sub fields      { qw(w h); }
 sub as_html {
     my $self = shift;
-    return BML::ml('/editpics.bml.error.imagetoolarge', {
+    return BML::ml('/editicons.bml.error.imagetoolarge', {
         imagesize => $self->{'w'} . 'x' . $self->{'h'}
         });
 }
@@ -1089,7 +1089,7 @@ sub fields      { qw(type); }
 sub fields      { qw(type); }
 sub as_html {
     my $self = shift;
-    return BML::ml("/editpics.bml.error.unsupportedtype",
+    return BML::ml("/editicons.bml.error.unsupportedtype",
                           { 'filetype' => $self->{'type'} });
 }
 
@@ -1098,7 +1098,7 @@ sub fields      { qw(origkw newkw); }
 sub fields      { qw(origkw newkw); }
 sub as_html {
     my $self = shift;
-    return BML::ml("/editpics.bml.error.rename.mismatchedlength",
+    return BML::ml("/editicons.bml.error.rename.mismatchedlength",
                           { 'origkw' => $self->{'origkw'},
                             'newkw' => $self->{'newkw'} });
 }
@@ -1108,7 +1108,7 @@ sub fields      { qw(origkw newkw); }
 sub fields      { qw(origkw newkw); }
 sub as_html {
     my $self = shift;
-    return BML::ml("/editpics.bml.error.rename.blankkw",
+    return BML::ml("/editicons.bml.error.rename.blankkw",
                           { 'origkw' => $self->{'origkw'},
                             'newkw' => $self->{'newkw'} });
 }
@@ -1118,7 +1118,7 @@ sub fields      { qw(keyword); }
 sub fields      { qw(keyword); }
 sub as_html {
     my $self = shift;
-    return BML::ml("/editpics.bml.error.rename.keywordexists",
+    return BML::ml("/editicons.bml.error.rename.keywordexists",
                           { 'keyword' => $self->{'keyword'} });
 }
 
@@ -1127,7 +1127,7 @@ sub fields      { qw(origkw newkw); }
 sub fields      { qw(origkw newkw); }
 sub as_html {
     my $self = shift;
-    return BML::ml("/editpics.bml.error.rename.keywords",
+    return BML::ml("/editicons.bml.error.rename.keywords",
                           { 'origkw' => $self->{'origkw'},
                             'newkw' => $self->{'newkw'} });
 }
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/LJ/Widget/CreateAccount.pm
--- a/cgi-bin/LJ/Widget/CreateAccount.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/LJ/Widget/CreateAccount.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -521,7 +521,7 @@ sub handle_post {
             lostinfourl => "$LJ::SITEROOT/lostinfo",
             editprofileurl => "$LJ::SITEROOT/manage/profile/",
             searchinterestsurl => "$LJ::SITEROOT/interests",
-            editpicsurl => "$LJ::SITEROOT/editpics",
+            editiconsurl => "$LJ::SITEROOT/editicons",
             customizeurl => "$LJ::SITEROOT/customize/",
             postentryurl => "$LJ::SITEROOT/update",
             setsecreturl => "$LJ::SITEROOT/set_secret",
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/LJ/Widget/CreateAccountNextSteps.pm
--- a/cgi-bin/LJ/Widget/CreateAccountNextSteps.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/LJ/Widget/CreateAccountNextSteps.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -30,7 +30,7 @@ sub render_body {
     $ret .= "<table cellspacing='0' cellpadding='0'>";
     $ret .= "<tr valign='top'><td><ul>";
     $ret .= "<li><a href='$LJ::SITEROOT/update'>" . $class->ml('widget.createaccountnextsteps.steps.post') . "</a></li>";
-    $ret .= "<li><a href='$LJ::SITEROOT/editpics'>" . $class->ml('widget.createaccountnextsteps.steps.userpics') . "</a></li>";
+    $ret .= "<li><a href='$LJ::SITEROOT/editicons'>" . $class->ml('widget.createaccountnextsteps.steps.userpics') . "</a></li>";
     $ret .= "<li><a href='$LJ::SITEROOT/interests'>" . $class->ml('widget.createaccountnextsteps.steps.find') . "</a></li>";
     $ret .= "</ul></td><td><ul>";
     $ret .= "<li><a href='$LJ::SITEROOT/customize/'>" . $class->ml('widget.createaccountnextsteps.steps.customize') . "</a></li>";
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/LJ/Widget/UserpicDisplay.pm
--- a/cgi-bin/LJ/Widget/UserpicDisplay.pm	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/LJ/Widget/UserpicDisplay.pm	Mon Mar 08 22:25:40 2010 +0000
@@ -112,7 +112,7 @@ sub render_body {
                             userpic_preview_image.alt = alttext[userpic_select.selectedIndex];
                         } else {
                             userpic_preview.className += " userpic_preview_border";
-                            userpic_preview.innerHTML = '<a href="$LJ::SITEROOT/editpics"><img src="" alt="selected userpic" id="userpic_preview_image" style="display: none;" /><span id="userpic_msg">' + userpic_msg + '</span></a>';
+                            userpic_preview.innerHTML = '<a href="$LJ::SITEROOT/editicons"><img src="" alt="selected userpic" id="userpic_preview_image" style="display: none;" /><span id="userpic_msg">' + userpic_msg + '</span></a>';
                         }
                     }
                 }
@@ -220,7 +220,7 @@ sub render_body {
     } elsif (!$u)  {
         $$pic .= "<div id='userpic'><p id='userpic_preview'><img src='/img/nouserpic.png' alt='selected userpic' id='userpic_preview_image' class='userpic_loggedout'  /></p></div>";
     } else {
-        $$pic .= "<div id='userpic'><p id='userpic_preview' class='userpic_preview_border'><a href='$LJ::SITEROOT/editpics'>Upload a userpic</a></p></div>";
+        $$pic .= "<div id='userpic'><p id='userpic_preview' class='userpic_preview_border'><a href='$LJ::SITEROOT/editicons'>Upload a userpic</a></p></div>";
     }
 
 
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/bml/scheme/blueshift.look
--- a/cgi-bin/bml/scheme/blueshift.look	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/bml/scheme/blueshift.look	Mon Mar 08 22:25:40 2010 +0000
@@ -66,7 +66,7 @@ accountlinks<=
         my $unread = $inbox->unread_count;
         my $identity = $remote->is_identity;
 
-        $ret .= "<div id='account-links-userpic'><a href='$LJ::SITEROOT/editpics'>";
+        $ret .= "<div id='account-links-userpic'><a href='$LJ::SITEROOT/editicons'>";
 
         if ( $userpic ) {
             my $wh = $userpic->img_fixedsize( width => 80, height => 80 );
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/bml/scheme/celerity.look
--- a/cgi-bin/bml/scheme/celerity.look	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/bml/scheme/celerity.look	Mon Mar 08 22:25:40 2010 +0000
@@ -147,7 +147,7 @@ userpic<=
     my $remote = LJ::get_remote();
     my $ret;
 
-    $ret .= "<div id='header-userpic'><a href='$LJ::SITEROOT/editpics'>";
+    $ret .= "<div id='header-userpic'><a href='$LJ::SITEROOT/editicons'>";
 
     if ( $remote ) {
         my $userpic = $remote->userpic;
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/bml/scheme/global.look
--- a/cgi-bin/bml/scheme/global.look	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/bml/scheme/global.look	Mon Mar 08 22:25:40 2010 +0000
@@ -81,7 +81,7 @@ LOAD_PAGE_INFO<=
                   { 'name' => 'Your Entries',
                 'uri' => '/editjournal', },
                   { 'name' => 'Your Pictures',
-                'uri' => '/editpics', },
+                'uri' => '/editicons', },
                   { 'name' => 'Your Password',
                 'uri' => '/changepassword', },
                   ],
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/bml/scheme/gradation-vertical.look
--- a/cgi-bin/bml/scheme/gradation-vertical.look	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/bml/scheme/gradation-vertical.look	Mon Mar 08 22:25:40 2010 +0000
@@ -66,7 +66,7 @@ accountlinks<=
         my $unread = $inbox->unread_count;
         my $identity = $remote->is_identity;
 
-        $ret .= "<div id='account-links-userpic'><a href='$LJ::SITEROOT/editpics'>";
+        $ret .= "<div id='account-links-userpic'><a href='$LJ::SITEROOT/editicons'>";
         if ( $userpic ) {
             my $wh = $userpic->img_fixedsize( width => 80, height => 80 );
             $ret .= "<img src='" . $userpic->url . "' $wh alt=\"$ML{'sitescheme.accountlinks.userpic.alt'}\" />";
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/crumbs.pl
--- a/cgi-bin/crumbs.pl	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/crumbs.pl	Mon Mar 08 22:25:40 2010 +0000
@@ -67,7 +67,7 @@ use Errno qw(ENOENT);
     'managefriendgrps' => ['Manage Filters', '/manage/circle/editfilters', 'friends'],
     'managetags' => ['Manage Tags', '/manage/tags', 'manage'],
     'managelogins' => ['Manage Your Login Sessions', '/manage/logins', 'manage'],
-    'manageuserpics' => ['Manage Userpics', '/editpics', 'manage'],
+    'manageuserpics' => ['Manage Userpics', '/editicons', 'manage'],
     'memories' => ['Memorable Posts', '/tools/memories', 'manage'],
     'mobilepost' => ['Mobile Post Settings', '/manage/emailpost', 'manage'],
     'moderate' => ['Community Moderation', '/community/moderate', 'community'],
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/ljprotocol.pl	Mon Mar 08 22:25:40 2010 +0000
@@ -990,7 +990,7 @@ sub common_event_validation
 
         # need to make sure they aren't trying to post with an inactive keyword, but also
         # we don't want to allow them to post with a keyword that has no pic at all to prevent
-        # them from deleting the keyword, posting, then adding it back with editpics.bml
+        # them from deleting the keyword, posting, then adding it back with editicons.bml
         delete $req->{'props'}->{'picture_keyword'} if ! $pic || $pic->{'state'} eq 'I';
     }
 
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/redirect.dat
--- a/cgi-bin/redirect.dat	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/redirect.dat	Mon Mar 08 22:25:40 2010 +0000
@@ -9,8 +9,8 @@
 /faqbrowse.bml      /support/faqbrowse.bml
 /setscheme.bml          /manage/settings/
 /setlang.bml            /manage/settings/
-/uploadpic.bml          /editpics.bml
-/uploadpic_do.bml       /editpics.bml
+/uploadpic.bml          /editicons
+/uploadpic_do.bml       /editicons
 /modify_do.bml          /modify.bml
 /editjournal_do.bml     /editjournal.bml
 /editinfo.bml       /manage/profile/
@@ -62,3 +62,5 @@
 /syn/list.bml                       /feeds/list
 /syn/raw                            /feeds/raw
 /syn/raw.bml                        /feeds/raw
+/editpics                           /editicons
+/editpics.bml                       /editicons
diff -r 8bd7822e342b -r 4f61e7788b51 cgi-bin/weblib.pl
--- a/cgi-bin/weblib.pl	Mon Mar 08 22:09:09 2010 +0000
+++ b/cgi-bin/weblib.pl	Mon Mar 08 22:25:40 2010 +0000
@@ -1172,7 +1172,7 @@ sub entry_form {
                                     userpic_preview_image.alt = alttext[userpic_select.selectedIndex];
                                 } else {
                                     userpic_preview.className += " userpic_preview_border";
-                                    userpic_preview.innerHTML = '<a href="$LJ::SITEROOT/editpics"><img src="" alt="selected userpic" id="userpic_preview_image" style="display: none;" /><span id="userpic_msg">' + userpic_msg + '</span></a>';
+                                    userpic_preview.innerHTML = '<a href="$LJ::SITEROOT/editicons"><img src="" alt="selected userpic" id="userpic_preview_image" style="display: none;" /><span id="userpic_msg">' + userpic_msg + '</span></a>';
                                 }
                             }
                         }
@@ -1278,7 +1278,7 @@ sub entry_form {
             } elsif (!$remote || $altlogin)  {
                 $out .= "<div id='userpic'><p id='userpic_preview'><img src='/img/nouserpic.png' alt='selected userpic' id='userpic_preview_image' class='userpic_loggedout'  /></p></div>";
             } else {
-                $out .= "<div id='userpic'><p id='userpic_preview' class='userpic_preview_border'><a href='$LJ::SITEROOT/editpics'>Upload a userpic</a></p></div>";
+                $out .= "<div id='userpic'><p id='userpic_preview' class='userpic_preview_border'><a href='$LJ::SITEROOT/editicons'>Upload a userpic</a></p></div>";
             }
 
 
@@ -2701,7 +2701,7 @@ sub control_strip
         my $userpic = $remote->userpic;
         if ( $userpic ) {
             my $wh = $userpic->img_fixedsize( width => 43, height => 43 );
-            $ret .= "<td id='lj_controlstrip_userpic' style='background-image: none;'><a href='$LJ::SITEROOT/editpics'>";
+            $ret .= "<td id='lj_controlstrip_userpic' style='background-image: none;'><a href='$LJ::SITEROOT/editicons'>";
             $ret .= "<img src='" . $userpic->url . "' alt=\"$BML::ML{'web.controlstrip.userpic.alt'}\" title=\"$BML::ML{'web.controlstrip.userpic.title'}\" $wh /></a></td>";
         } else {
             my $tinted_nouserpic_img = "";
@@ -2718,7 +2718,7 @@ sub control_strip
                     }
                 }
             }
-            $ret .= "<td id='lj_controlstrip_userpic' style='background-image: none;'><a href='$LJ::SITEROOT/editpics'>";
+            $ret .= "<td id='lj_controlstrip_userpic' style='background-image: none;'><a href='$LJ::SITEROOT/editicons'>";
             if ($tinted_nouserpic_img eq "") {
                 $ret .= "<img src='$LJ::IMGPREFIX/controlstrip/nouserpic.gif' ";
             } else {
diff -r 8bd7822e342b -r 4f61e7788b51 doc/raw/build/ljconfig/ljconfig2db.pl
--- a/doc/raw/build/ljconfig/ljconfig2db.pl	Mon Mar 08 22:09:09 2010 +0000
+++ b/doc/raw/build/ljconfig/ljconfig2db.pl	Mon Mar 08 22:25:40 2010 +0000
@@ -93,7 +93,7 @@ my %ljconfig =
         'caps' => {
             'name' => "Capabilities/User Options",
             'allow_pics_over_quota' => {
-                    'desc' => "By default, when a user has more userpics than their account type allows, perhaps due to expiration of paid time, their least often used userpics (based on their journal posts) will be marked inactive. This happens whenever their account type is changed or they visit <filename>editpics.bml</filename>. They will no longer be available for use, and only the account owner may see them on <filename>editpics.bml</filename>. Turning this boolean setting true will circumvent this behavior. In other words, enabling this option lets users just keep whatever userpics they had when their account type changed.",
+                    'desc' => "By default, when a user has more userpics than their account type allows, perhaps due to expiration of paid time, their least often used userpics (based on their journal posts) will be marked inactive. This happens whenever their account type is changed or they visit <filename>editicons.bml</filename>. They will no longer be available for use, and only the account owner may see them on <filename>editicons.bml</filename>. Turning this boolean setting true will circumvent this behavior. In other words, enabling this option lets users just keep whatever userpics they had when their account type changed.",
             },
             'cap' => {
                     'desc' => "A hash that defines the capability class limits. The keys are bit numbers, from 0 &ndash; 15, and the values ".
@@ -450,7 +450,7 @@ my %ljconfig =
     );'
             },
             'disable_media_uploads' => {
-                'desc' => "Boolean to disable all media uploads/modifications that would go to &mogfs;. This puts code that interacts with &mogfs; into read-only mode: editpics.bml - users can&apos;t delete/upload userpics while in this mode, and &captcha;s - can&apos;t generate new ones or delete old ones while flag on. You might set this if you needed to turn off your &mogfs; install, for example.",
+                'desc' => "Boolean to disable all media uploads/modifications that would go to &mogfs;. This puts code that interacts with &mogfs; into read-only mode: editicons.bml - users can&apos;t delete/upload userpics while in this mode, and &captcha;s - can&apos;t generate new ones or delete old ones while flag on. You might set this if you needed to turn off your &mogfs; install, for example.",
             },
             'mogilefs_config' => {
                     'desc' => "If you are using &mogfs; on your site for userpics (the userpic factory requires &mogfs; in order to work) or other purposes, you will need to define this hash and complete the information in it. Please see also [ljconfig[userpic_mogilefs]]. The <literal>your_class</literal> element allows you to define any special &mogfs; classes you need. If you want &captcha;s to come from a &mogfs; backend, enable [ljconfig[captcha_mogilefs]]; you also need a class called &apos;captcha&apos; in your domain, as in the example.",
diff -r 8bd7822e342b -r 4f61e7788b51 doc/raw/http-interface.txt
--- a/doc/raw/http-interface.txt	Mon Mar 08 22:09:09 2010 +0000
+++ b/doc/raw/http-interface.txt	Mon Mar 08 22:25:40 2010 +0000
@@ -133,7 +133,7 @@ POST
         selecttype
         howmany
 
-editpics.bml
+editicons.bml
 GET
         authas
 POST
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/allpics.bml
--- a/htdocs/allpics.bml	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/allpics.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -177,7 +177,7 @@ _c?>
                 $body .= BML::ml('.pics.owner', {'user' => LJ::ljuser($u),});
                 my $hook_text = LJ::Hooks::run_hook('allpics_upsell_text', $u, $getextra);
                 if ($hook_text eq "") {
-                    $body .= ' ' . BML::ml('.edit4', {'aopts' => "href='$LJ::SITEROOT/editpics$getextra'"});
+                    $body .= ' ' . BML::ml('.edit4', {'aopts' => "href='$LJ::SITEROOT/editicons$getextra'"});
                 } else {
                     $body .= $hook_text;
                 }
@@ -269,7 +269,7 @@ _c?>
     } else {
         if ($can_manage) {
             $body = "<?h1 $ML{'.nopics.title'} h1?><?p ";
-            $body .= BML::ml('.nopics.text3', {'aopts' => "href='$LJ::SITEROOT/editpics$getextra#upload'"}) . " p?>";
+            $body .= BML::ml('.nopics.text3', {'aopts' => "href='$LJ::SITEROOT/editicons$getextra#upload'"}) . " p?>";
         } else {
             $body = "<?h1 $ML{'.nopics.title'} h1?><?p ". BML::ml('.nopics.text.other2', {'aopts' => "href='$LJ::SITEROOT/manage/subscriptions/user?journal=$u->{user}'", username => $u->ljuser_display }). " p?>";
         }
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/editicons.bml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/editicons.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -0,0 +1,1028 @@
+<?_c
+# This code was forked from the LiveJournal project owned and operated
+# by Live Journal, Inc. The code has been modified and expanded by
+# Dreamwidth Studios, LLC. These files were originally licensed under
+# the terms of the license supplied by Live Journal, Inc, which can
+# currently be found at:
+#
+# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
+#
+# In accordance with the original license, this code and all its
+# modifications are provided under the GNU General Public License.
+# A copy of that license can be found in the LICENSE file included as
+# part of this distribution.
+_c?>
+<?_code
+use strict;
+{
+    use vars qw(%GET %POST $title $body $head @errors);
+    use Carp qw(croak);
+
+    LJ::set_active_crumb('manageuserpics');
+    BML::set_language_scope("/editicons.bml");
+
+    my $suffix = "";
+    if (BML::get_request()->uri =~ /editicons-beta/) {
+        $suffix = "-beta";
+    }
+
+    $title = $ML{'.title3'};
+    $body = "";
+    @errors = ();
+
+    my $err = sub {
+        $title = $ML{'Error'};
+        $body = LJ::bad_input(@_);
+        return;
+    };
+
+    unless (LJ::text_in(\%POST)) {
+        return $err->("Invalid UTF-8 Input");
+    }
+
+    my $remote = LJ::get_remote();
+    unless ($remote) {
+        $body = "<?needlogin?>";
+        return;
+    }
+
+    LJ::need_res(qw(
+                    stc/lj_base.css
+                    stc/editicons.css
+                    js/progressbar.js
+                    js/ljprogressbar.js
+                    js/perlbal-uploadtrack.js
+                    js/editicons.js
+                    ));
+
+    my $authas = $GET{'authas'} || $remote->{'user'};
+    my $u = LJ::get_authas_user($authas) or
+        return $err->($ML{'error.invalidauth'});
+
+    # extra arguments for get requests
+    my $getextra = $authas ne $remote->{'user'} ? "?authas=$authas" : '';
+
+    my $returl = LJ::CleanHTML::canonical_url($POST{'ret'});
+    my $picurl = LJ::CleanHTML::canonical_url($POST{'urlpic'});
+
+    if ( $u->is_readonly ) {
+        $title = "Read-only mode";
+        $body = $LJ::MSG_READONLY_USER;
+        return;
+    }
+
+    # update this user's activated pics
+    $u->activate_userpics;
+
+    # get userpics and count 'em
+    my @userpics = LJ::Userpic->load_user_userpics($u);
+
+    # get maximum number of userpics for this user
+    my $max      = $u->count_max_userpics;
+
+    my @info;
+
+    my $factory_redirect;
+    my $no_errors = 1;
+    my $success_count = 0;
+
+    ### save/update mode
+    if (LJ::did_post()) {
+
+        ### save changes to existing pics
+        if ($POST{'action:save'}) {
+            my $refresh = update_userpics(\@userpics, $u, $err);
+
+            # push all the errors to info
+            push(@info, @errors);
+
+            # reload the pictures to account for deleted
+            @userpics = LJ::Userpic->load_user_userpics($u) if $refresh;
+        }
+
+        ### no post data, so we'll parse the multipart data
+        ### this means that we have a new pic to handle.
+        unless (%POST) {
+            my $r = DW::Request->get;
+            my $size = $r->header_in("Content-Length");
+            unless ($size) {
+                return $err->("No content-length header: can't upload");
+            }
+
+            my $MAX_UPLOAD = LJ::Userpic->max_allowed_bytes($u);
+            my $error;
+
+            # act like the factory is disabled if no mogile
+            my $factory_disabled = !LJ::is_enabled('userpicfactory') || !LJ::mogclient();
+            my $mogcli = LJ::mogclient();
+
+            # just return an error immediately if there's no mogile and the upload
+            # size is too big.
+            if (!$mogcli && ($size > $MAX_UPLOAD + 2048)) {
+                # we have to suck in the data otherwise the browser gets upset because we're
+                # closing the connection before reading in all the data and it will sometimes
+                # refuse to show the error.
+
+                # pretend to tell apache that we care about parsing the data, but we really don't
+                my $bogus = sub {return 1;};
+                BML::parse_multipart_interactive(\$error, {
+                    newheaders => $bogus,
+                    data       => $bogus,
+                    enddata    => $bogus,
+                                                 });
+
+                return $err->(BML::ml('.error.filetoolarge',
+                                      { 'maxsize' => int($MAX_UPLOAD / 1024) }));
+                                           
+            }
+
+            my $parsetomogile = !$factory_disabled && ($size > $MAX_UPLOAD + 2048);
+
+            # array of map references
+            my @uploaded_userpics; 
+
+            # three possibilites here:  small upload, in which case we 
+            # just parse it, large upload, in which case we save the
+            # files to mogile, or coming from the factory.
+            if (!$parsetomogile) {
+                # BML::parse_multipart(\%POST, \$error, $MAX_UPLOAD + 2048);
+                BML::parse_multipart(\%POST, \$error);
+
+                # couldn't parse correctly
+                if ($error) {
+                    # return parse_multipart error
+                    return $err->($error);
+                }
+
+                # parse the post parameters into an array of pics
+                @uploaded_userpics = parse_post_uploads(\%POST, $u, $MAX_UPLOAD, $factory_disabled);
+
+            } 
+
+            # if we're coming from the factory, we don't need to write
+            # to mogilefs
+            $parsetomogile = 0 if ($POST{'src'} && $POST{'src'} eq 'factory');
+
+            if ($parsetomogile) {
+                my $res = parse_large_upload(\%POST, \$error, $u, $err);
+                # large path
+
+                # was there an error parsing the multipart form?
+                if ($error) {
+                    if ($error =~ /^\[(\S+?)\]/) {
+                        my $code = $1;
+                        if ($code eq "toolarge") {
+                            return $err->(BML::ml('.error.filetoolarge',
+                                                  { 'maxsize' => int($MAX_UPLOAD / 1024) }));
+                        }
+                        $error = BML::ml("BML.parse_multipart.$code");
+                    }
+                    return $err->($error) if $error;
+                }
+
+                # parse the post parameters into an array of pics
+                @uploaded_userpics = parse_post_uploads(\%POST, $u, $MAX_UPLOAD, $factory_disabled);
+
+            } elsif ($POST{'src'} eq "factory") {
+
+                my $scaledsizemax = $POST{'scaledSizeMax'};
+                my $x1 = $POST{'x1'}+0;
+                my $x2 = $POST{'x2'}+0;
+                my $y1 = $POST{'y1'}+0;
+                my $y2 = $POST{'y2'}+0;
+                my $index = $POST{'index'};
+
+                return $err->("Invalid userpic creation parameters.") if (!$scaledsizemax || !$x2);
+
+                my $picinfo = eval {
+                    LJ::get_upf_scaled(
+                        x1 => $x1,
+                        y1 => $y1,
+                        x2 => $x2,
+                        y2 => $y2,
+                        border => $POST{'border'},
+                        userid  => $u->userid,
+                        mogkey => "upf_$index:$u->{userid}",
+                        );
+                }
+                or return $err->($ML{'.error.generatinguserpic'} . $@);
+
+                my %current_upload;
+                $current_upload{key} = "userpic_0";
+                $current_upload{image} = \${ $picinfo->[0] };
+                $current_upload{keywords} = $POST{keywords};
+                $current_upload{default} = $POST{default};
+                $current_upload{comments} = $POST{comments};
+                $current_upload{descriptions} = $POST{descriptions};
+                $current_upload{make_default} = $POST{make_default};
+                $current_upload{index} = 0;
+
+                push @uploaded_userpics, \%current_upload;
+
+            } 
+            
+            # throw an error if we didn't get a first pic.
+
+            unless (@uploaded_userpics) {
+                if ($POST{src} eq "file")  {
+                    return $err->($ML{'.error.nofile'});
+                } else {
+                    return $err->($ML{'.error.nourl'});
+                }
+            }
+            
+            my $userpic_count = scalar @userpics;
+
+            my $current_index = 0;
+            # go through each userpic and try to create it
+            foreach my $current_upload_ref (sort { $a->{"index"} cmp $b->{"index"} } @uploaded_userpics) {
+                $current_index++;
+                my $message_prefix = "";
+                if (scalar @uploaded_userpics > 1) {
+                    $message_prefix = BML::ml('.userpic', { "num" => $current_index });
+                }
+                my %current_upload = %$current_upload_ref;
+                
+                ## see if they have too many pictures uploaded
+                my $inline;
+                if ($userpic_count >= $max) {
+                    if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPicsMax')) {
+                        push @info, $inline;
+                        $no_errors = 0;
+                    } else {
+                        push @info, BML::ml('.error.toomanypics4', { "num" => $max });
+                        $no_errors = 0;
+                    }
+                } elsif ($current_upload{"error"}) {
+                    push @info, $message_prefix . "$current_upload{error}";
+                    $no_errors = 0;
+                } elsif ($current_upload{requires_factory}) {
+                    unless ($current_upload{spool_fh}) {
+                        LJ::mogclient()->store_content("upf_$current_upload{index}:$u->{userid}", "temp", $current_upload{image});
+                    }
+
+                    $factory_redirect = "$LJ::SITEROOT/tools/userpicfactory?keywords=" .
+                        BML::eurl($current_upload{keywords}) . "&comments=" .
+                        BML::eurl($current_upload{comments}) . "&descriptions=" .
+                        BML::eurl($current_upload{descriptions}) .
+                        "&imageWidth=" . BML::eurl($current_upload{imagew}) . 
+                        "&imageHeight=" . BML::eurl($current_upload{imageh}) .
+                        "&make_default=" . BML::eurl($current_upload{make_default}) . 
+                        "&index=" . BML::eurl($current_upload{index}) . '&authas=' .
+                        BML::eurl($GET{'authas'}) . '&sfx=' . BML::eurl($suffix);
+                    
+                    # go ahead and add the error message to the info string;
+                    # this will only get displayed if we don't do the redirect.
+                    push @info, $message_prefix . $ML{'.error.toolarge.separately'};
+                } else {
+                    my $userpic = eval { LJ::Userpic->create($u, data => $current_upload{image}); };
+                    if (!$userpic) {
+                        $@ = $@->as_html if $@->isa('LJ::Error');
+                        push @info, $message_prefix . "$@";
+                        $no_errors = 0;
+                    } else {
+                        my $picid = $userpic->id;
+                        
+                        push @info, $message_prefix . $ML{'.uploadsuccessful'};
+                        $success_count++;
+
+                        # make it their default pic?
+                        if ($current_upload{make_default}) {
+                            $userpic->make_default;
+                        }
+                        $userpic->set_keywords($current_upload{keywords}) if $current_upload{keywords};
+                        $userpic->set_comment($current_upload{comments})  if $current_upload{comments};
+                        $userpic->set_description($current_upload{descriptions}) if $current_upload{descriptions};
+                        $userpic->set_fullurl($current_upload{url})       if $POST{url};
+                        
+                        $userpic_count++;
+                    }
+                }
+                
+            }
+            # yay we created new pics, reload the @userpics
+            @userpics = LJ::Userpic->load_user_userpics($u);
+        }
+        
+        if ($factory_redirect && $no_errors) {
+            if ($success_count) {
+                $factory_redirect .= '&successcount=' . $success_count;
+            }
+            return BML::redirect($factory_redirect);
+        }
+
+        # now fall through to edit page and show the updated userpic info
+        # redirect back to ourselves
+        $returl = LJ::CleanHTML::canonical_url($POST{'ret'});
+        if ($returl) {
+            my $redir_host;
+            $redir_host = $1 if $returl =~ m!^http://([\.:\w-]+)!i;
+            return BML::redirect($returl) if $LJ::REDIRECT_ALLOWED{$redir_host};
+        }
+    }
+
+    # authas switcher form
+    $body .= "<form method='get' id='userpic_authas' action='editicons$suffix'>\n";
+    $body .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} }) . "\n";
+    $body .= "</form>\n\n";
+
+    # if we're disabling media, say so
+    $body .= "<?warningbar $ML{'error.mediauploadsdisabled'} warningbar?>"
+        if $LJ::DISABLE_MEDIA_UPLOADS;
+
+    if (@info) {
+        $body .= '<div class="warningbar">';
+        $body .= "<div>$_</div>" foreach @info;
+        $body .= '</div>';
+    }
+
+    # print out upload pic box
+    my $emit_upload_box = sub {
+        $body .= '<a name="uploadBox"></a>';
+        if (scalar @userpics < $max) {
+
+            # upload form (with perlbal upload-tracking)
+            $body .= qq {
+                <iframe name='upiframe' width='1' height='1' style='border: none'></iframe>
+                <div id='uploadBox' class='pkg'><div id='uploadBox-inner'>
+                    <form enctype="multipart/form-data" action="editicons$suffix$getextra" method='post' id='uploadPic'>
+                    <input type="hidden" id="go_to" name="go_to" value="editicons$suffix$getextra" />
+            };
+
+            $body .= "<?h1 $ML{'.uploadheader'} h1?>\n";
+            $body .= "<p class='detail'><a href='javascript:void(0)' onclick='toggleElement(\"upload_desc\")' id='upload_desc_link'>$ML{'.about.icons'}</a></p>";
+            $body .= "<div id='upload_desc'>";
+            $body .= "<?p $ML{'.uploaddesc'} p?>\n";
+            $body .= "</div><!-- end #uploaddesc -->";
+
+            $body .= "<div id='upload_wrapper' class='pkg'>\n";
+            $body .= "<p class='pkg'>\n";
+            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'src', 'id' => 'radio_file',
+                                      'class' => 'radio', 'value' => 'file', 'selected' => '1', 
+                                      'accesskey' => $ML{'.fromfile.key'} }) . "\n";
+            $body .= "<label for='radio_file'>$ML{'.fromfile'}</label><br />\n";
+            $body .= "<input type='file' class='file' name='userpic_0' id='userpic_0' size='18' style='margin: 0em 0em 0.5em 2em;' />\n";
+            $body .= "</p>\n";
+            $body .= "<p class='pkg'>\n";
+            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'src', 'value' => 'url',
+                                      'id' => 'radio_url', 'class' => 'radio', 'accesskey' => $ML{'.fromurl.key'} }) . "\n";
+            $body .= "<label for='radio_url'>$ML{'.fromurl'}</label><br />\n";
+            $body .= LJ::html_text({ 'name' => 'urlpic_0', 'id' => 'urlpic_0', class => 'text', style => 'margin: 0em 0em 0.5em 2em;' }) . "\n";
+            $body .= "</p>\n";
+            $body .= "<p class='detail'>$ML{'.label.formats.desc'}</p>\n";
+            $body .= "</div>\n";
+
+            $body .= "<hr class='hr' />";
+
+            $body .= "<p class='pkg'>\n";
+            $body .= "<label class='left' for='keywords_0'>$ML{'.label.keywords'}</label>\n";
+            $body .= "<span class='input-wrapper'>";
+            $body .= LJ::html_text({ 'name' => 'keywords_0', class => 'text', id => 'keywords_0' }) . "\n";
+            $body .= LJ::help_icon_html('upic_keywords') . "\n";
+            $body .= "</span>";
+            $body .= "</p>\n";
+            $body .= "<p class='detail'>$ML{'.label.keywords.desc'}</p>\n";
+
+            $body .= "<p class='pkg'>\n";
+            $body .= "<label class='left' for='comments_0'>$ML{'.label.comment'}</label>\n";
+            my $comments = $POST{'comments'};
+            $body .= "<span class='input-wrapper'>";
+            $body .= LJ::html_text({ 'name' => 'comments_0', 'class' => 'text', id => 'comments_0', 'maxlength' => LJ::CMAX_UPIC_COMMENT, 'value', $comments }) . "\n";
+            $body .= LJ::help_icon_html('upic_comments') . "\n";
+            $body .= "</span>";
+            $body .= "</p>\n";
+            $body .= "<p class='detail'>$ML{'.label.comment.desc'}</p>\n";
+
+            $body .= "<p class='pkg'>\n";
+            $body .= "<label class='left' for='descriptions_0'>$ML{'.label.description'}</label>\n";
+            my $descriptions = $POST{'descriptions'};
+            $body .= "<span class='input-wrapper'>";
+            $body .= LJ::html_text( { name => 'descriptions_0', class => 'text', id => 'descriptions_0', 'maxlength' => LJ::CMAX_UPIC_DESCRIPTION, value => $descriptions } ) . "\n";
+            $body .= LJ::help_icon_html('upic_descriptions') . "\n";
+            $body .= "</span>";
+            $body .= "</p>\n";
+            $body .= "<p class='detail'>$ML{'.label.description.desc'}</p>\n";
+
+            $body .= "<p class='pkg'>\n";
+            $body .= LJ::html_check({ 'type' => 'checkbox',
+                                      'name' => 'make_default',
+                                      'id' => 'make_default_0',
+                                      'value' => '0',
+                                      'selected' => @userpics ? 0 : 1,
+                                      'accesskey' => $ML{'.makedefault.key'} });
+
+            $body .= "<label for='make_default_0'>$ML{'.makedefault'}</label>\n";
+            $body .= "</p>\n";
+            
+            # adding multi-upload option if mogile is enabled
+            
+            my $remaining_uploads = $max - scalar @userpics;
+            if ($remaining_uploads >= 2 && LJ::mogclient()) {
+                $body .= "<div id='multi_insert'></div>";
+                $body .= "<div id='no_default_insert'></div>";
+                $body .= "<p class='pkg' id='multi_insert_buttons'>\n";
+
+                $body .= "<input type='button' value='$ML{'.btn.addfile'}' onclick='javascript:addNewUpload(\"file\");' /> <input type='button' value='$ML{'.btn.addurl'}' onclick='javascript:addNewUpload(\"url\");'/>\n";
+                $body .= "<script type='text/javascript'>\n";
+                $body .= "maxcounter = $remaining_uploads;\n";
+                $body .= "allowComments = true;\n";
+                $body .= "allowDescriptions = true;\n";
+
+                $body .= "ep_labels.comment = '$ML{'.label.comment'}';\n";
+                $body .= "ep_labels.description = '$ML{'.label.description'}';\n";
+                $body .= "ep_labels.fromfile = '$ML{'.fromfile'}';\n";
+                $body .= "ep_labels.fromurl = '$ML{'.fromurl'}';\n";
+                $body .= "ep_labels.keepdefault = '$ML{'.label.keepdefault'}';\n";
+                $body .= "ep_labels.keywords = '$ML{'.label.keywords'}';\n";
+                $body .= "ep_labels.makedefault = '$ML{'.makedefault'}';\n";
+                $body .= "ep_labels.makedefaultkey = '$ML{'.makedefault.key'}';\n";
+                $body .= "ep_labels.remove = '$ML{'.btn.remove'}';\n";
+                
+                $body .="</script>\n";
+                $body .= "</p>\n";
+            }
+
+            $body .= "<p class='pkg' id='submit_wrapper'>";
+            $body .= LJ::html_submit(undef, $ML{'.btn.proceed'},
+                                     { disabled => $LJ::DISABLE_MEDIA_UPLOADS });
+            $body .= "</p>\n";
+            $body .= q {
+                    </form>
+                    </div></div><!-- end #uploadBox -->
+                    <div id="uploadStatus" style="display: none;"></div>
+                    <div id="progressBar" style="display: none;"></div>
+                };
+
+        } else {
+            $body .= "<div id='limit'>\n";
+            my $inline;
+            if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPicsMax')) {
+                $body .= $inline;
+            } else {
+                $body .= BML::ml('.error.toomanypics_standout', { num => $max });
+            }
+            $body .= "</div><!-- end #limit -->";
+        }
+        $body .= " \n\n";
+    };
+
+    $emit_upload_box->();
+
+    # print out each pic and editing fields
+    if ( scalar @userpics ) {
+        $body .= "<div id='current_userpics'>";
+        $body .= "<form method='post' action='editicons$suffix$getextra'>";
+        $body .= LJ::form_auth();
+
+        $body .= qq {
+                <?h1 $ML{'.curpics'} h1?>
+                <?p $ML{'.curpics.desc2'} p?>
+                <div class='EditIconsStatus'>
+            };
+
+        $body .= "<p><strong>" . BML::ml('.piclimitstatus', {current => scalar @userpics, max => $max}) . "</strong></p>";;
+        if (scalar @userpics >= $max) {
+            my $inline;
+            if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPics')) {
+                $body .= "<?warningbar" . $inline . "warningbar?>";
+            } else {
+                $body .= "<p>".BML::ml('cprod.editpics.text7.v1',{ "num" => $max })."</p>";
+            }
+        }
+        $body .= "</div>";
+
+        $body .= "<div id='list_userpics' style='width: 98%; float: left;'>";
+        my $display_rename = LJ::theschwartz() ? 1 : 0;
+
+        foreach my $pic (@userpics) {
+            my $pid = $pic->id;
+            
+            $body .= "<div class='pkg userpic_wrapper'>";
+            $body .= "<span class='EditIconsUserpic'>" .  $pic->imgtag . "</span>\n";
+
+            # TODO: if no keywords then light grey text and empty out when you click in it
+            my $keywords = $pic->keywords;
+            my $comment = $pic->comment;
+            my $description = $pic->description;
+            $body .= "<div class='userpic_controls'  style='float: left; width: auto;'>";
+            $body .= "<div class='userpic_keywords pkg'>\n";
+            $body .= "<label class='left' for='kw_$pid'>$ML{'.label.keywords'}</label>\n ";
+            $body .= LJ::html_text({'name' => "kw_$pid", 'class' => "text", 'id' => "kw_$pid",
+                                    'value' => $keywords,
+                                    'disabled' => $pic->inactive,
+                                    'onfocus' => $display_rename ? "\$(\'rename_div_$pid\').style.display = \'block\';" : ""
+                                   }) . "\n";
+            $body .= LJ::html_hidden({ 'name' => "kw_orig_$pid",
+                                       'value' => $keywords }) . "\n";
+            if ($display_rename) {
+                $body .= "<div id='rename_div_$pid' class='userpic_rename pkg'>\n";
+                $body .= "<script type='text/javascript'>document.getElementById('rename_div_$pid').style.display = 'none';</script>\n";
+                $body .= LJ::html_check({ 'type' => 'checkbox', 'name' => "rename_keyword_$pid", 'class' => "checkbox",
+                                          'id' => "rename_keyword_$pid", 'value' => 1,
+                                          'disabled' => $LJ::DISABLE_MEDIA_UPLOADS });
+                $body .= "<label for='rename_keyword_$pid'>$ML{'.label.rename'}</label>"; 
+                $body .= "</div>\n";
+            }
+            $body .= "</div>\n";
+
+            $body .= "<div class='userpic_comments pkg'>\n";
+            $body .= "<label class='left' for='com_$pid'>$ML{'.label.comment'}</label>\n ";
+            $body .= LJ::html_text({ 'name' => "com_$pid", 'class' => "text", 'id' => "com_$pid",
+                                     'value' => $comment,
+                                     'maxlength' => LJ::CMAX_UPIC_COMMENT,
+                                     'disabled' => $pic->inactive }) . "\n";
+            $body .= LJ::html_hidden({ 'name' => "com_orig_$pid",
+                                       'value' => $comment }) . "\n";
+
+            $body .= "</div>\n";
+            
+            $body .= "<div class='userpic_descriptions pkg'>\n";
+            $body .= "<label class='left' for='desc_$pid'>$ML{'.label.description'}</label>\n ";
+            $body .= LJ::html_text({ 'name' => "desc_$pid", 'class' => "text", 'id' => "desc_$pid",
+                                     'value' => $description,
+                                     'maxlength' => LJ::CMAX_UPIC_DESCRIPTION,
+                                     'disabled' => $pic->inactive }) . "\n";
+            $body .= LJ::html_hidden({ 'name' => "desc_orig_$pid",
+                                       'value' => $description }) . "\n";
+
+            $body .= "</div>\n";
+        
+            $body .= "<div class='userpic_defaultdelete pkg'>";
+            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'defaultpic', 'class' => "radio", 'value' => $pid,
+                                      'selected' => $pic->is_default ? 1 : 0,
+                                      'id' => "def_$pid",
+                                      'disabled' => $pic->inactive });
+            $body .= "<label class='userpic_default_label' for='def_$pid'>$ML{'.label.default'}</label> ";
+            $body .= LJ::html_check({ 'type' => 'checkbox', 'name' => "delete_$pid", 'class' => "checkbox",
+                                      'id' => "del_$pid", 'value' => 1,
+                                      'disabled' => $LJ::DISABLE_MEDIA_UPLOADS });
+            $body .= "<label for='del_$pid'>$ML{'.label.delete'}</label>"; 
+            if ($pic->inactive) {
+                $body .= " &nbsp;<i>[$ML{'userpic.inactive'}]</i> " . LJ::help_icon('userpic_inactive');
+            }
+            $body .= "</div>";
+            $body .= "</div>";
+            $body .= "</div>";
+            $body .= "<hr class='hr' />";
+        }
+
+        $body .= "</div><!-- end #list_userpics -->";
+        # no default userpic
+        $body .= "<p id='no_default_userpic' style='clear: both;'>";
+        $body .= LJ::html_check({ 'name' => 'defaultpic',
+                                  'value' => 0,
+                                  'type' => 'radio',
+                                  'class' => 'radio',
+                                  'selected' => $u->{'defaultpicid'} == 0,
+                                  'raw' => "id='nodefpic'" });
+        $body .= "<label for='nodefpic'>$ML{'.nodefault'}</label></p>";
+        $body .= "<?standout" . LJ::html_submit('action:save', $ML{'.btn.save'}) . "standout?>";
+        $body .= "</form>";
+        $body .= "</div><!-- end #current_userpics -->";
+        $body .= "<script type='text/javascript'>\n";
+        $body .= "editiconsInit();\n";
+        $body .= "</script>\n";
+
+    } else {
+        $body .= qq {
+                <?h1 $ML{'.nopics'} h1?>
+                <?p $ML{'.noneupload2'} p?>
+            };
+    }
+
+    
+    return;
+}
+
+sub update_userpics
+{
+    my $userpicsref = shift;
+    my $u = shift;
+    my @userpics = @$userpicsref;
+    my $err = shift;
+    
+    
+    # form being posted isn't multipart, since we were able to read from %POST
+    unless (LJ::check_form_auth()) {
+        return $err->($ML{'error.invalidform'});
+    }
+    
+    my @delete; # userpic objects to delete
+    my @inactive_picids;
+    my %picid_of_kwid;
+    my %used_keywords;
+    
+    # we need to count keywords based on what the user provided, in order
+    # to find duplicates. $up->keywords doesn't work, because re-using a
+    # keyword will remove it from the other userpic without our knowing
+    my $count_keywords = sub {
+        my $kwlist = shift;
+        $used_keywords{$_}++ foreach split(/,\s*/, $kwlist);
+    };
+
+    foreach my $up (@userpics) {
+
+        my $picid = $up->id;
+        
+        # delete this pic
+        if ($POST{"delete_$picid"}) {
+            push @delete, $up;
+            next;
+        }
+        
+        # we're only going to modify keywords/comments on active pictures
+        if ($up->inactive) {
+            # use 'orig' because we don't POST disabled fields
+            $count_keywords->($POST{"kw_orig_$picid"});
+            next;
+        }
+        
+        $count_keywords->($POST{"kw_$picid"});
+        
+        # only modify if changing the data, make sure not collidiing with other edits, etc
+        if ($POST{"kw_$picid"} ne $POST{"kw_orig_$picid"}) {
+            my $kws = $POST{"kw_$picid"};
+            
+            if ($POST{"rename_keyword_$picid"}) {
+                eval {
+                    $up->set_and_rename_keywords($kws, $POST{"kw_orig_$picid"});
+                } or push @errors, $@->as_html;
+            } else {
+                eval {
+                    $up->set_keywords($kws);
+                } or push @errors, $@;
+            }
+        }
+        
+        eval {
+            $up->set_comment ($POST{"com_$picid"})
+                unless $POST{"com_$picid"} eq $POST{"com_orig_$picid"};
+        } or push @errors, $@;
+        
+        eval {
+            $up->set_description ($POST{"desc_$picid"})
+                unless $POST{"desc_$picid"} eq $POST{"desc_orig_$picid"};
+        } or push @errors, $@;
+
+    }
+    
+    foreach my $kw (keys %used_keywords) {
+        next unless $used_keywords{$kw} > 1;
+        push @errors, BML::ml('.error.keywords', {ekw => $kw});
+    }
+    
+    if (@delete && $LJ::DISABLE_MEDIA_UPLOADS) {
+        push @errors, $ML{'.error.nomediauploads.delete'};
+        
+    } elsif (@delete) {
+        
+        # delete pics
+        foreach my $up (@delete) {
+            eval { $up->delete; } or push @errors, $@;
+        }
+        
+        # if any of the userpics they want to delete are active, then we want to
+        # re-run activate_userpics() - turns out it's faster to not check to
+        # see if we need to do this
+        $u->activate_userpics;
+    }
+    
+    my $new_default = $POST{'defaultpic'}+0;
+    if ($POST{"delete_${new_default}"}) {
+        # deleting default
+        $new_default = 0;
+    }
+    
+    if ($new_default && $new_default != $u->{'defaultpicid'}) {
+        my ($up) = grep { $_->id == $new_default } @userpics;
+        
+        # see if they are trying to make an inactive userpic their default
+        if ($up && !$up->inactive) {
+            $up->make_default;
+        }
+    } elsif ($new_default eq '0' && $u->{'defaultpicid'}) {
+        # selected the "no default picture" option
+        LJ::update_user($u, { defaultpicid => 0 });
+        $u->{'defaultpicid'} = 0;
+    }
+    
+    return scalar @delete;
+}
+
+sub parse_post_uploads
+{
+    my $postref = shift;
+    my %POST = %$postref;
+    my $u = shift;
+    my $MAX_UPLOAD = shift;
+    my $factory_disabled = shift;
+
+
+    my @uploads;
+    
+    # if we find a userpic that requires the factory, save it here.
+    # we can only have one.
+    my $requires_factory;
+    
+    # go through each key and create a %current_upload for it, then
+    # put it in @uploads.
+    foreach my $userpic_key (keys %POST) {
+        # uploaded pics
+        if ($userpic_key =~ /userpic_.*/) {
+            # only use userpic_0 if we selected file for the source    
+            unless ($userpic_key eq "userpic_0" && $POST{"src"} ne "file") {
+                # copy all of the basic settings into the hash.
+                my %current_upload;
+                $current_upload{key} = $userpic_key;
+                my @tokens = split(/_/, $userpic_key);
+                my $counter = $tokens[1];
+                $current_upload{keywords} = $POST{"keywords_$counter"};
+                $current_upload{comments} = $POST{"comments_$counter"};
+                $current_upload{descriptions} = $POST{"descriptions_$counter"};
+                $current_upload{index} = $counter;
+                $current_upload{image} = \$POST{$userpic_key};
+                $current_upload{make_default} =  ($POST{"make_default"} eq $counter);
+
+                # check the image size.
+                my $imgdata = $POST{"spool_fh_$counter"} ? $POST{"spool_fh_$counter"} : \$POST{$userpic_key};
+                my $size = length($$imgdata);
+                
+                if ($size == 0) {
+                    $current_upload{error} = $ML{'.error.nofile'};
+                } else {
+                    my ($imagew, $imageh, $filetype) = Image::Size::imgsize($imgdata);
+                    my $size = length($imgdata);
+                    
+                    if (!$imagew || !$imageh) {
+                        # couldn't parse the file
+                        $current_upload{error} = BML::ml(".error.unsupportedtype", {filetype => $filetype});
+                    } elsif ($imagew > 5000 || $imageh > 5000) {
+                        # file is too big, no matter what.
+                        $current_upload{error} = "The dimensions of this image are too large.";
+                    } elsif (int($imagew) > 100 || int($imageh) > 100 || $size > $MAX_UPLOAD) {
+                        # file is too large.  
+                        if ($factory_disabled) {
+                            if (int($imagew) > 100 || int($imageh) > 100) {
+                                $current_upload{error} = BML::ml('.error.imagetoolarge', {imagesize => "${imagew}x$imageh"});
+                            } else {
+                                $current_upload{error} = BML::ml('.error.filetoolarge', { 'maxsize' => int($MAX_UPLOAD / 1024) });
+                            }
+                        } elsif ($filetype ne 'JPG' && $filetype ne 'PNG') {
+                            # factory only works on jpegs and pngs because Image::Magick has issues
+                            if (int($imagew) > 100 || int($imageh) > 100) {
+                                $current_upload{error} = $ML{'.error.giffiledimensions'};
+                            } else {
+                                $current_upload{error} = BML::ml('.error.filetoolarge', { 'maxsize' => int($MAX_UPLOAD / 1024)});
+                            }
+                        } elsif ($imagew <= 100 && $imageh <= 100) {
+                            # if it's the right size, just too large a file, see if we can
+                            # resize it down
+                            unless ($POST{"spool_file_name_$counter"}) {
+                                LJ::mogclient()->store_content("upf_${counter}:$u->{userid}", "temp", \$POST{$userpic_key});
+                            }
+                            
+                            eval {
+                                my $picinfo = LJ::get_upf_scaled(
+                                    size => 100,
+                                    u    => $u,
+                                    mogkey => "upf_${counter}:$u->{userid}"
+                                    );
+                                
+                                # success! don't go to the factory, and pretend the user just uploaded the file
+                                # and continue on normally
+                                $current_upload{image} = \${ $picinfo->[0] };
+                            };
+                            
+                            if ($@ || (length($POST{$userpic_key}) > $MAX_UPLOAD)) {
+                                $current_upload{error} = ML::ml('.error.filetoolarge', {maxsize => int($MAX_UPLOAD / 1024) });
+                            }
+                        } else {
+                            # this is a candidate for the userpicfactory.
+                            
+                            # we can only do a single pic in the factory, so if there are two,
+                            # then error out for both.
+                            if ($requires_factory) {
+                                $requires_factory -> {error} = $ML{'.error.multipleresize'};
+                                $current_upload{error} = $ML{'.error.multipleresize'};
+                                $requires_factory->{requires_factory} = 0;
+                            } else {
+                                $current_upload{requires_factory} = 1;
+                                $current_upload{imageh} = $imageh;
+                                $current_upload{imagew} = $imagew;
+                                if ($POST{"spool_fh_$counter"}) {
+                                    $current_upload{spool_fh} = $POST{"spool_fh_$counter"};
+                                }
+                                $requires_factory = \%current_upload;
+                            }
+                        }
+                    } else {
+                        # valid file; just add it as given.
+                        if ($POST{"spool_file_name_$counter"}) {
+                            $current_upload{image} = LJ::mogclient()->get_file_data($POST{"spool_file_name_$counter"});
+                        }
+                    }
+                }
+                push @uploads, \%current_upload;
+            }
+        } elsif ($userpic_key =~ /urlpic_.*/) {
+            # go through the URL uploads
+            unless ($userpic_key eq "urlpic_0" && $POST{src} ne "url") {
+                # copy all of the basic settings into the hash.
+                my %current_upload;
+                $current_upload{key} = $userpic_key;
+                my @tokens = split(/_/, $userpic_key);
+                my $counter = $tokens[1];
+                $current_upload{keywords} = $POST{"keywords_$counter"};
+                $current_upload{comments} = $POST{"comments_$counter"};
+                $current_upload{descriptions} = $POST{"descriptions_$counter"};
+                $current_upload{index} = $counter;
+                $current_upload{make_default} =  ($POST{"make_default"} eq $counter);
+
+                if (! $POST{$userpic_key}) {
+                    $current_upload{error} = $ML{'.error.nourl'};
+                } elsif ($POST{$userpic_key} !~ /^http:\/\//) {
+                    $current_upload{error} = $ML{'.error.badurl'};
+                } else {
+                    my $ua = LJ::get_useragent(
+                        role     => 'userpic',
+                        max_size => $MAX_UPLOAD + 1024,
+                        timeout  => 10,
+                        );
+                    my $res = $ua->get($POST{$userpic_key});
+                    $current_upload{image} = \$res->content if $res && $res->is_success;
+                    $current_upload{error} = $ML{'.error.urlerror'} unless $current_upload{image};
+                    #Below, $current_upload{image} needs to be dereferenced because it contains a hash value.
+                    $current_upload{error} = $ML{'.error.urlfiletoolarge'} if length( ${ $current_upload{image} } ) > $MAX_UPLOAD;
+                }
+                push @uploads, \%current_upload;
+            }
+        }
+    }
+
+    return @uploads;
+}
+
+sub parse_large_upload 
+{
+    my $postref = shift;
+    my $errorref = shift;
+    my $user = shift;
+    my $err = shift;
+
+    my %upload = (); # { spool_fh, spool_path, filename, bytes, md5sum, md5ctx, mime }
+    my @uploaded_files = ();
+    my $curr_name;
+
+    # called when the beginning of an upload is encountered
+    my $hook_newheaders = sub {
+        my ($name, $filename) = @_;
+
+        # for uploaded files, just set POST value to filename
+        $postref->{$name} = '';
+        
+        $curr_name = $name;
+        
+        return 1 unless $curr_name =~ /userpic.*/;
+        
+        # new file, need to create a filehandle, etc
+        %upload = ();
+        $upload{filename} = $filename;
+        $upload{md5ctx} = new Digest::MD5;
+        
+        # get MogileFS filehandle
+        return $err->("Sorry, MogileFS must be running to handle the uploading of large images.") unless LJ::mogclient();
+        
+        my @tokens = split(/_/, $curr_name);
+        my $counter = $tokens[1];
+
+        $upload{spool_file_name} = "upf_${counter}:$user->{userid}";
+        $upload{spool_fh} = LJ::mogclient()->new_file($upload{spool_file_name}, 'temp')
+            or die "Failed to open MogileFS tempfile";
+        
+        push @uploaded_files, $upload{spool_file_name};
+        return 1;
+    };
+    
+    # called as data is received
+    my $hook_data = sub {
+        my ($len, $data) = @_;
+        
+        unless ($curr_name =~ /userpic.*/) {
+            $postref->{$curr_name} .= $data;
+            return 1;
+        }
+
+        # check that we've not exceeded the max read limit
+        my $max_read = (1<<20) * 5; # 5 MiB
+        my $len_read = 0;
+        
+        $len_read = ($upload{bytes} += $len);
+        
+        die "Upload max exceeded at $len_read bytes"
+            if $len_read > $max_read;
+        
+        $upload{md5ctx}->add($data);
+        $upload{spool_fh}->print($data);
+
+        return 1;
+    };
+    
+    # called when the end of an upload is encountered
+    my $hook_enddata = sub {
+        return 1 unless $curr_name =~ /userpic.*/;
+
+        # since we've just finished a potentially slow upload, we need to
+        # make sure the database handles in DBI::Role's cache haven't expired,
+        # so we'll just trigger a revalidation now so that subsequent database
+        # calls will be safe.
+        $LJ::DBIRole->clear_req_cache();
+        
+        # don't try to operate on 0-length spoolfiles
+        unless ($upload{bytes}) {
+            %upload = ();
+            return 1;
+        }
+
+        # read magic and try to determine formatid of uploaded file. This
+        # doesn't use fh->tell and fh->seek because the filehandle is
+        # sysopen()ed, so isn't really an IO::Seekable like an IO::File
+        # filehandle would be.
+        my $magic;
+        tell $upload{spool_fh}
+        or die "read offset is 0, empty file?";
+        seek $upload{spool_fh}, 0, 0;
+
+        # $! should always be set in this case because a failed read will
+        # always be an error, not EOF, which is handled above (tell)
+        $upload{spool_fh}->read($magic, 20)
+            or die "Couldn't read magic: $!";
+        
+        $upload{spool_fh}->close
+            or die "Can't close Mogile filehandle";
+        
+        my $format_magic = sub {
+            my $magic = shift;
+            my $hex = unpack "H*", $magic;
+            my $mime;
+            
+            # image formats
+            $mime = 'image/jpeg' if $magic =~ /^\xff\xd8/; # JPEG
+            $mime = 'image/gif'  if $magic =~ /^GIF8/;     # GIF
+            $mime = 'image/png'  if $magic =~ /^\x89PNG/;  # PNG
+            
+            return $mime;
+        };
+        
+        $upload{mime} = $format_magic->( $magic );
+        unless ( $upload{mime} ) {
+            $$errorref = "Unknown format for upload";
+            return $err->( $$errorref );
+        }
+        
+        # finished adding data for md5, create digest (but don't destroy original)
+        $upload{md5sum} = $upload{md5ctx}->digest;
+        
+        my @tokens = split(/_/, $curr_name);
+        my $counter = $tokens[1];
+
+        $postref->{$curr_name} = $upload{spool_fh};
+        $postref->{"spool_file_name_$counter"} = $upload{spool_file_name};
+        $postref->{"spool_fh_$counter"} = $upload{spool_fh};
+
+        return 1;
+    };
+    
+    
+    # parse multipart-mime submission, one chunk at a time,
+    # calling our hooks as we go to put uploads in temporary
+    # MogileFS filehandles
+    my $retval = eval { BML::parse_multipart_interactive($errorref, {
+        newheaders => $hook_newheaders,
+        data       => $hook_data,
+        enddata    => $hook_enddata,
+                                                         }); };
+    
+    # if BML::Parse_multipart_interactive failed, we need to add
+    # all of our gpics to the gpic_delete queue.  if any of them
+    # still have refcounts, they won't really be deleted because
+    # the async job will realize and leave them alone
+    unless ($retval) {
+        # if we hit a parse error, delete the uploaded files
+        foreach my $mogkey (@uploaded_files) {
+            LJ::mogclient()->delete($mogkey);
+        }
+
+        if (index(lc($$errorref), 'unknown format') == 0) {
+            return $err->(BML::ml(".error.unknowntype"));
+        }
+        return $err->("couldn't parse upload: $$errorref");
+    }
+
+    return $retval;
+}
+
+_code?><?page
+    head=><?_code return $head; _code?>
+    title=><?_code return $title; _code?>
+    body=><?_code return $body; _code?>
+    page?>
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/editicons.bml.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/editicons.bml.text	Mon Mar 08 22:25:40 2010 +0000
@@ -0,0 +1,145 @@
+;; -*- coding: utf-8 -*-
+
+.about.icons=About Icons
+
+.btn.addfile=Add File
+
+.btn.addurl=Add URL
+
+.btn.proceed=Proceed
+
+.btn.remove=Remove
+
+.btn.save=Save Settings
+
+.curpics=Current Pictures
+
+.curpics.desc2=Here are the pictures you've uploaded in the past. You can assign keywords to them so you can use them by keyword later, select which one to use as your default, or delete old ones. To upload a new one, use the form at the top of the page.
+
+.error.badurl=The address for the picture to be uploaded does not look correct.  It should start with <b>http://</b>
+
+.error.filetoolarge=Image uploaded is too large.  File size cannot exceed [[maxsize]] KB.
+
+.error.generatinguserpic=There was an error in generating the userpic: 
+
+.error.giffiletoolarge=The GIF image you uploaded is too large.  GIF file size cannot exceed [[maxsize]].
+
+.error.giffiledimensions=Sorry, you cannot upload a userpic larger than 100x100 pixels if it is in GIF format.
+
+.error.imagetoolarge=The dimensions of your image ([[imagesize]]) exceed maximum size.  Your picture can only be 100x100 pixels large.  Use a image/photo editing program to reduce the image to thumbnail-size.
+
+.error.invalidimage=Invalid image file.
+
+.error.keywords=You used the keyword "[[ekw]]" for multiple pictures.  One was randomly chosen, but likely not the one you wanted.  You may want to go back and fix that.
+
+.error.multipleresize=Error:  only one image requiring resizing may be sent.
+
+.error.nofile=You must choose a file to upload
+
+.error.nourl=You must enter the URL of an image
+
+.error.nomediauploads.delete=Unable to delete userpics at this time.  Media modification is currently disabled for the site.
+
+.error.rename.blankkw=Error renaming '[[origkw]]' to '[[newkw]]':  renaming of blank (pic#) keywords not allowed.
+
+.error.rename.keywordexists=Cannot rename to '[[keyword]]':  keyword already exists.
+
+.error.rename.keywords=An error occurred trying to rename '[[origkw]]' to '[[newkw]]'; entries and comments with the old keywords may not have changed to use the new keywords.
+
+.error.rename.mismatchedlength=Error renaming '[[origkw]]' to '[[newkw]]':  must rename to the same number of keywords.
+
+.error.toolarge.separately=Image is too large; please submit it separately to resize.
+
+.error.toomanykeywords=The [[?numwords|keyword|keywords]] "[[words]]" [[?numwords|has|have]] not been saved as [[?numwords|its|their]] user picture icon already has [[max]] keywords.
+
+.error.toomanypics4=You are already at your limit of [[num]] [[?num|userpic|userpics]]. You cannot upload this userpic until you delete <a [[aopts]]>one of your existing ones</a>.
+
+.error.toomanypics_standout=You are at your limit of [[num]] [[?num|userpic|userpics]]. You cannot upload any more userpics until you delete one of your existing ones.
+
+.error.unknowntype=You can only upload GIF, PNG, or JPG files.
+
+.error.unsupportedtype=Files of type [[filetype]] are not supported.  You can only upload GIF, PNG or JPG files.  Nearly all image/photo programs can do this conversion for you.
+
+.error.urlerror=An error ocurred while trying to fetch your image.
+
+.error.urlfiletoolarge=You cannot upload large images from URLs.
+
+.fromfile=From <u>F</u>ile:
+
+.fromfile.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".fromfile". This is the shortcut key for the fromfile option.
+.fromfile.key=f
+
+.fromurl=From U<u>R</u>L:
+
+.fromurl.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".fromurl". This is the shortcut key for the fromurl option.
+.fromurl.key=r
+
+.imagesize.by|notes=This character is inserted between two numbers to indicate "by" when specifying image dimensions, for example "100x100".
+.imagesize.by=x
+
+.label.comment=Comment:
+
+.label.comment.desc=Optional comments about the picture. Credit can go here. Example: "I made this!"
+
+.label.default=Default
+
+.label.delete=Delete
+
+.label.description=Description:
+
+.label.description.desc=Optional description of what is in the picture. Shown to people who cannot view the image, e.g. blind people using screen readers. Example: "Photo of me in the mirror, holding up camera"
+
+.label.formats.desc=Acceptable formats are GIF, JPG and PNG.
+
+.label.keepdefault=Keep existing default pic.
+
+.label.keywords=Keywords:
+
+.label.keywords.desc=Comma-separated list of terms you'll use to select this picture.
+
+.label.rename=Rename Keywords
+
+.makedefault=Make this your <u>d</u>efault picture
+
+.makedefault.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".makedefault". This is the shortcut key for the makedefault option.
+.makedefault.key=d
+
+.nodefault=No Default Picture
+
+.noneupload=You have no pictures uploaded.  Please upload one using the form below.
+
+.noneupload2=You have no pictures uploaded.  Please upload one using the form above.
+
+.nopics=No Pictures
+
+.piclimitstatus=Currently uploaded: [[current]] out of [[max]]. 
+
+.restriction.fileformat=File format must be either PNG, GIF or JPG
+
+.restriction.filesize=File size must be less than 40k
+
+.restriction.imagesize2=If dimensions are larger than 100x100 pixels, you will be taken to the Create Userpic page
+
+.restriction.keywords=Picture will be unusable if keywords are not supplied
+
+.restriction.keywords.faq=Picture will be unusable if <a [[aopts]]>keywords</a> are not supplied
+
+.title=Edit Userpics
+
+.title3|notes=This is the new page title.  .title is used by multisearch.bml.
+.title3=Manage Userpics
+
+.uploaddesc=Use the form below to upload a new picture.
+
+.uploaddesc.userpicfactory=Upload a JPG image of any size and we'll send you to the Userpic Factory where you can easily crop and resize it.
+
+.uploadheader=Upload a New Picture
+
+.uploadsuccessful=Image has been successfully uploaded
+
+.userpic=Userpic [[num]]: 
+
+.warning.keywords=One or more of your pictures do not have keywords defined and thus cannot currently be used
+
+.warning.keywords.faq=One or more of your pictures do not have <a [[aopts]]>keywords</a> defined and thus cannot currently be used
+
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/editpics.bml
--- a/htdocs/editpics.bml	Mon Mar 08 22:09:09 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1028 +0,0 @@
-<?_c
-# This code was forked from the LiveJournal project owned and operated
-# by Live Journal, Inc. The code has been modified and expanded by
-# Dreamwidth Studios, LLC. These files were originally licensed under
-# the terms of the license supplied by Live Journal, Inc, which can
-# currently be found at:
-#
-# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
-#
-# In accordance with the original license, this code and all its
-# modifications are provided under the GNU General Public License.
-# A copy of that license can be found in the LICENSE file included as
-# part of this distribution.
-_c?>
-<?_code
-use strict;
-{
-    use vars qw(%GET %POST $title $body $head @errors);
-    use Carp qw(croak);
-
-    LJ::set_active_crumb('manageuserpics');
-    BML::set_language_scope("/editpics.bml");
-
-    my $suffix = "";
-    if (BML::get_request()->uri =~ /editpics-beta/) {
-        $suffix = "-beta";
-    }
-
-    $title = $ML{'.title3'};
-    $body = "";
-    @errors = ();
-
-    my $err = sub {
-        $title = $ML{'Error'};
-        $body = LJ::bad_input(@_);
-        return;
-    };
-
-    unless (LJ::text_in(\%POST)) {
-        return $err->("Invalid UTF-8 Input");
-    }
-
-    my $remote = LJ::get_remote();
-    unless ($remote) {
-        $body = "<?needlogin?>";
-        return;
-    }
-
-    LJ::need_res(qw(
-                    stc/lj_base.css
-                    stc/editpics.css
-                    js/progressbar.js
-                    js/ljprogressbar.js
-                    js/perlbal-uploadtrack.js
-                    js/editpics.js
-                    ));
-
-    my $authas = $GET{'authas'} || $remote->{'user'};
-    my $u = LJ::get_authas_user($authas) or
-        return $err->($ML{'error.invalidauth'});
-
-    # extra arguments for get requests
-    my $getextra = $authas ne $remote->{'user'} ? "?authas=$authas" : '';
-
-    my $returl = LJ::CleanHTML::canonical_url($POST{'ret'});
-    my $picurl = LJ::CleanHTML::canonical_url($POST{'urlpic'});
-
-    if ( $u->is_readonly ) {
-        $title = "Read-only mode";
-        $body = $LJ::MSG_READONLY_USER;
-        return;
-    }
-
-    # update this user's activated pics
-    $u->activate_userpics;
-
-    # get userpics and count 'em
-    my @userpics = LJ::Userpic->load_user_userpics($u);
-
-    # get maximum number of userpics for this user
-    my $max      = $u->count_max_userpics;
-
-    my @info;
-
-    my $factory_redirect;
-    my $no_errors = 1;
-    my $success_count = 0;
-
-    ### save/update mode
-    if (LJ::did_post()) {
-
-        ### save changes to existing pics
-        if ($POST{'action:save'}) {
-            my $refresh = update_userpics(\@userpics, $u, $err);
-
-            # push all the errors to info
-            push(@info, @errors);
-
-            # reload the pictures to account for deleted
-            @userpics = LJ::Userpic->load_user_userpics($u) if $refresh;
-        }
-
-        ### no post data, so we'll parse the multipart data
-        ### this means that we have a new pic to handle.
-        unless (%POST) {
-            my $r = DW::Request->get;
-            my $size = $r->header_in("Content-Length");
-            unless ($size) {
-                return $err->("No content-length header: can't upload");
-            }
-
-            my $MAX_UPLOAD = LJ::Userpic->max_allowed_bytes($u);
-            my $error;
-
-            # act like the factory is disabled if no mogile
-            my $factory_disabled = !LJ::is_enabled('userpicfactory') || !LJ::mogclient();
-            my $mogcli = LJ::mogclient();
-
-            # just return an error immediately if there's no mogile and the upload
-            # size is too big.
-            if (!$mogcli && ($size > $MAX_UPLOAD + 2048)) {
-                # we have to suck in the data otherwise the browser gets upset because we're
-                # closing the connection before reading in all the data and it will sometimes
-                # refuse to show the error.
-
-                # pretend to tell apache that we care about parsing the data, but we really don't
-                my $bogus = sub {return 1;};
-                BML::parse_multipart_interactive(\$error, {
-                    newheaders => $bogus,
-                    data       => $bogus,
-                    enddata    => $bogus,
-                                                 });
-
-                return $err->(BML::ml('.error.filetoolarge',
-                                      { 'maxsize' => int($MAX_UPLOAD / 1024) }));
-                                           
-            }
-
-            my $parsetomogile = !$factory_disabled && ($size > $MAX_UPLOAD + 2048);
-
-            # array of map references
-            my @uploaded_userpics; 
-
-            # three possibilites here:  small upload, in which case we 
-            # just parse it, large upload, in which case we save the
-            # files to mogile, or coming from the factory.
-            if (!$parsetomogile) {
-                # BML::parse_multipart(\%POST, \$error, $MAX_UPLOAD + 2048);
-                BML::parse_multipart(\%POST, \$error);
-
-                # couldn't parse correctly
-                if ($error) {
-                    # return parse_multipart error
-                    return $err->($error);
-                }
-
-                # parse the post parameters into an array of pics
-                @uploaded_userpics = parse_post_uploads(\%POST, $u, $MAX_UPLOAD, $factory_disabled);
-
-            } 
-
-            # if we're coming from the factory, we don't need to write
-            # to mogilefs
-            $parsetomogile = 0 if ($POST{'src'} && $POST{'src'} eq 'factory');
-
-            if ($parsetomogile) {
-                my $res = parse_large_upload(\%POST, \$error, $u, $err);
-                # large path
-
-                # was there an error parsing the multipart form?
-                if ($error) {
-                    if ($error =~ /^\[(\S+?)\]/) {
-                        my $code = $1;
-                        if ($code eq "toolarge") {
-                            return $err->(BML::ml('.error.filetoolarge',
-                                                  { 'maxsize' => int($MAX_UPLOAD / 1024) }));
-                        }
-                        $error = BML::ml("BML.parse_multipart.$code");
-                    }
-                    return $err->($error) if $error;
-                }
-
-                # parse the post parameters into an array of pics
-                @uploaded_userpics = parse_post_uploads(\%POST, $u, $MAX_UPLOAD, $factory_disabled);
-
-            } elsif ($POST{'src'} eq "factory") {
-
-                my $scaledsizemax = $POST{'scaledSizeMax'};
-                my $x1 = $POST{'x1'}+0;
-                my $x2 = $POST{'x2'}+0;
-                my $y1 = $POST{'y1'}+0;
-                my $y2 = $POST{'y2'}+0;
-                my $index = $POST{'index'};
-
-                return $err->("Invalid userpic creation parameters.") if (!$scaledsizemax || !$x2);
-
-                my $picinfo = eval {
-                    LJ::get_upf_scaled(
-                        x1 => $x1,
-                        y1 => $y1,
-                        x2 => $x2,
-                        y2 => $y2,
-                        border => $POST{'border'},
-                        userid  => $u->userid,
-                        mogkey => "upf_$index:$u->{userid}",
-                        );
-                }
-                or return $err->($ML{'.error.generatinguserpic'} . $@);
-
-                my %current_upload;
-                $current_upload{key} = "userpic_0";
-                $current_upload{image} = \${ $picinfo->[0] };
-                $current_upload{keywords} = $POST{keywords};
-                $current_upload{default} = $POST{default};
-                $current_upload{comments} = $POST{comments};
-                $current_upload{descriptions} = $POST{descriptions};
-                $current_upload{make_default} = $POST{make_default};
-                $current_upload{index} = 0;
-
-                push @uploaded_userpics, \%current_upload;
-
-            } 
-            
-            # throw an error if we didn't get a first pic.
-
-            unless (@uploaded_userpics) {
-                if ($POST{src} eq "file")  {
-                    return $err->($ML{'.error.nofile'});
-                } else {
-                    return $err->($ML{'.error.nourl'});
-                }
-            }
-            
-            my $userpic_count = scalar @userpics;
-
-            my $current_index = 0;
-            # go through each userpic and try to create it
-            foreach my $current_upload_ref (sort { $a->{"index"} cmp $b->{"index"} } @uploaded_userpics) {
-                $current_index++;
-                my $message_prefix = "";
-                if (scalar @uploaded_userpics > 1) {
-                    $message_prefix = BML::ml('.userpic', { "num" => $current_index });
-                }
-                my %current_upload = %$current_upload_ref;
-                
-                ## see if they have too many pictures uploaded
-                my $inline;
-                if ($userpic_count >= $max) {
-                    if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPicsMax')) {
-                        push @info, $inline;
-                        $no_errors = 0;
-                    } else {
-                        push @info, BML::ml('.error.toomanypics4', { "num" => $max });
-                        $no_errors = 0;
-                    }
-                } elsif ($current_upload{"error"}) {
-                    push @info, $message_prefix . "$current_upload{error}";
-                    $no_errors = 0;
-                } elsif ($current_upload{requires_factory}) {
-                    unless ($current_upload{spool_fh}) {
-                        LJ::mogclient()->store_content("upf_$current_upload{index}:$u->{userid}", "temp", $current_upload{image});
-                    }
-
-                    $factory_redirect = "$LJ::SITEROOT/tools/userpicfactory?keywords=" .
-                        BML::eurl($current_upload{keywords}) . "&comments=" .
-                        BML::eurl($current_upload{comments}) . "&descriptions=" .
-                        BML::eurl($current_upload{descriptions}) .
-                        "&imageWidth=" . BML::eurl($current_upload{imagew}) . 
-                        "&imageHeight=" . BML::eurl($current_upload{imageh}) .
-                        "&make_default=" . BML::eurl($current_upload{make_default}) . 
-                        "&index=" . BML::eurl($current_upload{index}) . '&authas=' .
-                        BML::eurl($GET{'authas'}) . '&sfx=' . BML::eurl($suffix);
-                    
-                    # go ahead and add the error message to the info string;
-                    # this will only get displayed if we don't do the redirect.
-                    push @info, $message_prefix . $ML{'.error.toolarge.separately'};
-                } else {
-                    my $userpic = eval { LJ::Userpic->create($u, data => $current_upload{image}); };
-                    if (!$userpic) {
-                        $@ = $@->as_html if $@->isa('LJ::Error');
-                        push @info, $message_prefix . "$@";
-                        $no_errors = 0;
-                    } else {
-                        my $picid = $userpic->id;
-                        
-                        push @info, $message_prefix . $ML{'.uploadsuccessful'};
-                        $success_count++;
-
-                        # make it their default pic?
-                        if ($current_upload{make_default}) {
-                            $userpic->make_default;
-                        }
-                        $userpic->set_keywords($current_upload{keywords}) if $current_upload{keywords};
-                        $userpic->set_comment($current_upload{comments})  if $current_upload{comments};
-                        $userpic->set_description($current_upload{descriptions}) if $current_upload{descriptions};
-                        $userpic->set_fullurl($current_upload{url})       if $POST{url};
-                        
-                        $userpic_count++;
-                    }
-                }
-                
-            }
-            # yay we created new pics, reload the @userpics
-            @userpics = LJ::Userpic->load_user_userpics($u);
-        }
-        
-        if ($factory_redirect && $no_errors) {
-            if ($success_count) {
-                $factory_redirect .= '&successcount=' . $success_count;
-            }
-            return BML::redirect($factory_redirect);
-        }
-
-        # now fall through to edit page and show the updated userpic info
-        # redirect back to ourselves
-        $returl = LJ::CleanHTML::canonical_url($POST{'ret'});
-        if ($returl) {
-            my $redir_host;
-            $redir_host = $1 if $returl =~ m!^http://([\.:\w-]+)!i;
-            return BML::redirect($returl) if $LJ::REDIRECT_ALLOWED{$redir_host};
-        }
-    }
-
-    # authas switcher form
-    $body .= "<form method='get' id='userpic_authas' action='editpics$suffix'>\n";
-    $body .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} }) . "\n";
-    $body .= "</form>\n\n";
-
-    # if we're disabling media, say so
-    $body .= "<?warningbar $ML{'error.mediauploadsdisabled'} warningbar?>"
-        if $LJ::DISABLE_MEDIA_UPLOADS;
-
-    if (@info) {
-        $body .= '<div class="warningbar">';
-        $body .= "<div>$_</div>" foreach @info;
-        $body .= '</div>';
-    }
-
-    # print out upload pic box
-    my $emit_upload_box = sub {
-        $body .= '<a name="uploadBox"></a>';
-        if (scalar @userpics < $max) {
-
-            # upload form (with perlbal upload-tracking)
-            $body .= qq {
-                <iframe name='upiframe' width='1' height='1' style='border: none'></iframe>
-                <div id='uploadBox' class='pkg'><div id='uploadBox-inner'>
-                    <form enctype="multipart/form-data" action="editpics$suffix$getextra" method='post' id='uploadPic'>
-                    <input type="hidden" id="go_to" name="go_to" value="editpics$suffix$getextra" />
-            };
-
-            $body .= "<?h1 $ML{'.uploadheader'} h1?>\n";
-            $body .= "<p class='detail'><a href='javascript:void(0)' onclick='toggleElement(\"upload_desc\")' id='upload_desc_link'>$ML{'.about.icons'}</a></p>";
-            $body .= "<div id='upload_desc'>";
-            $body .= "<?p $ML{'.uploaddesc'} p?>\n";
-            $body .= "</div><!-- end #uploaddesc -->";
-
-            $body .= "<div id='upload_wrapper' class='pkg'>\n";
-            $body .= "<p class='pkg'>\n";
-            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'src', 'id' => 'radio_file',
-                                      'class' => 'radio', 'value' => 'file', 'selected' => '1', 
-                                      'accesskey' => $ML{'.fromfile.key'} }) . "\n";
-            $body .= "<label for='radio_file'>$ML{'.fromfile'}</label><br />\n";
-            $body .= "<input type='file' class='file' name='userpic_0' id='userpic_0' size='18' style='margin: 0em 0em 0.5em 2em;' />\n";
-            $body .= "</p>\n";
-            $body .= "<p class='pkg'>\n";
-            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'src', 'value' => 'url',
-                                      'id' => 'radio_url', 'class' => 'radio', 'accesskey' => $ML{'.fromurl.key'} }) . "\n";
-            $body .= "<label for='radio_url'>$ML{'.fromurl'}</label><br />\n";
-            $body .= LJ::html_text({ 'name' => 'urlpic_0', 'id' => 'urlpic_0', class => 'text', style => 'margin: 0em 0em 0.5em 2em;' }) . "\n";
-            $body .= "</p>\n";
-            $body .= "<p class='detail'>$ML{'.label.formats.desc'}</p>\n";
-            $body .= "</div>\n";
-
-            $body .= "<hr class='hr' />";
-
-            $body .= "<p class='pkg'>\n";
-            $body .= "<label class='left' for='keywords_0'>$ML{'.label.keywords'}</label>\n";
-            $body .= "<span class='input-wrapper'>";
-            $body .= LJ::html_text({ 'name' => 'keywords_0', class => 'text', id => 'keywords_0' }) . "\n";
-            $body .= LJ::help_icon_html('upic_keywords') . "\n";
-            $body .= "</span>";
-            $body .= "</p>\n";
-            $body .= "<p class='detail'>$ML{'.label.keywords.desc'}</p>\n";
-
-            $body .= "<p class='pkg'>\n";
-            $body .= "<label class='left' for='comments_0'>$ML{'.label.comment'}</label>\n";
-            my $comments = $POST{'comments'};
-            $body .= "<span class='input-wrapper'>";
-            $body .= LJ::html_text({ 'name' => 'comments_0', 'class' => 'text', id => 'comments_0', 'maxlength' => LJ::CMAX_UPIC_COMMENT, 'value', $comments }) . "\n";
-            $body .= LJ::help_icon_html('upic_comments') . "\n";
-            $body .= "</span>";
-            $body .= "</p>\n";
-            $body .= "<p class='detail'>$ML{'.label.comment.desc'}</p>\n";
-
-            $body .= "<p class='pkg'>\n";
-            $body .= "<label class='left' for='descriptions_0'>$ML{'.label.description'}</label>\n";
-            my $descriptions = $POST{'descriptions'};
-            $body .= "<span class='input-wrapper'>";
-            $body .= LJ::html_text( { name => 'descriptions_0', class => 'text', id => 'descriptions_0', 'maxlength' => LJ::CMAX_UPIC_DESCRIPTION, value => $descriptions } ) . "\n";
-            $body .= LJ::help_icon_html('upic_descriptions') . "\n";
-            $body .= "</span>";
-            $body .= "</p>\n";
-            $body .= "<p class='detail'>$ML{'.label.description.desc'}</p>\n";
-
-            $body .= "<p class='pkg'>\n";
-            $body .= LJ::html_check({ 'type' => 'checkbox',
-                                      'name' => 'make_default',
-                                      'id' => 'make_default_0',
-                                      'value' => '0',
-                                      'selected' => @userpics ? 0 : 1,
-                                      'accesskey' => $ML{'.makedefault.key'} });
-
-            $body .= "<label for='make_default_0'>$ML{'.makedefault'}</label>\n";
-            $body .= "</p>\n";
-            
-            # adding multi-upload option if mogile is enabled
-            
-            my $remaining_uploads = $max - scalar @userpics;
-            if ($remaining_uploads >= 2 && LJ::mogclient()) {
-                $body .= "<div id='multi_insert'></div>";
-                $body .= "<div id='no_default_insert'></div>";
-                $body .= "<p class='pkg' id='multi_insert_buttons'>\n";
-
-                $body .= "<input type='button' value='$ML{'.btn.addfile'}' onclick='javascript:addNewUpload(\"file\");' /> <input type='button' value='$ML{'.btn.addurl'}' onclick='javascript:addNewUpload(\"url\");'/>\n";
-                $body .= "<script type='text/javascript'>\n";
-                $body .= "maxcounter = $remaining_uploads;\n";
-                $body .= "allowComments = true;\n";
-                $body .= "allowDescriptions = true;\n";
-
-                $body .= "ep_labels.comment = '$ML{'.label.comment'}';\n";
-                $body .= "ep_labels.description = '$ML{'.label.description'}';\n";
-                $body .= "ep_labels.fromfile = '$ML{'.fromfile'}';\n";
-                $body .= "ep_labels.fromurl = '$ML{'.fromurl'}';\n";
-                $body .= "ep_labels.keepdefault = '$ML{'.label.keepdefault'}';\n";
-                $body .= "ep_labels.keywords = '$ML{'.label.keywords'}';\n";
-                $body .= "ep_labels.makedefault = '$ML{'.makedefault'}';\n";
-                $body .= "ep_labels.makedefaultkey = '$ML{'.makedefault.key'}';\n";
-                $body .= "ep_labels.remove = '$ML{'.btn.remove'}';\n";
-                
-                $body .="</script>\n";
-                $body .= "</p>\n";
-            }
-
-            $body .= "<p class='pkg' id='submit_wrapper'>";
-            $body .= LJ::html_submit(undef, $ML{'.btn.proceed'},
-                                     { disabled => $LJ::DISABLE_MEDIA_UPLOADS });
-            $body .= "</p>\n";
-            $body .= q {
-                    </form>
-                    </div></div><!-- end #uploadBox -->
-                    <div id="uploadStatus" style="display: none;"></div>
-                    <div id="progressBar" style="display: none;"></div>
-                };
-
-        } else {
-            $body .= "<div id='limit'>\n";
-            my $inline;
-            if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPicsMax')) {
-                $body .= $inline;
-            } else {
-                $body .= BML::ml('.error.toomanypics_standout', { num => $max });
-            }
-            $body .= "</div><!-- end #limit -->";
-        }
-        $body .= " \n\n";
-    };
-
-    $emit_upload_box->();
-
-    # print out each pic and editing fields
-    if ( scalar @userpics ) {
-        $body .= "<div id='current_userpics'>";
-        $body .= "<form method='post' action='editpics$suffix$getextra'>";
-        $body .= LJ::form_auth();
-
-        $body .= qq {
-                <?h1 $ML{'.curpics'} h1?>
-                <?p $ML{'.curpics.desc2'} p?>
-                <div class='EditPicsStatus'>
-            };
-
-        $body .= "<p><strong>" . BML::ml('.piclimitstatus', {current => scalar @userpics, max => $max}) . "</strong></p>";;
-        if (scalar @userpics >= $max) {
-            my $inline;
-            if ($inline .= LJ::Hooks::run_hook("cprod_inline", $u, 'EditPics')) {
-                $body .= "<?warningbar" . $inline . "warningbar?>";
-            } else {
-                $body .= "<p>".BML::ml('cprod.editpics.text7.v1',{ "num" => $max })."</p>";
-            }
-        }
-        $body .= "</div>";
-
-        $body .= "<div id='list_userpics' style='width: 98%; float: left;'>";
-        my $display_rename = LJ::theschwartz() ? 1 : 0;
-
-        foreach my $pic (@userpics) {
-            my $pid = $pic->id;
-            
-            $body .= "<div class='pkg userpic_wrapper'>";
-            $body .= "<span class='EditPicsUserpic'>" .  $pic->imgtag . "</span>\n";
-
-            # TODO: if no keywords then light grey text and empty out when you click in it
-            my $keywords = $pic->keywords;
-            my $comment = $pic->comment;
-            my $description = $pic->description;
-            $body .= "<div class='userpic_controls'  style='float: left; width: auto;'>";
-            $body .= "<div class='userpic_keywords pkg'>\n";
-            $body .= "<label class='left' for='kw_$pid'>$ML{'.label.keywords'}</label>\n ";
-            $body .= LJ::html_text({'name' => "kw_$pid", 'class' => "text", 'id' => "kw_$pid",
-                                    'value' => $keywords,
-                                    'disabled' => $pic->inactive,
-                                    'onfocus' => $display_rename ? "\$(\'rename_div_$pid\').style.display = \'block\';" : ""
-                                   }) . "\n";
-            $body .= LJ::html_hidden({ 'name' => "kw_orig_$pid",
-                                       'value' => $keywords }) . "\n";
-            if ($display_rename) {
-                $body .= "<div id='rename_div_$pid' class='userpic_rename pkg'>\n";
-                $body .= "<script type='text/javascript'>document.getElementById('rename_div_$pid').style.display = 'none';</script>\n";
-                $body .= LJ::html_check({ 'type' => 'checkbox', 'name' => "rename_keyword_$pid", 'class' => "checkbox",
-                                          'id' => "rename_keyword_$pid", 'value' => 1,
-                                          'disabled' => $LJ::DISABLE_MEDIA_UPLOADS });
-                $body .= "<label for='rename_keyword_$pid'>$ML{'.label.rename'}</label>"; 
-                $body .= "</div>\n";
-            }
-            $body .= "</div>\n";
-
-            $body .= "<div class='userpic_comments pkg'>\n";
-            $body .= "<label class='left' for='com_$pid'>$ML{'.label.comment'}</label>\n ";
-            $body .= LJ::html_text({ 'name' => "com_$pid", 'class' => "text", 'id' => "com_$pid",
-                                     'value' => $comment,
-                                     'maxlength' => LJ::CMAX_UPIC_COMMENT,
-                                     'disabled' => $pic->inactive }) . "\n";
-            $body .= LJ::html_hidden({ 'name' => "com_orig_$pid",
-                                       'value' => $comment }) . "\n";
-
-            $body .= "</div>\n";
-            
-            $body .= "<div class='userpic_descriptions pkg'>\n";
-            $body .= "<label class='left' for='desc_$pid'>$ML{'.label.description'}</label>\n ";
-            $body .= LJ::html_text({ 'name' => "desc_$pid", 'class' => "text", 'id' => "desc_$pid",
-                                     'value' => $description,
-                                     'maxlength' => LJ::CMAX_UPIC_DESCRIPTION,
-                                     'disabled' => $pic->inactive }) . "\n";
-            $body .= LJ::html_hidden({ 'name' => "desc_orig_$pid",
-                                       'value' => $description }) . "\n";
-
-            $body .= "</div>\n";
-        
-            $body .= "<div class='userpic_defaultdelete pkg'>";
-            $body .= LJ::html_check({ 'type' => 'radio', 'name' => 'defaultpic', 'class' => "radio", 'value' => $pid,
-                                      'selected' => $pic->is_default ? 1 : 0,
-                                      'id' => "def_$pid",
-                                      'disabled' => $pic->inactive });
-            $body .= "<label class='userpic_default_label' for='def_$pid'>$ML{'.label.default'}</label> ";
-            $body .= LJ::html_check({ 'type' => 'checkbox', 'name' => "delete_$pid", 'class' => "checkbox",
-                                      'id' => "del_$pid", 'value' => 1,
-                                      'disabled' => $LJ::DISABLE_MEDIA_UPLOADS });
-            $body .= "<label for='del_$pid'>$ML{'.label.delete'}</label>"; 
-            if ($pic->inactive) {
-                $body .= " &nbsp;<i>[$ML{'userpic.inactive'}]</i> " . LJ::help_icon('userpic_inactive');
-            }
-            $body .= "</div>";
-            $body .= "</div>";
-            $body .= "</div>";
-            $body .= "<hr class='hr' />";
-        }
-
-        $body .= "</div><!-- end #list_userpics -->";
-        # no default userpic
-        $body .= "<p id='no_default_userpic' style='clear: both;'>";
-        $body .= LJ::html_check({ 'name' => 'defaultpic',
-                                  'value' => 0,
-                                  'type' => 'radio',
-                                  'class' => 'radio',
-                                  'selected' => $u->{'defaultpicid'} == 0,
-                                  'raw' => "id='nodefpic'" });
-        $body .= "<label for='nodefpic'>$ML{'.nodefault'}</label></p>";
-        $body .= "<?standout" . LJ::html_submit('action:save', $ML{'.btn.save'}) . "standout?>";
-        $body .= "</form>";
-        $body .= "</div><!-- end #current_userpics -->";
-        $body .= "<script type='text/javascript'>\n";
-        $body .= "editpicsInit();\n";
-        $body .= "</script>\n";
-
-    } else {
-        $body .= qq {
-                <?h1 $ML{'.nopics'} h1?>
-                <?p $ML{'.noneupload2'} p?>
-            };
-    }
-
-    
-    return;
-}
-
-sub update_userpics
-{
-    my $userpicsref = shift;
-    my $u = shift;
-    my @userpics = @$userpicsref;
-    my $err = shift;
-    
-    
-    # form being posted isn't multipart, since we were able to read from %POST
-    unless (LJ::check_form_auth()) {
-        return $err->($ML{'error.invalidform'});
-    }
-    
-    my @delete; # userpic objects to delete
-    my @inactive_picids;
-    my %picid_of_kwid;
-    my %used_keywords;
-    
-    # we need to count keywords based on what the user provided, in order
-    # to find duplicates. $up->keywords doesn't work, because re-using a
-    # keyword will remove it from the other userpic without our knowing
-    my $count_keywords = sub {
-        my $kwlist = shift;
-        $used_keywords{$_}++ foreach split(/,\s*/, $kwlist);
-    };
-
-    foreach my $up (@userpics) {
-
-        my $picid = $up->id;
-        
-        # delete this pic
-        if ($POST{"delete_$picid"}) {
-            push @delete, $up;
-            next;
-        }
-        
-        # we're only going to modify keywords/comments on active pictures
-        if ($up->inactive) {
-            # use 'orig' because we don't POST disabled fields
-            $count_keywords->($POST{"kw_orig_$picid"});
-            next;
-        }
-        
-        $count_keywords->($POST{"kw_$picid"});
-        
-        # only modify if changing the data, make sure not collidiing with other edits, etc
-        if ($POST{"kw_$picid"} ne $POST{"kw_orig_$picid"}) {
-            my $kws = $POST{"kw_$picid"};
-            
-            if ($POST{"rename_keyword_$picid"}) {
-                eval {
-                    $up->set_and_rename_keywords($kws, $POST{"kw_orig_$picid"});
-                } or push @errors, $@->as_html;
-            } else {
-                eval {
-                    $up->set_keywords($kws);
-                } or push @errors, $@;
-            }
-        }
-        
-        eval {
-            $up->set_comment ($POST{"com_$picid"})
-                unless $POST{"com_$picid"} eq $POST{"com_orig_$picid"};
-        } or push @errors, $@;
-        
-        eval {
-            $up->set_description ($POST{"desc_$picid"})
-                unless $POST{"desc_$picid"} eq $POST{"desc_orig_$picid"};
-        } or push @errors, $@;
-
-    }
-    
-    foreach my $kw (keys %used_keywords) {
-        next unless $used_keywords{$kw} > 1;
-        push @errors, BML::ml('.error.keywords', {ekw => $kw});
-    }
-    
-    if (@delete && $LJ::DISABLE_MEDIA_UPLOADS) {
-        push @errors, $ML{'.error.nomediauploads.delete'};
-        
-    } elsif (@delete) {
-        
-        # delete pics
-        foreach my $up (@delete) {
-            eval { $up->delete; } or push @errors, $@;
-        }
-        
-        # if any of the userpics they want to delete are active, then we want to
-        # re-run activate_userpics() - turns out it's faster to not check to
-        # see if we need to do this
-        $u->activate_userpics;
-    }
-    
-    my $new_default = $POST{'defaultpic'}+0;
-    if ($POST{"delete_${new_default}"}) {
-        # deleting default
-        $new_default = 0;
-    }
-    
-    if ($new_default && $new_default != $u->{'defaultpicid'}) {
-        my ($up) = grep { $_->id == $new_default } @userpics;
-        
-        # see if they are trying to make an inactive userpic their default
-        if ($up && !$up->inactive) {
-            $up->make_default;
-        }
-    } elsif ($new_default eq '0' && $u->{'defaultpicid'}) {
-        # selected the "no default picture" option
-        LJ::update_user($u, { defaultpicid => 0 });
-        $u->{'defaultpicid'} = 0;
-    }
-    
-    return scalar @delete;
-}
-
-sub parse_post_uploads
-{
-    my $postref = shift;
-    my %POST = %$postref;
-    my $u = shift;
-    my $MAX_UPLOAD = shift;
-    my $factory_disabled = shift;
-
-
-    my @uploads;
-    
-    # if we find a userpic that requires the factory, save it here.
-    # we can only have one.
-    my $requires_factory;
-    
-    # go through each key and create a %current_upload for it, then
-    # put it in @uploads.
-    foreach my $userpic_key (keys %POST) {
-        # uploaded pics
-        if ($userpic_key =~ /userpic_.*/) {
-            # only use userpic_0 if we selected file for the source    
-            unless ($userpic_key eq "userpic_0" && $POST{"src"} ne "file") {
-                # copy all of the basic settings into the hash.
-                my %current_upload;
-                $current_upload{key} = $userpic_key;
-                my @tokens = split(/_/, $userpic_key);
-                my $counter = $tokens[1];
-                $current_upload{keywords} = $POST{"keywords_$counter"};
-                $current_upload{comments} = $POST{"comments_$counter"};
-                $current_upload{descriptions} = $POST{"descriptions_$counter"};
-                $current_upload{index} = $counter;
-                $current_upload{image} = \$POST{$userpic_key};
-                $current_upload{make_default} =  ($POST{"make_default"} eq $counter);
-
-                # check the image size.
-                my $imgdata = $POST{"spool_fh_$counter"} ? $POST{"spool_fh_$counter"} : \$POST{$userpic_key};
-                my $size = length($$imgdata);
-                
-                if ($size == 0) {
-                    $current_upload{error} = $ML{'.error.nofile'};
-                } else {
-                    my ($imagew, $imageh, $filetype) = Image::Size::imgsize($imgdata);
-                    my $size = length($imgdata);
-                    
-                    if (!$imagew || !$imageh) {
-                        # couldn't parse the file
-                        $current_upload{error} = BML::ml(".error.unsupportedtype", {filetype => $filetype});
-                    } elsif ($imagew > 5000 || $imageh > 5000) {
-                        # file is too big, no matter what.
-                        $current_upload{error} = "The dimensions of this image are too large.";
-                    } elsif (int($imagew) > 100 || int($imageh) > 100 || $size > $MAX_UPLOAD) {
-                        # file is too large.  
-                        if ($factory_disabled) {
-                            if (int($imagew) > 100 || int($imageh) > 100) {
-                                $current_upload{error} = BML::ml('.error.imagetoolarge', {imagesize => "${imagew}x$imageh"});
-                            } else {
-                                $current_upload{error} = BML::ml('.error.filetoolarge', { 'maxsize' => int($MAX_UPLOAD / 1024) });
-                            }
-                        } elsif ($filetype ne 'JPG' && $filetype ne 'PNG') {
-                            # factory only works on jpegs and pngs because Image::Magick has issues
-                            if (int($imagew) > 100 || int($imageh) > 100) {
-                                $current_upload{error} = $ML{'.error.giffiledimensions'};
-                            } else {
-                                $current_upload{error} = BML::ml('.error.filetoolarge', { 'maxsize' => int($MAX_UPLOAD / 1024)});
-                            }
-                        } elsif ($imagew <= 100 && $imageh <= 100) {
-                            # if it's the right size, just too large a file, see if we can
-                            # resize it down
-                            unless ($POST{"spool_file_name_$counter"}) {
-                                LJ::mogclient()->store_content("upf_${counter}:$u->{userid}", "temp", \$POST{$userpic_key});
-                            }
-                            
-                            eval {
-                                my $picinfo = LJ::get_upf_scaled(
-                                    size => 100,
-                                    u    => $u,
-                                    mogkey => "upf_${counter}:$u->{userid}"
-                                    );
-                                
-                                # success! don't go to the factory, and pretend the user just uploaded the file
-                                # and continue on normally
-                                $current_upload{image} = \${ $picinfo->[0] };
-                            };
-                            
-                            if ($@ || (length($POST{$userpic_key}) > $MAX_UPLOAD)) {
-                                $current_upload{error} = ML::ml('.error.filetoolarge', {maxsize => int($MAX_UPLOAD / 1024) });
-                            }
-                        } else {
-                            # this is a candidate for the userpicfactory.
-                            
-                            # we can only do a single pic in the factory, so if there are two,
-                            # then error out for both.
-                            if ($requires_factory) {
-                                $requires_factory -> {error} = $ML{'.error.multipleresize'};
-                                $current_upload{error} = $ML{'.error.multipleresize'};
-                                $requires_factory->{requires_factory} = 0;
-                            } else {
-                                $current_upload{requires_factory} = 1;
-                                $current_upload{imageh} = $imageh;
-                                $current_upload{imagew} = $imagew;
-                                if ($POST{"spool_fh_$counter"}) {
-                                    $current_upload{spool_fh} = $POST{"spool_fh_$counter"};
-                                }
-                                $requires_factory = \%current_upload;
-                            }
-                        }
-                    } else {
-                        # valid file; just add it as given.
-                        if ($POST{"spool_file_name_$counter"}) {
-                            $current_upload{image} = LJ::mogclient()->get_file_data($POST{"spool_file_name_$counter"});
-                        }
-                    }
-                }
-                push @uploads, \%current_upload;
-            }
-        } elsif ($userpic_key =~ /urlpic_.*/) {
-            # go through the URL uploads
-            unless ($userpic_key eq "urlpic_0" && $POST{src} ne "url") {
-                # copy all of the basic settings into the hash.
-                my %current_upload;
-                $current_upload{key} = $userpic_key;
-                my @tokens = split(/_/, $userpic_key);
-                my $counter = $tokens[1];
-                $current_upload{keywords} = $POST{"keywords_$counter"};
-                $current_upload{comments} = $POST{"comments_$counter"};
-                $current_upload{descriptions} = $POST{"descriptions_$counter"};
-                $current_upload{index} = $counter;
-                $current_upload{make_default} =  ($POST{"make_default"} eq $counter);
-
-                if (! $POST{$userpic_key}) {
-                    $current_upload{error} = $ML{'.error.nourl'};
-                } elsif ($POST{$userpic_key} !~ /^http:\/\//) {
-                    $current_upload{error} = $ML{'.error.badurl'};
-                } else {
-                    my $ua = LJ::get_useragent(
-                        role     => 'userpic',
-                        max_size => $MAX_UPLOAD + 1024,
-                        timeout  => 10,
-                        );
-                    my $res = $ua->get($POST{$userpic_key});
-                    $current_upload{image} = \$res->content if $res && $res->is_success;
-                    $current_upload{error} = $ML{'.error.urlerror'} unless $current_upload{image};
-                    #Below, $current_upload{image} needs to be dereferenced because it contains a hash value.
-                    $current_upload{error} = $ML{'.error.urlfiletoolarge'} if length( ${ $current_upload{image} } ) > $MAX_UPLOAD;
-                }
-                push @uploads, \%current_upload;
-            }
-        }
-    }
-
-    return @uploads;
-}
-
-sub parse_large_upload 
-{
-    my $postref = shift;
-    my $errorref = shift;
-    my $user = shift;
-    my $err = shift;
-
-    my %upload = (); # { spool_fh, spool_path, filename, bytes, md5sum, md5ctx, mime }
-    my @uploaded_files = ();
-    my $curr_name;
-
-    # called when the beginning of an upload is encountered
-    my $hook_newheaders = sub {
-        my ($name, $filename) = @_;
-
-        # for uploaded files, just set POST value to filename
-        $postref->{$name} = '';
-        
-        $curr_name = $name;
-        
-        return 1 unless $curr_name =~ /userpic.*/;
-        
-        # new file, need to create a filehandle, etc
-        %upload = ();
-        $upload{filename} = $filename;
-        $upload{md5ctx} = new Digest::MD5;
-        
-        # get MogileFS filehandle
-        return $err->("Sorry, MogileFS must be running to handle the uploading of large images.") unless LJ::mogclient();
-        
-        my @tokens = split(/_/, $curr_name);
-        my $counter = $tokens[1];
-
-        $upload{spool_file_name} = "upf_${counter}:$user->{userid}";
-        $upload{spool_fh} = LJ::mogclient()->new_file($upload{spool_file_name}, 'temp')
-            or die "Failed to open MogileFS tempfile";
-        
-        push @uploaded_files, $upload{spool_file_name};
-        return 1;
-    };
-    
-    # called as data is received
-    my $hook_data = sub {
-        my ($len, $data) = @_;
-        
-        unless ($curr_name =~ /userpic.*/) {
-            $postref->{$curr_name} .= $data;
-            return 1;
-        }
-
-        # check that we've not exceeded the max read limit
-        my $max_read = (1<<20) * 5; # 5 MiB
-        my $len_read = 0;
-        
-        $len_read = ($upload{bytes} += $len);
-        
-        die "Upload max exceeded at $len_read bytes"
-            if $len_read > $max_read;
-        
-        $upload{md5ctx}->add($data);
-        $upload{spool_fh}->print($data);
-
-        return 1;
-    };
-    
-    # called when the end of an upload is encountered
-    my $hook_enddata = sub {
-        return 1 unless $curr_name =~ /userpic.*/;
-
-        # since we've just finished a potentially slow upload, we need to
-        # make sure the database handles in DBI::Role's cache haven't expired,
-        # so we'll just trigger a revalidation now so that subsequent database
-        # calls will be safe.
-        $LJ::DBIRole->clear_req_cache();
-        
-        # don't try to operate on 0-length spoolfiles
-        unless ($upload{bytes}) {
-            %upload = ();
-            return 1;
-        }
-
-        # read magic and try to determine formatid of uploaded file. This
-        # doesn't use fh->tell and fh->seek because the filehandle is
-        # sysopen()ed, so isn't really an IO::Seekable like an IO::File
-        # filehandle would be.
-        my $magic;
-        tell $upload{spool_fh}
-        or die "read offset is 0, empty file?";
-        seek $upload{spool_fh}, 0, 0;
-
-        # $! should always be set in this case because a failed read will
-        # always be an error, not EOF, which is handled above (tell)
-        $upload{spool_fh}->read($magic, 20)
-            or die "Couldn't read magic: $!";
-        
-        $upload{spool_fh}->close
-            or die "Can't close Mogile filehandle";
-        
-        my $format_magic = sub {
-            my $magic = shift;
-            my $hex = unpack "H*", $magic;
-            my $mime;
-            
-            # image formats
-            $mime = 'image/jpeg' if $magic =~ /^\xff\xd8/; # JPEG
-            $mime = 'image/gif'  if $magic =~ /^GIF8/;     # GIF
-            $mime = 'image/png'  if $magic =~ /^\x89PNG/;  # PNG
-            
-            return $mime;
-        };
-        
-        $upload{mime} = $format_magic->( $magic );
-        unless ( $upload{mime} ) {
-            $$errorref = "Unknown format for upload";
-            return $err->( $$errorref );
-        }
-        
-        # finished adding data for md5, create digest (but don't destroy original)
-        $upload{md5sum} = $upload{md5ctx}->digest;
-        
-        my @tokens = split(/_/, $curr_name);
-        my $counter = $tokens[1];
-
-        $postref->{$curr_name} = $upload{spool_fh};
-        $postref->{"spool_file_name_$counter"} = $upload{spool_file_name};
-        $postref->{"spool_fh_$counter"} = $upload{spool_fh};
-
-        return 1;
-    };
-    
-    
-    # parse multipart-mime submission, one chunk at a time,
-    # calling our hooks as we go to put uploads in temporary
-    # MogileFS filehandles
-    my $retval = eval { BML::parse_multipart_interactive($errorref, {
-        newheaders => $hook_newheaders,
-        data       => $hook_data,
-        enddata    => $hook_enddata,
-                                                         }); };
-    
-    # if BML::Parse_multipart_interactive failed, we need to add
-    # all of our gpics to the gpic_delete queue.  if any of them
-    # still have refcounts, they won't really be deleted because
-    # the async job will realize and leave them alone
-    unless ($retval) {
-        # if we hit a parse error, delete the uploaded files
-        foreach my $mogkey (@uploaded_files) {
-            LJ::mogclient()->delete($mogkey);
-        }
-
-        if (index(lc($$errorref), 'unknown format') == 0) {
-            return $err->(BML::ml(".error.unknowntype"));
-        }
-        return $err->("couldn't parse upload: $$errorref");
-    }
-
-    return $retval;
-}
-
-_code?><?page
-    head=><?_code return $head; _code?>
-    title=><?_code return $title; _code?>
-    body=><?_code return $body; _code?>
-    page?>
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/editpics.bml.text
--- a/htdocs/editpics.bml.text	Mon Mar 08 22:09:09 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-;; -*- coding: utf-8 -*-
-
-.about.icons=About Icons
-
-.btn.addfile=Add File
-
-.btn.addurl=Add URL
-
-.btn.proceed=Proceed
-
-.btn.remove=Remove
-
-.btn.save=Save Settings
-
-.curpics=Current Pictures
-
-.curpics.desc2=Here are the pictures you've uploaded in the past. You can assign keywords to them so you can use them by keyword later, select which one to use as your default, or delete old ones. To upload a new one, use the form at the top of the page.
-
-.error.badurl=The address for the picture to be uploaded does not look correct.  It should start with <b>http://</b>
-
-.error.filetoolarge=Image uploaded is too large.  File size cannot exceed [[maxsize]] KB.
-
-.error.generatinguserpic=There was an error in generating the userpic: 
-
-.error.giffiletoolarge=The GIF image you uploaded is too large.  GIF file size cannot exceed [[maxsize]].
-
-.error.giffiledimensions=Sorry, you cannot upload a userpic larger than 100x100 pixels if it is in GIF format.
-
-.error.imagetoolarge=The dimensions of your image ([[imagesize]]) exceed maximum size.  Your picture can only be 100x100 pixels large.  Use a image/photo editing program to reduce the image to thumbnail-size.
-
-.error.invalidimage=Invalid image file.
-
-.error.keywords=You used the keyword "[[ekw]]" for multiple pictures.  One was randomly chosen, but likely not the one you wanted.  You may want to go back and fix that.
-
-.error.multipleresize=Error:  only one image requiring resizing may be sent.
-
-.error.nofile=You must choose a file to upload
-
-.error.nourl=You must enter the URL of an image
-
-.error.nomediauploads.delete=Unable to delete userpics at this time.  Media modification is currently disabled for the site.
-
-.error.rename.blankkw=Error renaming '[[origkw]]' to '[[newkw]]':  renaming of blank (pic#) keywords not allowed.
-
-.error.rename.keywordexists=Cannot rename to '[[keyword]]':  keyword already exists.
-
-.error.rename.keywords=An error occurred trying to rename '[[origkw]]' to '[[newkw]]'; entries and comments with the old keywords may not have changed to use the new keywords.
-
-.error.rename.mismatchedlength=Error renaming '[[origkw]]' to '[[newkw]]':  must rename to the same number of keywords.
-
-.error.toolarge.separately=Image is too large; please submit it separately to resize.
-
-.error.toomanykeywords=The [[?numwords|keyword|keywords]] "[[words]]" [[?numwords|has|have]] not been saved as [[?numwords|its|their]] user picture icon already has [[max]] keywords.
-
-.error.toomanypics4=You are already at your limit of [[num]] [[?num|userpic|userpics]]. You cannot upload this userpic until you delete <a [[aopts]]>one of your existing ones</a>.
-
-.error.toomanypics_standout=You are at your limit of [[num]] [[?num|userpic|userpics]]. You cannot upload any more userpics until you delete one of your existing ones.
-
-.error.unknowntype=You can only upload GIF, PNG, or JPG files.
-
-.error.unsupportedtype=Files of type [[filetype]] are not supported.  You can only upload GIF, PNG or JPG files.  Nearly all image/photo programs can do this conversion for you.
-
-.error.urlerror=An error ocurred while trying to fetch your image.
-
-.error.urlfiletoolarge=You cannot upload large images from URLs.
-
-.fromfile=From <u>F</u>ile:
-
-.fromfile.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".fromfile". This is the shortcut key for the fromfile option.
-.fromfile.key=f
-
-.fromurl=From U<u>R</u>L:
-
-.fromurl.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".fromurl". This is the shortcut key for the fromurl option.
-.fromurl.key=r
-
-.imagesize.by|notes=This character is inserted between two numbers to indicate "by" when specifying image dimensions, for example "100x100".
-.imagesize.by=x
-
-.label.comment=Comment:
-
-.label.comment.desc=Optional comments about the picture. Credit can go here. Example: "I made this!"
-
-.label.default=Default
-
-.label.delete=Delete
-
-.label.description=Description:
-
-.label.description.desc=Optional description of what is in the picture. Shown to people who cannot view the image, e.g. blind people using screen readers. Example: "Photo of me in the mirror, holding up camera"
-
-.label.formats.desc=Acceptable formats are GIF, JPG and PNG.
-
-.label.keepdefault=Keep existing default pic.
-
-.label.keywords=Keywords:
-
-.label.keywords.desc=Comma-separated list of terms you'll use to select this picture.
-
-.label.rename=Rename Keywords
-
-.makedefault=Make this your <u>d</u>efault picture
-
-.makedefault.key|notes=Enter here a <b>lower-case</b> version of the letter you underlined in ".makedefault". This is the shortcut key for the makedefault option.
-.makedefault.key=d
-
-.nodefault=No Default Picture
-
-.noneupload=You have no pictures uploaded.  Please upload one using the form below.
-
-.noneupload2=You have no pictures uploaded.  Please upload one using the form above.
-
-.nopics=No Pictures
-
-.piclimitstatus=Currently uploaded: [[current]] out of [[max]]. 
-
-.restriction.fileformat=File format must be either PNG, GIF or JPG
-
-.restriction.filesize=File size must be less than 40k
-
-.restriction.imagesize2=If dimensions are larger than 100x100 pixels, you will be taken to the Create Userpic page
-
-.restriction.keywords=Picture will be unusable if keywords are not supplied
-
-.restriction.keywords.faq=Picture will be unusable if <a [[aopts]]>keywords</a> are not supplied
-
-.title=Edit Userpics
-
-.title3|notes=This is the new page title.  .title is used by multisearch.bml.
-.title3=Manage Userpics
-
-.uploaddesc=Use the form below to upload a new picture.
-
-.uploaddesc.userpicfactory=Upload a JPG image of any size and we'll send you to the Userpic Factory where you can easily crop and resize it.
-
-.uploadheader=Upload a New Picture
-
-.uploadsuccessful=Image has been successfully uploaded
-
-.userpic=Userpic [[num]]: 
-
-.warning.keywords=One or more of your pictures do not have keywords defined and thus cannot currently be used
-
-.warning.keywords.faq=One or more of your pictures do not have <a [[aopts]]>keywords</a> defined and thus cannot currently be used
-
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/js/editicons.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/js/editicons.js	Mon Mar 08 22:25:40 2010 +0000
@@ -0,0 +1,209 @@
+var uptrack; // our Perlbal upload tracker object, if defined
+var uploadInProgress = false;
+var pbar = new LJProgressBar();
+
+function submitForm () {
+  if (uptrack) uptrack.stopTracking();
+
+  uploadInProgress = true;
+
+  var frm = $("uploadPic");
+  var postgoto = $("go_to");
+
+  if (!frm || !postgoto) return;
+
+  // to $POST{'go_to'} value of "jscallup" means our iframe returns a javascript
+  // document that calls up to us to tell us it's done.
+  postgoto.value = "jscallup";
+
+  frm.target = "upiframe";
+  uptrack = new UploadTracker(frm, uploadCallback);
+
+  $("uploadStatus").innerHTML = "Uploading, please wait...";
+  $("progressBar").style.display = "block";
+  $("uploadStatus").style.display = "block";
+  return true;
+}
+
+// called from iframe's content (manage/uploaded) on complete, after
+// uptrackWebUpload.pm redirects the iframe there:
+function onUploadComplete (gotoUrl) {
+  if (!uploadInProgress) return; // silly IE, caching the iframe's content
+
+  if (uptrack) uptrack.stopTracking();
+
+  if (pbar)
+    pbar.setIndefinite(true);
+
+  $("uploadStatus").innerHTML = "Upload complete.";
+
+  window.location = gotoUrl;
+}
+
+// called by the perlbal upload tracker library
+function uploadCallback (data) {
+  if (! (data && data.total)) return;
+  if (pbar) {
+    pbar.setMax(data.total);
+    pbar.setValue(data.done);
+  }
+  var percent = Math.floor(data.done/data.total*100);
+  var status = Math.floor(data.done / 1024) + " kB / " + Math.floor(data.total / 1024) + " kB, " + percent + "% complete";
+  $("uploadStatus").innerHTML = status;
+}
+
+function setup () {
+  if (!$("progressBar"))
+    return;
+
+  if (pbar)
+    pbar.init($("progressBar"));
+
+  $("progressBar").className="lj_progresscontainer";
+
+  DOM.addEventListener($("radio_url"), "click", selectUrlUpload);
+  DOM.addEventListener($("radio_file"), "click", selectFileUpload);
+  DOM.addEventListener($("urlpic_0"), "keypress", keyPressUrlUpload);
+  DOM.addEventListener($("userpic_0"), "change", keyPressFileUpload);
+}
+
+function editiconsInit() {
+    if ($("upload_desc_link")) {
+        $("upload_desc_link").style.display = 'block';
+        $("upload_desc").style.display = 'none';
+    }
+
+    if ($("upload_desc_photo_link")) {
+        $("upload_desc_photo_link").style.display = 'block';
+        $("upload_desc_photo").style.display = 'none';
+    }
+}
+
+function toggleElement(elementId) {
+    var el = $(elementId);
+    if (el && el.style.display == 'block') {
+        el.style.display = 'none';
+    } else {
+        el.style.display = 'block';
+    }
+}
+
+// keeps track of maximum number of uploads alowed
+var counter = 1;
+var maxcounter;
+var ep_labels = {};
+var allowComments = false;
+var allowDescriptions = false;
+
+function addNewUpload(uploadType) {
+  if (document.forms.uploadPic.make_default instanceof HTMLInputElement) {
+    value = document.forms.uploadPic.make_default.checked;
+    document.forms.uploadPic.make_default.type = "radio";
+    document.forms.uploadPic.make_default.checked = value;
+  }
+
+  insertIntoTag = document.getElementById("multi_insert");
+  insertElement = document.createElement("p");
+  insertElement.setAttribute("id", "additional_upload_" + counter);
+  insertElement.setAttribute("class", "pkg");
+
+  newPicHTML = "<input type='button' value='" + ep_labels.remove + "' onclick='javascript:removeAdditionalUpload(" + counter + ");' /><br/>\n";
+
+  if (uploadType == 'file') {
+    newPicHTML += "<label class='left' for='userpic_" + counter + "'>From <u>F</u>ile:</label>";
+    newPicHTML += "<input type='file' class='file' name='userpic_" + counter + "' id='userpic_" + counter + "' size='22' />";
+  } else if (uploadType == 'url') {
+    newPicHTML += "<label class='left' for='urlpic_'" + counter + ">";
+    newPicHTML += ep_labels.fromurl + '</label>';
+    newPicHTML += '<input type="text" name="urlpic_' + counter + '" id="urlpic_' + counter + '" class="text" />';
+  }
+  newPicHTML += "<label class='left' for='keywords_" + counter + "'>" + ep_labels.keywords + "</label><input type='text' name='keywords_" + counter + "' id='keywords_" + counter + "' class='text' />";
+  if (allowComments) {
+    newPicHTML += "<label class='left' for='comments_" + counter + "'>" + ep_labels.comment + "</label><input type='text' maxlength='120' name='comments_" + counter + "' id='comments_" + counter + "' class='text' />";
+  }
+  if (allowDescriptions) {
+    newPicHTML += "<label class='left' for='descriptions_" + counter + "'>" + ep_labels.description +"</label><input type='text' maxlength='120' name='descriptions_" + counter + "' id='descriptions_" + counter + "' class='text' />";
+  }
+  newPicHTML += "<br/><input type='radio' accesskey='" + ep_labels.makedefaultkey + "' value='" + counter + "' name='make_default' id='make_default_" + counter + "' /><label for='make_default_" + counter + "'>" + ep_labels.makedefault + "</label>\n";
+
+  insertElement.innerHTML = newPicHTML;
+  insertIntoTag.appendChild(insertElement);
+  counter++;
+  if (counter >= maxcounter) {
+    hideUploadButtons();
+  }
+
+  if (document.forms.uploadPic.make_default.length == 2) {
+    addNoDefaultButton();
+  }
+
+}
+
+function removeAdditionalUpload(removeIndex) {
+  if (document.forms.uploadPic.make_default.length == 3) {
+    removeNoDefaultButton();
+  }
+
+  removeFromTag = document.getElementById("multi_insert");
+  removeElement = document.getElementById("additional_upload_" + removeIndex);
+  removeFromTag.removeChild(removeElement);
+  maxcounter++;
+  if (counter < maxcounter) {
+    unhideUploadButtons();
+  }
+
+  if (document.forms.uploadPic.make_default instanceof HTMLInputElement) {
+    value = document.forms.uploadPic.make_default.checked;
+    document.forms.uploadPic.make_default.type = "checkbox";
+    document.forms.uploadPic.make_default.checked = value;
+  }
+}
+
+function hideUploadButtons() {
+  buttonsElement = document.getElementById("multi_insert_buttons");
+  buttonsElement.style.display = 'none';
+}
+
+function unhideUploadButtons() {
+  buttonsElement = document.getElementById("multi_insert_buttons");
+  buttonsElement.style.display = 'block';
+}
+
+function addNoDefaultButton() {
+  buttonsElement = document.getElementById("no_default_insert");
+  insertElement = document.createElement("p");
+  insertElement.setAttribute("id", "make_default_none");
+  insertElement.setAttribute("class", "pkg");
+
+  newPicHTML = "<input type='radio' accesskey='" + ep_labels.makedefaultkey +"' value='-1' name='make_default' id='make_default_button_none' /><label for='make_default_button_none'>" + ep_labels.keepdefault + "</label>\n";
+  insertElement.innerHTML = newPicHTML;
+  buttonsElement.appendChild(insertElement);
+}
+
+function removeNoDefaultButton() {
+  removeFromTag = document.getElementById("no_default_insert");
+  removeElement = document.getElementById("make_default_none");
+  removeFromTag.removeChild(removeElement);
+}
+
+function selectUrlUpload() {
+  $("userpic_0").disabled = true;
+  $("urlpic_0").disabled = false;
+}
+
+function selectFileUpload() {
+  $("urlpic_0").disabled = true;
+  $("userpic_0").disabled = false;
+}
+
+function keyPressUrlUpload() {
+  $("radio_url").checked =true;
+  selectUrlUpload();
+}
+
+function keyPressFileUpload() {
+  $("radio_file").checked =true;
+  selectFileUpload();
+}
+
+DOM.addEventListener(window, "load", setup);
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/js/editpics.js
--- a/htdocs/js/editpics.js	Mon Mar 08 22:09:09 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-var uptrack; // our Perlbal upload tracker object, if defined
-var uploadInProgress = false;
-var pbar = new LJProgressBar();
-
-function submitForm () {
-  if (uptrack) uptrack.stopTracking();
-
-  uploadInProgress = true;
-
-  var frm = $("uploadPic");
-  var postgoto = $("go_to");
-
-  if (!frm || !postgoto) return;
-
-  // to $POST{'go_to'} value of "jscallup" means our iframe returns a javascript
-  // document that calls up to us to tell us it's done.
-  postgoto.value = "jscallup";
-
-  frm.target = "upiframe";
-  uptrack = new UploadTracker(frm, uploadCallback);
-
-  $("uploadStatus").innerHTML = "Uploading, please wait...";
-  $("progressBar").style.display = "block";
-  $("uploadStatus").style.display = "block";
-  return true;
-}
-
-// called from iframe's content (manage/uploaded) on complete, after
-// uptrackWebUpload.pm redirects the iframe there:
-function onUploadComplete (gotoUrl) {
-  if (!uploadInProgress) return; // silly IE, caching the iframe's content
-
-  if (uptrack) uptrack.stopTracking();
-
-  if (pbar)
-    pbar.setIndefinite(true);
-
-  $("uploadStatus").innerHTML = "Upload complete.";
-
-  window.location = gotoUrl;
-}
-
-// called by the perlbal upload tracker library
-function uploadCallback (data) {
-  if (! (data && data.total)) return;
-  if (pbar) {
-    pbar.setMax(data.total);
-    pbar.setValue(data.done);
-  }
-  var percent = Math.floor(data.done/data.total*100);
-  var status = Math.floor(data.done / 1024) + " kB / " + Math.floor(data.total / 1024) + " kB, " + percent + "% complete";
-  $("uploadStatus").innerHTML = status;
-}
-
-function setup () {
-  if (!$("progressBar"))
-    return;
-
-  if (pbar)
-    pbar.init($("progressBar"));
-
-  $("progressBar").className="lj_progresscontainer";
-
-  DOM.addEventListener($("radio_url"), "click", selectUrlUpload);
-  DOM.addEventListener($("radio_file"), "click", selectFileUpload);
-  DOM.addEventListener($("urlpic_0"), "keypress", keyPressUrlUpload);
-  DOM.addEventListener($("userpic_0"), "change", keyPressFileUpload);
-}
-
-function editpicsInit() {
-    if ($("upload_desc_link")) {
-        $("upload_desc_link").style.display = 'block';
-        $("upload_desc").style.display = 'none';
-    }
-
-    if ($("upload_desc_photo_link")) {
-        $("upload_desc_photo_link").style.display = 'block';
-        $("upload_desc_photo").style.display = 'none';
-    }
-}
-
-function toggleElement(elementId) {
-    var el = $(elementId);
-    if (el && el.style.display == 'block') {
-        el.style.display = 'none';
-    } else {
-        el.style.display = 'block';
-    }
-}
-
-// keeps track of maximum number of uploads alowed
-var counter = 1;
-var maxcounter;
-var ep_labels = {};
-var allowComments = false;
-var allowDescriptions = false;
-
-function addNewUpload(uploadType) {
-  if (document.forms.uploadPic.make_default instanceof HTMLInputElement) {
-    value = document.forms.uploadPic.make_default.checked;
-    document.forms.uploadPic.make_default.type = "radio";
-    document.forms.uploadPic.make_default.checked = value;
-  }
-
-  insertIntoTag = document.getElementById("multi_insert");
-  insertElement = document.createElement("p");
-  insertElement.setAttribute("id", "additional_upload_" + counter);
-  insertElement.setAttribute("class", "pkg");
-
-  newPicHTML = "<input type='button' value='" + ep_labels.remove + "' onclick='javascript:removeAdditionalUpload(" + counter + ");' /><br/>\n";
-
-  if (uploadType == 'file') {
-    newPicHTML += "<label class='left' for='userpic_" + counter + "'>From <u>F</u>ile:</label>";
-    newPicHTML += "<input type='file' class='file' name='userpic_" + counter + "' id='userpic_" + counter + "' size='22' />";
-  } else if (uploadType == 'url') {
-    newPicHTML += "<label class='left' for='urlpic_'" + counter + ">";
-    newPicHTML += ep_labels.fromurl + '</label>';
-    newPicHTML += '<input type="text" name="urlpic_' + counter + '" id="urlpic_' + counter + '" class="text" />';
-  }
-  newPicHTML += "<label class='left' for='keywords_" + counter + "'>" + ep_labels.keywords + "</label><input type='text' name='keywords_" + counter + "' id='keywords_" + counter + "' class='text' />";
-  if (allowComments) {
-    newPicHTML += "<label class='left' for='comments_" + counter + "'>" + ep_labels.comment + "</label><input type='text' maxlength='120' name='comments_" + counter + "' id='comments_" + counter + "' class='text' />";
-  }
-  if (allowDescriptions) {
-    newPicHTML += "<label class='left' for='descriptions_" + counter + "'>" + ep_labels.description +"</label><input type='text' maxlength='120' name='descriptions_" + counter + "' id='descriptions_" + counter + "' class='text' />";
-  }
-  newPicHTML += "<br/><input type='radio' accesskey='" + ep_labels.makedefaultkey + "' value='" + counter + "' name='make_default' id='make_default_" + counter + "' /><label for='make_default_" + counter + "'>" + ep_labels.makedefault + "</label>\n";
-
-  insertElement.innerHTML = newPicHTML;
-  insertIntoTag.appendChild(insertElement);
-  counter++;
-  if (counter >= maxcounter) {
-    hideUploadButtons();
-  }
-
-  if (document.forms.uploadPic.make_default.length == 2) {
-    addNoDefaultButton();
-  }
-
-}
-
-function removeAdditionalUpload(removeIndex) {
-  if (document.forms.uploadPic.make_default.length == 3) {
-    removeNoDefaultButton();
-  }
-
-  removeFromTag = document.getElementById("multi_insert");
-  removeElement = document.getElementById("additional_upload_" + removeIndex);
-  removeFromTag.removeChild(removeElement);
-  maxcounter++;
-  if (counter < maxcounter) {
-    unhideUploadButtons();
-  }
-
-  if (document.forms.uploadPic.make_default instanceof HTMLInputElement) {
-    value = document.forms.uploadPic.make_default.checked;
-    document.forms.uploadPic.make_default.type = "checkbox";
-    document.forms.uploadPic.make_default.checked = value;
-  }
-}
-
-function hideUploadButtons() {
-  buttonsElement = document.getElementById("multi_insert_buttons");
-  buttonsElement.style.display = 'none';
-}
-
-function unhideUploadButtons() {
-  buttonsElement = document.getElementById("multi_insert_buttons");
-  buttonsElement.style.display = 'block';
-}
-
-function addNoDefaultButton() {
-  buttonsElement = document.getElementById("no_default_insert");
-  insertElement = document.createElement("p");
-  insertElement.setAttribute("id", "make_default_none");
-  insertElement.setAttribute("class", "pkg");
-
-  newPicHTML = "<input type='radio' accesskey='" + ep_labels.makedefaultkey +"' value='-1' name='make_default' id='make_default_button_none' /><label for='make_default_button_none'>" + ep_labels.keepdefault + "</label>\n";
-  insertElement.innerHTML = newPicHTML;
-  buttonsElement.appendChild(insertElement);
-}
-
-function removeNoDefaultButton() {
-  removeFromTag = document.getElementById("no_default_insert");
-  removeElement = document.getElementById("make_default_none");
-  removeFromTag.removeChild(removeElement);
-}
-
-function selectUrlUpload() {
-  $("userpic_0").disabled = true;
-  $("urlpic_0").disabled = false;
-}
-
-function selectFileUpload() {
-  $("urlpic_0").disabled = true;
-  $("userpic_0").disabled = false;
-}
-
-function keyPressUrlUpload() {
-  $("radio_url").checked =true;
-  selectUrlUpload();
-}
-
-function keyPressFileUpload() {
-  $("radio_file").checked =true;
-  selectFileUpload();
-}
-
-DOM.addEventListener(window, "load", setup);
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/manage/index.bml
--- a/htdocs/manage/index.bml	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/manage/index.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -229,7 +229,7 @@ header=><?_ml .userpics.header _ml?>
 header=><?_ml .userpics.header _ml?>
 about=><?_ml .userpics        _ml?>
 list<=
-<li><a href="/editpics<?authas?>"><?_ml .userpics.edit.about _ml?></a></li>
+<li><a href="/editicons<?authas?>"><?_ml .userpics.edit.about _ml?></a></li>
 <=list
 block?>
 
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/manage/profile/index.bml
--- a/htdocs/manage/profile/index.bml	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/manage/profile/index.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -133,7 +133,7 @@ body<=
         $ret .= "</div><div style='margin-left: 110px'>\n";
         $ret .= "<span class='helper'>$ML{'.userpic'}</span>";
         $ret .= LJ::help_icon('upic_keywords');
-        $ret .= "<?p <a href='$LJ::SITEROOT/editpics$getextra'>$ML{'.userpic.change'}</a> p?>\n";
+        $ret .= "<?p <a href='$LJ::SITEROOT/editicons$getextra'>$ML{'.userpic.change'}</a> p?>\n";
         $ret .= "</td>";
         $ret .= "</tr>\n";
 
@@ -742,7 +742,7 @@ body<=
                          "<?p $ML{'.success.gonext'} p?>" .
                          "<ul><li><a href='$profile_url'>$ML{'.success.viewprofile'}</a></li>" .
                          "<li><a href='$LJ::SITEROOT/manage/profile/$getextra'>$ML{'.success.editprofile'}</a></li>" .
-                         "<li><a href='$LJ::SITEROOT/editpics$getextra'>$ML{'.success.editpics'}</a></li></ul>";
+                         "<li><a href='$LJ::SITEROOT/editicons$getextra'>$ML{'.success.editicons'}</a></li></ul>";
     }
 
     # should never happen
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/manage/profile/index.bml.text
--- a/htdocs/manage/profile/index.bml.text	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/manage/profile/index.bml.text	Mon Mar 08 22:25:40 2010 +0000
@@ -227,7 +227,7 @@
 
 .state.us=US States
 
-.success.editpics=Manage your userpics
+.success.editicons=Manage your userpics
 
 .success.editprofile=Edit your profile
 
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/site/index.bml
--- a/htdocs/site/index.bml	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/site/index.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -40,7 +40,7 @@ body<=
    <li><a href='/manage/tags'><?_ml .maplinks.manage-tags _ml?></a></li>
    <li><a href='/tools/memories'><?_ml .maplinks.manage-memories _ml?></a></li>
    <li><a href='/manage/profile'><?_ml .maplinks.manage-profile _ml?></a></li>
-   <li><a href='/editpics'><?_ml .maplinks.manage-userpics _ml?></a></li>
+   <li><a href='/editicons'><?_ml .maplinks.manage-userpics _ml?></a></li>
    <li><a href='/poll/create'><?_ml .maplinks.create-poll _ml?></a></li>
   </ul></dd>
  </dt></dl>
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/stc/blueshift/blueshift.css
--- a/htdocs/stc/blueshift/blueshift.css	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/stc/blueshift/blueshift.css	Mon Mar 08 22:25:40 2010 +0000
@@ -381,7 +381,7 @@ table#table_yourlayers td { padding: .15
  * Other site scheme designers: use your own colors here
  * /
 
-/* editpics.css */
+/* editicons.css */
 #uploadBox {
     background-color: #E6ECF9;
     border: 1px solid #3960A0;
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/stc/celerity/celerity.css
--- a/htdocs/stc/celerity/celerity.css	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/stc/celerity/celerity.css	Mon Mar 08 22:25:40 2010 +0000
@@ -416,7 +416,7 @@ table#table_yourlayers td { padding: .15
  * Other site scheme designers: use your own colors here
  * /
 
-/* editpics.css */
+/* editicons.css */
 #uploadBox {
     background-color: #EEEECC;
     border: 1px solid #999966;
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/stc/editicons.css
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/stc/editicons.css	Mon Mar 08 22:25:40 2010 +0000
@@ -0,0 +1,125 @@
+#Content input.text,
+#Content input.radio,
+#Content input.file,
+#Content label.left,
+#Content .helplink {
+    float: left;
+}
+#Content .helplink {
+    margin-top: 4px;
+}
+#Content label.left {
+    min-width: 6em !important;
+    line-height: 20px !important; 
+}
+* html #Content label.left {
+    width: 6em;
+}
+hr {
+    clear: left;
+}
+#userpic_authas {
+    margin-bottom: 10px;
+}
+#uploadBox {
+    float: left;
+    width: 300px;
+    margin: 0 15px 0 0;
+	background: #eee; }
+	
+#uploadBox-inner  {
+    padding: 6px 12px;
+}
+#upload_desc, #upload_desc_photo {
+    font-size: 0.9em;
+    line-height: 1.4em;
+    margin-bottom: 8px;
+}
+#uploadBox p {
+    margin: 0 0 6px 0;
+}
+#uploadBox p.detail {
+    margin: 0 0 10px 0
+}
+#uploadBox input.text {
+    width: 240px;
+}
+#submit_wrapper {
+    text-align: center;
+}
+#current_userpics {
+    margin-left: 320px;
+}
+.userpic_wrapper {
+    margin: 10px 0 5px 0;
+}
+.EditIconsUserpic {
+    margin-right: 10px;
+    display: block;
+    text-align: center;
+    width: 100px;
+    height: 100px;
+    float: left;
+    clear: left;
+    margin-bottom: 10px;
+}
+.userpic_defaultdelete input.radio,
+.userpic_defaultdelete input.checkbox,
+.userpic_defaultdelete label {
+    float: none;
+}
+@media all and (min-width: 0px){ .userpic_controls { 
+    width: 400px;
+}}
+.userpic_controls input.text {
+    width: 220px;
+}
+* html .userpic_controls input.text {
+    width: 180px;
+}
+*:first-child+html .userpic_controls input.text {
+    width: 180px;
+}
+.userpic_keywords, .userpic_comments, .userpic_descriptions, .userpic_defaultdelete {
+    float: left;
+    clear: left;
+    margin-bottom: 8px;
+}
+.userpic_defaultdelete {
+    width: 200px;
+}
+.userpic_rename {
+    width: 200px;
+    margin-left: 6.5em;
+    margin-bottom: 4px;
+    margin-top: 4px;
+}
+* html .userpic_keywords,
+* html .userpic_comments,
+* html .userpic_descriptions {
+    width: 290px;
+}
+*:first-child+html .userpic_keywords, 
+*:first-child+html .userpic_comments,
+*:first-child+html .userpic_descriptions {
+    width: 290px;
+}
+html>body .userpic_defaultdelete {
+    margin-left: 6.5em;
+}
+.userpic_defaultdelete label {
+    margin-right: 10px !important;
+}
+#no_default_userpic {
+    text-align: center;
+}
+#userpic_submit {
+    width: 120px;
+    margin: 0 auto;
+    text-align: center;
+}
+#no_default_userpic input.radio,
+#no_default_userpic label {
+    float: none;
+    display: inline;
+}
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/stc/editpics.css
--- a/htdocs/stc/editpics.css	Mon Mar 08 22:09:09 2010 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-#Content input.text,
-#Content input.radio,
-#Content input.file,
-#Content label.left,
-#Content .helplink {
-    float: left;
-}
-#Content .helplink {
-    margin-top: 4px;
-}
-#Content label.left {
-    min-width: 6em !important;
-    line-height: 20px !important; 
-}
-* html #Content label.left {
-    width: 6em;
-}
-hr {
-    clear: left;
-}
-#userpic_authas {
-    margin-bottom: 10px;
-}
-#uploadBox {
-    float: left;
-    width: 300px;
-    margin: 0 15px 0 0;
-	background: #eee; }
-	
-#uploadBox-inner  {
-    padding: 6px 12px;
-}
-#upload_desc, #upload_desc_photo {
-    font-size: 0.9em;
-    line-height: 1.4em;
-    margin-bottom: 8px;
-}
-#uploadBox p {
-    margin: 0 0 6px 0;
-}
-#uploadBox p.detail {
-    margin: 0 0 10px 0
-}
-#uploadBox input.text {
-    width: 240px;
-}
-#submit_wrapper {
-    text-align: center;
-}
-#current_userpics {
-    margin-left: 320px;
-}
-.userpic_wrapper {
-    margin: 10px 0 5px 0;
-}
-.EditPicsUserpic {
-    margin-right: 10px;
-    display: block;
-    text-align: center;
-    width: 100px;
-    height: 100px;
-    float: left;
-    clear: left;
-    margin-bottom: 10px;
-}
-.userpic_defaultdelete input.radio,
-.userpic_defaultdelete input.checkbox,
-.userpic_defaultdelete label {
-    float: none;
-}
-@media all and (min-width: 0px){ .userpic_controls { 
-    width: 400px;
-}}
-.userpic_controls input.text {
-    width: 220px;
-}
-* html .userpic_controls input.text {
-    width: 180px;
-}
-*:first-child+html .userpic_controls input.text {
-    width: 180px;
-}
-.userpic_keywords, .userpic_comments, .userpic_descriptions, .userpic_defaultdelete {
-    float: left;
-    clear: left;
-    margin-bottom: 8px;
-}
-.userpic_defaultdelete {
-    width: 200px;
-}
-.userpic_rename {
-    width: 200px;
-    margin-left: 6.5em;
-    margin-bottom: 4px;
-    margin-top: 4px;
-}
-* html .userpic_keywords,
-* html .userpic_comments,
-* html .userpic_descriptions {
-    width: 290px;
-}
-*:first-child+html .userpic_keywords, 
-*:first-child+html .userpic_comments,
-*:first-child+html .userpic_descriptions {
-    width: 290px;
-}
-html>body .userpic_defaultdelete {
-    margin-left: 6.5em;
-}
-.userpic_defaultdelete label {
-    margin-right: 10px !important;
-}
-#no_default_userpic {
-    text-align: center;
-}
-#userpic_submit {
-    width: 120px;
-    margin: 0 auto;
-    text-align: center;
-}
-#no_default_userpic input.radio,
-#no_default_userpic label {
-    float: none;
-    display: inline;
-}
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/stc/gradation/gradation-vertical.css
--- a/htdocs/stc/gradation/gradation-vertical.css	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/stc/gradation/gradation-vertical.css	Mon Mar 08 22:25:40 2010 +0000
@@ -429,7 +429,7 @@ table#table_yourlayers td { padding: .15
  * Other site scheme designers: use your own colors here
  * /
 
-/* editpics.css */
+/* editicons.css */
 #uploadBox {
     background-color: #333333;
     border: 1px solid #888888;
diff -r 8bd7822e342b -r 4f61e7788b51 htdocs/tools/userpicfactory.bml
--- a/htdocs/tools/userpicfactory.bml	Mon Mar 08 22:09:09 2010 +0000
+++ b/htdocs/tools/userpicfactory.bml	Mon Mar 08 22:25:40 2010 +0000
@@ -179,7 +179,7 @@ if ($GET{successcount}) {
 }
 
 $body .= qq {
-    <a href="/editpics$sfx"><< Edit Icons</a>
+    <a href="/editicons$sfx"><< Edit Icons</a>
     <noscript><p><b>
 You need JavaScript in order to use the
 Icon Factory. Since you have JavaScript disabled, you will be unable
@@ -191,7 +191,7 @@ Create Icon button.</b></p>
 
 
 my $upload_form = qq {
-        <form enctype="multipart/form-data" action="/editpics$sfx"
+        <form enctype="multipart/form-data" action="/editicons$sfx"
         method='post'>
       From File: <input type="file" name="userpic" /><br/>
       <small>JPEG only.</small>
@@ -225,7 +225,7 @@ if (0) {
       <div id="picContainer" style="float: left; margin-bottom: 15px; width: ${scaledSizeMax}px; height: ${scaledSizeMax}px; border: 2px solid #EEEEEE; padding: 2px;"> <img src="$picpath" id="userpic" style="display: none;" /></div>
 
       <?standout <div style='float: right;'>
-      <form action="$LJ::SITEROOT/editpics$sfx?authas=$GET{'authas'}" method="POST" enctype='multipart/form-data'>
+      <form action="$LJ::SITEROOT/editicons$sfx?authas=$GET{'authas'}" method="POST" enctype='multipart/form-data'>
       <table cellpadding="4"><tr>
       <td style='whitespace: nowrap'>
         <nobr><input type="checkbox" id="constrain" onchange="setConstrain();" />
--------------------------------------------------------------------------------