Index: extlib/Data/ObjectDriver.pm =================================================================== --- extlib/Data/ObjectDriver.pm (revision 92) +++ extlib/Data/ObjectDriver.pm (working copy) @@ -1,4 +1,4 @@ -# $Id: ObjectDriver.pm 506 2008-06-30 17:52:14Z ykerherve $ +# $Id: ObjectDriver.pm 560 2009-01-28 18:37:28Z btrott $ package Data::ObjectDriver; use strict; @@ -10,7 +10,7 @@ __PACKAGE__->mk_accessors(qw( pk_generator txn_active )); -our $VERSION = '0.05'; +our $VERSION = '0.06'; our $DEBUG = $ENV{DOD_DEBUG} || 0; our $PROFILE = $ENV{DOD_PROFILE} || 0; our $PROFILER; @@ -68,7 +68,7 @@ _end_txn($driver, 'commit'); } -sub rollback { +sub rollback { my $driver = shift; _end_txn($driver, 'rollback'); } @@ -648,7 +648,7 @@ Data::ObjectDriver::BaseObject->rollback; } -=head2 Driver implementation +=head2 Driver implementation Drivers have to implement the following methods: @@ -656,7 +656,7 @@ =item * begin_work to initialize a transaction -=item * rollback +=item * rollback =item * commmit @@ -671,16 +671,16 @@ =head2 Transactions and DBI -In order to make transactions work properly you have to make sure that +In order to make transactions work properly you have to make sure that the C<$dbh> for each DBI drivers are shared among drivers using the same database (basically dsn). One way of doing that is to define a get_dbh() subref in each DBI driver -to return the same dbh if the dsn and attributes of the connection are +to return the same dbh if the dsn and attributes of the connection are identical. The other way is to use the new configuration flag on the DBI driver that -has been added specifically for this purpose: C. +has been added specifically for this purpose: C. ## example coming from the test suite __PACKAGE__->install_properties({ @@ -753,11 +753,38 @@ 1; +=head1 SUPPORTED DATABASES + +I is very modular and it's not very diffucult to add new drivers. + +=over 4 + +=item * MySQL is well supported and has been heavily tested. + +=item * PostgreSQL has been been used in production and should just work, too. + +=item * SQLite is supported, but YMMV depending on the version. This is the +backend used for the test suite. + +=item * Oracle support has been added in 0.06 + +=back + =head1 LICENSE I is free software; you may redistribute it and/or modify it under the same terms as Perl itself. +=head1 MAILING LIST, CODE & MORE INFORMATION + +I developers can be reached via the following group: +L + +Bugs should be reported using the CPAN RT system, patches are encouraged when +reporting bugs. + +L + =head1 AUTHOR & COPYRIGHT Except where otherwise noted, I is Copyright 2005-2006 Index: extlib/Data/ObjectDriver/Driver/DBD.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/DBD.pm (revision 92) +++ extlib/Data/ObjectDriver/Driver/DBD.pm (working copy) @@ -1,4 +1,4 @@ -# $Id: DBD.pm 458 2008-02-25 06:21:26Z btrott $ +# $Id: DBD.pm 558 2009-01-22 21:20:09Z miyagawa $ package Data::ObjectDriver::Driver::DBD; use strict; @@ -11,7 +11,7 @@ die "No Driver" unless $name; my $subclass = join '::', $class, $name; no strict 'refs'; - unless (defined ${"${subclass}::"}) { + unless (defined %{"${subclass}::"}) { eval "use $subclass"; ## no critic die $@ if $@; } @@ -39,8 +39,12 @@ sub can_replace { 0 } +# Some drivers have problems with prepared caches +sub can_prepare_cached_statements { 1 }; + sub sql_class { 'Data::ObjectDriver::SQL' } + 1; __END__ @@ -150,6 +154,12 @@ By default, C returns false. +=head2 C<$dbd-Ecan_prepare_cached_statements()> + +Returns true if the database this driver can cope with preparing a cached statement. + +By default, C returns true. + =head2 C<$dbd-Eis_case_insensitive()> Returns true if the database this driver represents normally compares string @@ -159,9 +169,18 @@ =head2 C<$dbd-Ecan_replace()> -Returns true or false if the driver can do "REPLACE INTO" only Mysql and -SQLite does. By default returns false. +Returns true if the database this driver represents supports C +statements. +By default, C returns false. + +=head2 C<$dbd-Eforce_no_prepared_cache()> + +Returns false if the database this driver represents supports the +C method on its DBI database handles. + +By default, C returns false. + =head2 C<$dbd-Esql_class()> Provides the package name of the class responsible for representing SQL Index: extlib/Data/ObjectDriver/Driver/DBD/Oracle.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/DBD/Oracle.pm (revision 0) +++ extlib/Data/ObjectDriver/Driver/DBD/Oracle.pm (revision 0) @@ -0,0 +1,159 @@ +# $Id$ +# Contributor(s): Xiaoou Wu +# +package Data::ObjectDriver::Driver::DBD::Oracle; + +use strict; + +use base qw( Data::ObjectDriver::Driver::DBD ); + +use Data::ObjectDriver::SQL::Oracle; +use Data::ObjectDriver::Errors; +use DBD::Oracle qw(:ora_types); + +sub init_dbh { + my $dbd = shift; + my ($dbh) = @_; + $dbh->{LongReadLen} = 1024000; + $dbh->{FetchHashKeyName} = 'NAME_lc'; + return bless $dbh, 'Data::ObjectDriver::Driver::DBD::Oracle::db'; +} + +sub bind_param_attributes { + my ($dbd, $data_type) = @_; + if ($data_type && $data_type eq 'blob') { + return { ora_type => ORA_BLOB }; + } + return; +} + +sub map_error_code { + my $dbd = shift; + my($code, $msg) = @_; + if ($msg && $msg =~ /ORA-00001/i) { + return Data::ObjectDriver::Errors->UNIQUE_CONSTRAINT; + } else { + return; + } +} + +## Oracle doesn't support auto-increment, it needs a SEQUENCE to emulate +## this feature. For usage, please see NOTES. +sub fetch_id { + my $dbd = shift; + my ($class, $dbh, $sth, $driver) = @_; + my $seq = $dbd->sequence_name($class, $driver); + my ($last_insert_id) = $dbh->selectrow_array("SELECT $seq.CURRVAL " + . " FROM DUAL"); + return $last_insert_id; +} + +sub sequence_name { + my $dbd = shift; + my ($class, $driver) = @_; + my $datasource = $class ->datasource; + my $prefix = $driver->prefix; + $datasource = join('', $prefix, $datasource) if $prefix; + join '_', $datasource, + $dbd->db_column_name( + $class->datasource, + $class->properties->{primary_key}, + ), + 'seq'; +} + +sub bulk_insert { + my $dbd = shift; + my $dbh = shift; + my $table = shift; + my $cols = shift; + my $rows_ref = shift; + + my $sql = "INSERT INTO $table(" + . join(',', @$cols) + . ") VALUES (" + . join(',', map {'?'} @$cols) + . ")"; + my $sth = $dbh->prepare($sql); + foreach my $row (@{ $rows_ref || []}) { + $sth->execute(@$row); + } + return 1; +} + +## +sub sql_class { 'Data::ObjectDriver::SQL::Oracle' } + +package Data::ObjectDriver::Driver::DBD::Oracle::db; + +use strict; + +## Inherit the DB class from DBI::db. +use base qw(DBI::db); + +## Oracle doesn't allow a SELECT statement without FROM. +sub _adjust_stmt { + my $stmt = shift; + my $has_select = ($stmt =~ m/^\s*SELECT\b/io); + my $has_from = ($stmt =~ m/\bFROM\b/io); + $stmt .= " FROM DUAL" if ($has_select and !$has_from); + return $stmt; +} + +sub selectrow_array { + my $self = shift; + my $stmt = shift; + $stmt = _adjust_stmt($stmt); + unshift @_, $stmt; + $self->SUPER::selectrow_array(@_); +} + +1; + +__END__ + +=head1 NAME + +Data::ObjectDriver::Driver::DBD::Oracle - Oracle Driver for Data::ObjectDriver + +=head1 DESCRIPTION + +This module overrides methods of the Data::ObjectDriver::Driver::DBD module +with Oracle specific implementation. + +=head1 NOTES + +Oracle doesn't support auto-increment, so before you use this feature, you +should create a sequence and a trigger to work with it. + +For example, you want field ID in table WINES be auto-increment, then create: + + -- Create sequence + CREATE SEQUENCE WINES_ID_SEQ + MINVALUE 1 + MAXVALUE 999999999999999999999999999 + START WITH 1 + INCREMENT BY 1 + NOCACHE; + + -- Create trigger + CREATE OR REPLACE TRIGGER WINES_ID_TR + BEFORE INSERT ON WINES + FOR EACH ROW + BEGIN + SELECT WINES_ID_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL; + END; + +=head1 LICENSE + +This module is free software; +you may redistribute and/or modify it under the same +terms as Perl itself. + +=head1 AUTHOR & COPYRIGHT + +This module is +copyright (c) 2009 Xiaoou Wu Exiaoou.wu@oracle.comE. +All rights reserved. + +=cut Index: extlib/Data/ObjectDriver/Driver/DBD/Pg.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/DBD/Pg.pm (revision 92) +++ extlib/Data/ObjectDriver/Driver/DBD/Pg.pm (working copy) @@ -1,4 +1,4 @@ -# $Id: Pg.pm 300 2006-11-22 02:02:52Z ykerherve $ +# $Id: Pg.pm 550 2008-12-22 22:26:14Z ykerherve $ package Data::ObjectDriver::Driver::DBD::Pg; use strict; @@ -7,8 +7,9 @@ use base qw( Data::ObjectDriver::Driver::DBD ); # No postgresql doesn't allow MySQL's REPLACE INTO syntax -sub can_replace { 1 } +sub can_replace { 0 } + sub init_dbh { my $dbd = shift; my($dbh) = @_; @@ -26,17 +27,21 @@ sub sequence_name { my $dbd = shift; - my($class) = @_; - join '_', $class->datasource, + my($class, $driver) = @_; + + my $datasource = $class ->datasource; + my $prefix = $driver->prefix; + $datasource = join('', $prefix, $datasource) if $prefix; + join '_', $datasource, $dbd->db_column_name($class->datasource, $class->properties->{primary_key}), 'seq'; } sub fetch_id { my $dbd = shift; - my($class, $dbh, $sth) = @_; + my($class, $dbh, $sth, $driver) = @_; $dbh->last_insert_id(undef, undef, undef, undef, - { sequence => $dbd->sequence_name($class) }); + { sequence => $dbd->sequence_name($class, $driver) }); } sub bulk_insert { Index: extlib/Data/ObjectDriver/Driver/DBD/SQLite.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/DBD/SQLite.pm (revision 92) +++ extlib/Data/ObjectDriver/Driver/DBD/SQLite.pm (working copy) @@ -7,14 +7,17 @@ use Data::ObjectDriver::Errors; -# yes according to http://www.sqlite.org/lang_replace.html +# yes according to http://www.sqlite.org/lang_replace.html sub can_replace { 1 } +# SQLite has problems with prepare_cached +sub can_prepare_cached_statements { 0 } + sub fetch_id { $_[2]->func('last_insert_rowid') } sub bind_param_attributes { my ($dbd, $data_type) = @_; - if ($data_type) { + if ($data_type) { if ($data_type eq 'blob') { return DBI::SQL_BLOB; } elsif ($data_type eq 'binchar') { @@ -56,7 +59,6 @@ return 1; } - 1; =pod @@ -77,6 +79,6 @@ With the 1.11 version of L Blobs are handled transparently, so C is optionnal. With previous version of L users have experimented issues -with binary data in CHAR (partially solved by the DBI::SQL_BINARY binding). +with binary data in CHAR (partially solved by the DBI::SQL_BINARY binding). =cut Index: extlib/Data/ObjectDriver/Driver/DBI.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/DBI.pm (revision 92) +++ extlib/Data/ObjectDriver/Driver/DBI.pm (working copy) @@ -1,4 +1,4 @@ -# $Id: DBI.pm 509 2008-07-02 18:00:57Z ykerherve $ +# $Id: DBI.pm 559 2009-01-24 00:30:59Z ykerherve $ package Data::ObjectDriver::Driver::DBI; use strict; @@ -13,8 +13,9 @@ use Data::ObjectDriver::Driver::DBD; use Data::ObjectDriver::Iterator; -__PACKAGE__->mk_accessors(qw( dsn username password connect_options dbh get_dbh dbd prefix reuse_dbh )); +__PACKAGE__->mk_accessors(qw( dsn username password connect_options dbh get_dbh dbd prefix reuse_dbh force_no_prepared_cache)); + sub init { my $driver = shift; my %param = @_; @@ -45,6 +46,21 @@ } } +# Some versions of SQLite require the undefing to finalise properly +sub _close_sth { + my $sth = shift; + $sth->finish; + undef $sth; +} + +# Some versions of SQLite have problems with prepared caching due to finalisation order +sub _prepare_cached { + my $driver = shift; + my $dbh = shift; + my $sql = shift; + return ($driver->dbd->can_prepare_cached_statements)? $dbh->prepare_cached($sql) : $dbh->prepare($sql); +} + my %Handles; sub init_db { my $driver = shift; @@ -97,14 +113,14 @@ my $rec = {}; my $sth = $driver->fetch($rec, $obj, $terms, $args); $sth->fetch; - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return $rec; } -sub fetch { +sub prepare_fetch { my $driver = shift; - my($rec, $class, $orig_terms, $orig_args) = @_; + my($class, $orig_terms, $orig_args) = @_; ## Use (shallow) duplicates so the pre_search trigger can modify them. my $terms = defined $orig_terms ? ( ref $orig_terms eq 'ARRAY' ? [ @$orig_terms ] : { %$orig_terms } ) : {}; @@ -113,23 +129,33 @@ my $stmt = $driver->prepare_statement($class, $terms, $args); + my $sql = $stmt->as_sql; + $sql .= "\nFOR UPDATE" if $orig_args->{for_update}; + return ($sql, $stmt->{bind}, $stmt) +} + +sub fetch { + my $driver = shift; + my($rec, $class, $orig_terms, $orig_args) = @_; + + my ($sql, $bind, $stmt) = $driver->prepare_fetch($class, $orig_terms, $orig_args); + my @bind; my $map = $stmt->select_map; for my $col (@{ $stmt->select }) { push @bind, \$rec->{ $map->{$col} }; } - my $sql = $stmt->as_sql; - $sql .= "\nFOR UPDATE" if $orig_args->{for_update}; my $dbh = $driver->r_handle($class->properties->{db}); $driver->start_query($sql, $stmt->{bind}); - my $sth = $orig_args->{no_cached_prepare} ? $dbh->prepare($sql) : $dbh->prepare_cached($sql); + + my $sth = $orig_args->{no_cached_prepare} ? $dbh->prepare($sql) : $driver->_prepare_cached($dbh, $sql); $sth->execute(@{ $stmt->{bind} }); $sth->bind_columns(undef, @bind); # need to slurp 'offset' rows for DBs that cannot do it themselves - if (!$driver->dbd->offset_implemented && $args->{offset}) { - for (1..$args->{offset}) { + if (!$driver->dbd->offset_implemented && $orig_args->{offset}) { + for (1..$orig_args->{offset}) { $sth->fetch; } } @@ -137,10 +163,23 @@ return $sth; } +sub load_object_from_rec { + my $driver = shift; + my ($class, $rec, $no_triggers) = @_; + + my $obj = $class->new; + $obj->set_values_internal($rec); + ## Don't need a duplicate as there's no previous version in memory + ## to preserve. + $obj->{__is_stored} = 1; + $obj->call_trigger('post_load') unless $no_triggers; + return $obj; +} + sub search { my($driver) = shift; my($class, $terms, $args) = @_; - + my $rec = {}; my $sth = $driver->fetch($rec, $class, $terms, $args); @@ -151,18 +190,11 @@ my $d = $driver; unless ($sth->fetch) { - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return; } - my $obj; - $obj = $class->new; - $obj->set_values_internal($rec); - ## Don't need a duplicate as there's no previous version in memory - ## to preserve. - $obj->{__is_stored} = 1; - $obj->call_trigger('post_load') unless $args->{no_triggers}; - $obj; + return $driver->load_object_from_rec($class, $rec, $args->{no_triggers}); }; if (wantarray) { @@ -174,7 +206,7 @@ return @objs; } else { my $iterator = Data::ObjectDriver::Iterator->new( - $iter, sub { $sth->finish; $driver->end_query($sth) }, + $iter, sub { _close_sth($sth); $driver->end_query($sth) }, ); return $iterator; } @@ -216,16 +248,16 @@ my $dbh = $driver->r_handle; $driver->start_query($sql, $bind); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); $sth->execute(@$bind); $sth->bind_columns(undef, \my($val)); unless ($sth->fetch) { - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return; } - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return $val; @@ -256,10 +288,10 @@ $sql .= $stmt->as_sql_where; my $dbh = $driver->r_handle($obj->properties->{db}); $driver->start_query($sql, $stmt->{bind}); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); $sth->execute(@{ $stmt->{bind} }); my $exists = $sth->fetch; - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return $exists; @@ -300,7 +332,7 @@ ## Syntax switch between INSERT or REPLACE statement based on options $options ||= {}; my $INSERT_OR_REPLACE = $options->{replace} ? 'REPLACE' : 'INSERT'; - + ## Use a duplicate so the pre_save trigger can modify it. my $obj = $orig_obj->clone_all; $obj->call_trigger('pre_save', $orig_obj); @@ -336,7 +368,7 @@ 'VALUES (' . join(', ', ('?') x @$cols) . ')' . "\n"; my $dbh = $driver->rw_handle($obj->properties->{db}); $driver->start_query($sql, $obj->{column_values}); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); my $i = 1; my $col_defs = $obj->properties->{column_defs}; for my $col (@$cols) { @@ -345,8 +377,9 @@ my $attr = $dbd->bind_param_attributes($type, $obj, $col); $sth->bind_param($i++, $val, $attr); } - $sth->execute; - $sth->finish; + eval { $sth->execute }; + die "Failed to execute $sql with ".join(", ",@$cols).": $@" if $@; + _close_sth($sth); $driver->end_query($sth); ## Now, if we didn't have an object ID, we need to grab the @@ -354,7 +387,7 @@ if (!$obj->is_pkless && ! $obj->has_primary_key) { my $pk = $obj->primary_key_tuple; ## but do that only for relation that aren't PK-less my $id_col = $pk->[0]; # XXX are we sure we will always use '0' ? - my $id = $dbd->fetch_id(ref($obj), $dbh, $sth); + my $id = $dbd->fetch_id(ref($obj), $dbh, $sth, $driver); $obj->$id_col($id); ## The ID is the only thing we *are* allowed to change on ## the original object. @@ -371,6 +404,7 @@ sub update { my $driver = shift; + my($orig_obj, $terms) = @_; ## Use a duplicate so the pre_save trigger can modify it. @@ -403,7 +437,7 @@ my $dbh = $driver->rw_handle($obj->properties->{db}); $driver->start_query($sql, $obj->{column_values}); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); my $i = 1; my $col_defs = $obj->properties->{column_defs}; for my $col (@changed_cols) { @@ -419,7 +453,7 @@ } my $rows = $sth->execute; - $sth->finish; + _close_sth($sth); $driver->end_query($sth); $obj->call_trigger('post_save', $orig_obj); @@ -464,9 +498,9 @@ $sql .= $stmt->as_sql_where; my $dbh = $driver->rw_handle($obj->properties->{db}); $driver->start_query($sql, $stmt->{bind}); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); my $result = $sth->execute(@{ $stmt->{bind} }); - $sth->finish; + _close_sth($sth); $driver->end_query($sth); $obj->call_trigger('post_remove', $orig_obj); @@ -499,9 +533,9 @@ my $dbh = $driver->rw_handle($class->properties->{db}); $driver->start_query($sql, $stmt->{bind}); - my $sth = $dbh->prepare_cached($sql); + my $sth = $driver->_prepare_cached($dbh, $sql); my $result = $sth->execute(@{ $stmt->{bind} }); - $sth->finish; + _close_sth($sth); $driver->end_query($sth); return $result; } @@ -550,7 +584,7 @@ $dbh = $driver->rw_handle; $driver->dbh($dbh); } - + if ($dbh->{AutoCommit}) { eval { $dbh->begin_work; Index: extlib/Data/ObjectDriver/Driver/GearmanDBI.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/GearmanDBI.pm (revision 0) +++ extlib/Data/ObjectDriver/Driver/GearmanDBI.pm (revision 0) @@ -0,0 +1,126 @@ +package Data::ObjectDriver::Driver::GearmanDBI; +use strict; +use warnings; + +use base qw( Data::ObjectDriver ); +use Data::ObjectDriver::Iterator; +use Storable(); +use Digest::MD5; +use Data::Dumper; + +__PACKAGE__->mk_accessors(qw( + dbi client func driver_arg enabled_cb uniqify_cb + on_exception_cb retry_count timeout +)); + +sub init { + my $driver = shift; + my %param = @_; + + for my $key (keys %param) { + $driver->$key($param{$key}); + } +} + +sub search { + my $driver = shift; + my($class, $terms, $args) = @_; + + my $dbi = $driver->dbi; + + ## if Gearman shouldn't be used, fallback to the configured dbi driver + return $dbi->search(@_) + unless $driver->enabled_cb->(@_); + + my ($sql, $bind, $stmt) = $dbi->prepare_fetch($class, $terms, $args); + my $results = $driver->_gearman_search($sql, $bind); + + ## Transform the array returned by gearman to the hash we expect to load + ## in the object + my $map = $stmt->select_map; + my @select = @{ $stmt->select }; + + my $to_hash = sub { + my $array = shift; + my $hash; + my $i = 0; + for my $col (@select) { + $hash->{ $map->{$col} } = $array->[$i++]; + } + return $hash; + }; + + my $nt = $args->{no_triggers}; + my @objs = map { $dbi->load_object_from_rec($class, $_, $nt); } + map { $to_hash->($_) } + @$results; + + return wantarray + ? @objs + : Data::ObjectDriver::Iterator->new( sub { shift @objs } ); +} + +sub _gearman_search { + my $driver = shift; + my ($sql, $bind) = @_; + + my $uniqify = $driver->uniqify_cb || \&_md5sum; + my $func = $driver->func; + my $uniq = $uniqify->($sql, $bind); + my $client = $driver->client; + + my %options = (); + $options{on_exception} = $driver->on_exception_cb + if $driver->on_exception_cb; + $options{retry_count} = $driver->retry_count + if $driver->retry_count; + $options{timeout} = $driver->timeout + if $driver->timeout; + + my $res = $client->do_task( $func => + \Storable::nfreeze( { + driver_arg => $driver->driver_arg, + sql => $sql, + bind => $bind, + key => $uniq, + } ), + { + uniq => $uniq, # coalesce all requests for this data + %options, + } + ); + return $res ? Storable::thaw($$res) : []; +} + +sub _md5sum { + my ($sql, $bind) = @_; + return Digest::MD5::md5_hex(join "", $sql, @$bind); +} + +## every single data access methods are delegated to dbi +## except for search +sub lookup { shift->dbi->lookup (@_) } +sub lookup_multi { shift->dbi->lookup_multi (@_) } +sub exists { shift->dbi->exists (@_) } +sub insert { shift->dbi->insert (@_) } +sub replace { shift->dbi->replace (@_) } +sub update { shift->dbi->update (@_) } +sub remove { shift->dbi->remove (@_) } +sub fetch_data { shift->dbi->fetch_data (@_) } + +## transactions are passed to dbi +sub add_working_driver { shift->dbi->add_working_driver (@_) } +sub commit { shift->dbi->commit (@_) } +sub rollback { shift->dbi->rollback (@_) } +sub rw_handle { shift->dbi->rw_handle (@_) } +sub r_handle { shift->dbi->r_handle (@_) } + +## safety AUTOLOAD for the rest of non-core methods +sub DESTROY { } +sub AUTOLOAD { + my $driver = shift; + (my $meth = our $AUTOLOAD) =~ s/^.*:://; + return $driver->dbi->$meth(@_); +} + +1; Index: extlib/Data/ObjectDriver/Driver/SQL/Oracle.pm =================================================================== --- extlib/Data/ObjectDriver/Driver/SQL/Oracle.pm (revision 0) +++ extlib/Data/ObjectDriver/Driver/SQL/Oracle.pm (revision 0) @@ -0,0 +1,63 @@ +# $Id$ +# Contributor(s): Xiaoou Wu +# +package Data::ObjectDriver::SQL::Oracle; + +use strict; +use base qw(Data::ObjectDriver::SQL); + +## Oracle doesn't have the LIMIT clause. +sub as_limit { + return; +} + +## Override as_sql to emulate the LIMIT clause. +sub as_sql { + my $stmt = shift; + my $limit = $stmt->limit; + my $offset = $stmt->offset; + + if (defined $limit && defined $offset) { + my @fields = $stmt->select; + push @fields, "ROW_NUMBER() OVER (ORDER BY 1) R"; + } + + my $sql = $stmt->SUPER::as_sql(@_); + + if (defined $limit) { + $sql = "SELECT * FROM ( $sql ) WHERE "; + if (defined $offset) { + $sql = $sql . " R BETWEEN $offset + 1 AND $limit + $offset"; + } else { + $sql = $sql . " rownum <= $limit"; + } + } + return $sql; +} + +1; + +__END__ + +=head1 NAME + +Data::ObjectDriver::SQL::Oracle + +=head1 DESCRIPTION + +This module overrides methods of the Data::ObjectDriver::SQL module +with Oracle specific implementation. + +=head1 LICENSE + +This module is free software; +you may redistribute and/or modify it under the same +terms as Perl itself. + +=head1 AUTHOR & COPYRIGHT + +This module is +copyright (c) 2009 Xiaoou Wu Exiaoou.wu@oracle.comE. +All rights reserved. + +=cut Index: extlib/Data/ObjectDriver/ResultSet.pm =================================================================== --- extlib/Data/ObjectDriver/ResultSet.pm (revision 92) +++ extlib/Data/ObjectDriver/ResultSet.pm (working copy) @@ -7,6 +7,7 @@ use strict; use base qw( Class::Accessor::Fast ); +use List::Util qw(min); ## Public/_Private Accessors @@ -59,6 +60,8 @@ sub clone { my $self = shift; + # note that this is a SHALLOW copy--any values that are references + # will be shared between the original and the clone my $terms = $self->_terms ? { %{$self->_terms} } : {}; my $args = $self->_args ? { %{$self->_args} } : {}; @@ -264,7 +267,7 @@ # Do we already have results? if ($self->_results) { - return \@{ $self->_results }[$start..$end]; + return [ @{ $self->_results }[$start..min($self->count-1, $end)] ]; } my $limit = $end - $start + 1; @@ -277,10 +280,25 @@ return $r; } +sub all { + my $self = shift; + + return unless $self->count; + + my @obj; + push @obj, $self->first; + while (my $obj = $self->next) { + push @obj, $obj; + } + + $self->rewind; + return @obj; +} + sub count { my $self = shift; - # Get/load the results if we already have them or if we have a limit term + # Get/load the results if we already have them if ($self->_results_loaded or $self->get_limit) { my $results = $self->_load_results; return scalar @$results; @@ -789,8 +807,8 @@ ; Example while ($bottle = $res->next){ - - if ($bottle->type eq 'Bud Light' + + if ($bottle->type eq 'Bud Light' && $res->peek_next->type eq 'Chimay'){ $bottle->pass; #don't spoil my palate @@ -799,8 +817,8 @@ $bottle->drink; } } - + =head2 prev Retrieve the previous item in the result set @@ -918,7 +936,7 @@ =head2 dod_debug -Set this and you'll see $Data::ObjectDriver::DEBUG output when +Set this and you'll see $Data::ObjectDriver::DEBUG output when I go to get the results. =head2 rewind Index: extlib/Data/ObjectDriver/SQL.pm =================================================================== --- extlib/Data/ObjectDriver/SQL.pm (revision 92) +++ extlib/Data/ObjectDriver/SQL.pm (working copy) @@ -1,4 +1,4 @@ -# $Id: SQL.pm 494 2008-06-10 23:13:56Z bchoate $ +# $Id: SQL.pm 564 2009-02-05 00:27:19Z athomason $ package Data::ObjectDriver::SQL; use strict; @@ -71,23 +71,27 @@ $sql .= 'FROM '; ## Add any explicit JOIN statements before the non-joined tables. + my %joined; + my @from = @{ $stmt->from || [] }; if ($stmt->joins && @{ $stmt->joins }) { my $initial_table_written = 0; for my $j (@{ $stmt->joins }) { my($table, $joins) = map { $j->{$_} } qw( table joins ); $table = $stmt->_add_index_hint($table); ## index hint handling $sql .= $table unless $initial_table_written++; + $joined{$table}++; for my $join (@{ $j->{joins} }) { $sql .= ' ' . uc($join->{type}) . ' JOIN ' . $join->{table} . ' ON ' . $join->{condition}; } } - $sql .= ', ' if @{ $stmt->from }; + @from = grep { ! $joined{ $_ } } @from; + $sql .= ', ' if @from; } - if ($stmt->from && @{ $stmt->from }) { - $sql .= join ', ', map { $stmt->_add_index_hint($_) } @{ $stmt->from }; + if (@from) { + $sql .= join ', ', map { $stmt->_add_index_hint($_) } @from; } $sql .= "\n"; @@ -267,7 +271,7 @@ my $hint = $stmt->index_hint->{$tbl_name}; return $tbl_name unless $hint && ref($hint) eq 'HASH'; if ($hint->{list} && @{ $hint->{list} }) { - return $tbl_name . ' ' . uc($hint->{type} || 'USE') . ' INDEX (' . + return $tbl_name . ' ' . uc($hint->{type} || 'USE') . ' INDEX (' . join (',', @{ $hint->{list} }) . ')'; } @@ -295,7 +299,7 @@ my $sth = $dbh->prepare($sql->as_sql); $sth->execute(@{ $sql->{bind} }); my @values = $sth->selectrow_array(); - + my $obj = SomeObject->new(); $obj->set_columns(...); @@ -573,7 +577,7 @@ =head2 C<$sql-Eadd_index_hint($table, \@hints)> -Addes the index hint into a C query. The structure for the set of C<\@hints> are arrayref of hashrefs containing these members: =over 4 Index: lib/MT.pm =================================================================== --- lib/MT.pm (revision 92) +++ lib/MT.pm (working copy) @@ -29,10 +29,10 @@ BEGIN { $plugins_installed = 0; - ( $VERSION, $SCHEMA_VERSION ) = ( '4.25', '4.0070' ); + ( $VERSION, $SCHEMA_VERSION ) = ( '4.26', '4.0070' ); ( $PRODUCT_NAME, $PRODUCT_CODE, $PRODUCT_VERSION, $VERSION_ID ) = ( 'Movable Type', 'MT', - '4.25', '4.25-ru' + '4.26', '4.26-ru' ); $DebugMode = 0; @@ -518,7 +518,7 @@ if ( my $settings = $plugin->{registry}{config_settings} ) { $settings = $plugin->{registry}{config_settings} = $settings->() if ref($settings) eq 'CODE'; - $class->config->define($settings); + $class->config->define($settings) if $settings; } } push @Components, $plugin; @@ -801,16 +801,20 @@ my $mt = shift; my ($param) = @_; - my $cfg_file = $mt->find_config($param); - return $mt->error( -"Missing configuration file. Maybe you forgot to move mt-config.cgi-original to mt-config.cgi?" - ) unless $cfg_file; - $cfg_file = File::Spec->rel2abs($cfg_file); + unless ($mt->{cfg_file}) { + my $cfg_file = $mt->find_config($param); + + return $mt->error( + "Missing configuration file. Maybe you forgot to move mt-config.cgi-original to mt-config.cgi?" + ) unless $cfg_file; + $cfg_file = File::Spec->rel2abs($cfg_file); + $mt->{cfg_file} = $cfg_file; + } # translate the config file's location to an absolute path, so we # can use that directory as a basis for calculating other relative # paths found in the config file. - my $config_dir = $mt->{config_dir} = dirname($cfg_file); + my $config_dir = $mt->{config_dir} = dirname($mt->{cfg_file}); # store the mt_dir (home) as an absolute path; fallback to the config # directory if it isn't set. @@ -823,21 +827,22 @@ # also make note of the active application path; this is derived by # checking the PWD environment variable, the dirname of $0, # the directory of SCRIPT_FILENAME and lastly, falls back to mt_dir - $mt->{app_dir} = $ENV{PWD} || ""; - $mt->{app_dir} = dirname($0) - if !$mt->{app_dir} - || !File::Spec->file_name_is_absolute( $mt->{app_dir} ); - $mt->{app_dir} = dirname( $ENV{SCRIPT_FILENAME} ) - if $ENV{SCRIPT_FILENAME} - && ( !$mt->{app_dir} - || ( !File::Spec->file_name_is_absolute( $mt->{app_dir} ) ) ); - $mt->{app_dir} ||= $mt->{mt_dir}; - $mt->{app_dir} = File::Spec->rel2abs( $mt->{app_dir} ); + unless ($mt->{app_dir}) { + $mt->{app_dir} = $ENV{PWD} || ""; + $mt->{app_dir} = dirname($0) + if !$mt->{app_dir} + || !File::Spec->file_name_is_absolute( $mt->{app_dir} ); + $mt->{app_dir} = dirname( $ENV{SCRIPT_FILENAME} ) + if $ENV{SCRIPT_FILENAME} + && ( !$mt->{app_dir} + || ( !File::Spec->file_name_is_absolute( $mt->{app_dir} ) ) ); + $mt->{app_dir} ||= $mt->{mt_dir}; + $mt->{app_dir} = File::Spec->rel2abs( $mt->{app_dir} ); + } my $cfg = $mt->config; $cfg->define( $mt->registry('config_settings') ); - $cfg->read_config($cfg_file) or return $mt->error( $cfg->errstr ); - $mt->{cfg_file} = $cfg_file; + $cfg->read_config($mt->{cfg_file}) or return $mt->error( $cfg->errstr ); my @mt_paths = $cfg->paths; for my $meth (@mt_paths) { @@ -854,6 +859,7 @@ $cfg->$meth( \@paths ); } else { + next if ref($path); # unexpected referene, ignore if ( !File::Spec->file_name_is_absolute($path) ) { $path = File::Spec->catfile( $config_dir, $path ); $cfg->$meth($path); @@ -1027,11 +1033,18 @@ my $mt = shift; my ($param) = @_; my $cfg = $mt->config; - $cfg->read_config_db(); # Tell any instantiated drivers to reconfigure themselves as necessary - MT::ObjectDriverFactory->configure; + require MT::ObjectDriverFactory; + if (MT->config('ObjectDriver')) { + my $driver = MT::ObjectDriverFactory->instance; + $driver->configure if $driver; + } else { + MT::ObjectDriverFactory->configure(); + } + $cfg->read_config_db(); + 1; } @@ -1356,6 +1369,7 @@ $Plugins{$plugin_dir}{enabled} = 0; next; } + next if exists $Plugins{$plugin_dir}; my $id = lc $plugin_dir; $id =~ s/\.\w+$//; my $p = $pclass->new( @@ -1369,8 +1383,7 @@ # rebless? based on config? local $plugin_sig = $plugin_dir; MT->add_plugin($p); - $p->init_callbacks() - if $pclass eq 'MT::Plugin'; + $p->init_callbacks(); next; } @@ -2245,6 +2258,7 @@ my $max_size = exists $opt->{max_size} ? $opt->{max_size} : 100_000; my $timeout = exists $opt->{timeout} ? $opt->{timeout} : $cfg->HTTPTimeout || $cfg->PingTimeout; my $proxy = exists $opt->{proxy} ? $opt->{proxy} : $cfg->HTTPProxy || $cfg->PingProxy; + my $sec_proxy = exists $opt->{sec_proxy} ? $opt->{sec_proxy} : $cfg->HTTPSProxy; my $no_proxy = exists $opt->{no_proxy} ? $opt->{no_proxy} : $cfg->HTTPNoProxy || $cfg->PingNoProxy; my $agent = $opt->{agent} || 'MovableType/' . $MT::VERSION; my $interface = exists $opt->{interface} ? $opt->{interface} : $cfg->HTTPInterface || $cfg->PingInterface; @@ -2265,6 +2279,9 @@ my @domains = split( /,\s*/, $no_proxy ) if $no_proxy; $ua->no_proxy(@domains) if @domains; } + if ( defined $sec_proxy ) { + $ua->proxy ( https => $sec_proxy ); + } return $ua; } Index: lib/MT/App.pm =================================================================== --- lib/MT/App.pm (revision 92) +++ lib/MT/App.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: App.pm 3515 2009-03-09 07:36:07Z auno $ +# $Id: App.pm 3780 2009-06-02 23:10:15Z jmarcotte $ package MT::App; @@ -447,6 +447,8 @@ $param->{object_loop} = \@data; # handle pagination +$limit += 0; +$offset += 0; my $pager = { offset => $offset, limit => $limit, @@ -636,17 +638,13 @@ return Apache::Constants::OK(); } -sub new { - my $pkg = shift; - my $app = $pkg->SUPER::new(@_); - $app->{init_request} = 0; - $app; -} - sub init { my $app = shift; my %param = @_; $app->{apache} = $param{ApacheObject} if exists $param{ApacheObject}; + + # start tracing even prior to 'init' + local $SIG{__WARN__} = sub { $app->trace( $_[0] ) }; $app->SUPER::init(%param) or return; $app->{vtbl} = {}; $app->{is_admin} = 0; @@ -713,12 +711,6 @@ return if $app->{init_request}; if ($MT::DebugMode) { - if ( $MT::DebugMode & 4 ) { # SQL profile reporting is enabled - my $h = MT::Object->driver->r_handle; - if ( my $Profile = $h->{Profile} ) { # if DBI profiling is enabled - $Profile->{Data} = {}; # reset the profile data - } - } require Time::HiRes; $app->{start_request_time} = Time::HiRes::time(); } @@ -733,7 +725,7 @@ my @req_vars = qw(mode __path_info _blog redirect login_again no_print_body response_code response_content_type response_message author cgi_headers breadcrumbs goback cache_templates warning_trace - cookies _errstr request_method requires_login ); + cookies _errstr request_method requires_login __host ); delete $app->{$_} foreach @req_vars; $app->user(undef); if ( $ENV{MOD_PERL} ) { @@ -1115,7 +1107,7 @@ sub session_state { my $app = shift; my $blog = $app->blog; - my $blog_id = $blog->id if $blog; + my $blog_id = $blog ? $blog->id : 0; my ( $c, $commenter ); ( my $sessobj, $commenter ) = $app->get_commenter_session(); @@ -2533,6 +2525,7 @@ } local $param->{error} = $error; $tmpl->param($param); + $app->run_callbacks('template_param.error', $app, $tmpl->param, $tmpl); my $out = $tmpl->output; if ( !defined $out ) { $error = '
' . $error . '
' unless $error =~ m/
/;
@@ -2541,6 +2534,7 @@
             . encode_html( $tmpl->errstr )
             . "'. Giving up. Original error was: $error";
     }
+    $app->run_callbacks('template_output.error', $app, \$out, $tmpl->param, $tmpl);
     return $app->l10n_filter($out);
 }
 
@@ -2886,6 +2880,7 @@
 
 sub takedown {
     my $app = shift;
+    my $cfg = $app->config;
 
     MT->run_callbacks( ref($app) . '::take_down', $app )
         ;    # arg is the app object
@@ -2898,7 +2893,7 @@
     $app->user(undef);
     delete $app->{$_}
         for qw( cookies perms session trace response_content _blog
-        WeblogPublisher );
+        WeblogPublisher init_request );
 
     my $driver = $MT::Object::DRIVER;
     $driver->clear_cache if $driver && $driver->can('clear_cache');
@@ -2906,7 +2901,7 @@
     require MT::Auth;
     MT::Auth->release;
 
-    if ( $app->config->PerformanceLogging ) {
+    if ( $cfg->PerformanceLogging ) {
         $app->log_times();
     }
 
@@ -2914,18 +2909,20 @@
     if ( UNIVERSAL::isa( $app, 'MT::App::Upgrader' ) ) {
 
         # mt_config table doesn't exist during installation
-        if ( $driver->table_exists('MT::Config') ) {
-            $app->config->save_config();
+        if (my $cfg_pkg = $app->model('config')) {
+            my $driver = $cfg_pkg->driver;
+            if ( $driver->table_exists($cfg_pkg) ) {
+                $cfg->save_config();
+            }
         }
     }
     else {
-        $app->config->save_config();
+        $cfg->save_config();
     }
 
     $app->request->finish;
     delete $app->{request};
 
-    $app->{request_read_config} = 1;
 }
 
 sub l10n_filter { $_[0]->translate_templatized( $_[1] ) }
@@ -3594,12 +3591,16 @@
 sub trace {
     my $app = shift;
     $app->{trace} ||= [];
-    push @{ $app->{trace} }, "@_";
     if ( $MT::DebugMode & 2 ) {
         require Carp;
         local $Carp::CarpLevel = 1;
-        push @{ $app->{trace} }, Carp::longmess("Stack trace:");
+        my $msg = "@_";
+        chomp $msg;
+        push @{ $app->{trace} }, Carp::longmess($msg);
     }
+    else {
+        push @{ $app->{trace} }, "@_";
+    }
     if ( $MT::DebugMode & 128 ) {
         my @caller = caller(1);
         my $place
@@ -3608,10 +3609,13 @@
             . $caller[1]
             . ', line '
             . $caller[2];
-        print STDERR "(warn from $place) @_\n";
         if ( $MT::DebugMode & 2 ) {
             local $Carp::CarpLevel = 1;
-            print STDERR Carp::longmess("Stack trace:");
+            my $msg = "@_";
+            chomp $msg;
+            print STDERR Carp::longmess("(warn from $place) $msg");
+        } else {
+            print STDERR "(warn from $place) @_\n";
         }
     }
 }
Index: lib/MT/App/CMS.pm
===================================================================
--- lib/MT/App/CMS.pm	(revision 92)
+++ lib/MT/App/CMS.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: CMS.pm 3465 2009-02-27 07:18:17Z takayama $
+# $Id: CMS.pm 3697 2009-05-12 19:14:08Z jmarcotte $
 
 package MT::App::CMS;
 
@@ -61,10 +61,7 @@
         'list_template' => "${pkg}Template::list",
         'list_widget'   => "${pkg}Template::list_widget",
         'list_page'     => "${pkg}Page::list",
-        'list_comment'  => {
-            handler    => "${pkg}Comment::list",
-            permission => 'view_feedback',
-        },
+        'list_comment'  => "${pkg}Comment::list",
         'list_member'      => "${pkg}User::list_member",
         'list_user'        => "${pkg}User::list",
         'list_author'      => "${pkg}User::list",
@@ -240,10 +237,7 @@
         'list_pings'    => "${pkg}TrackBack::list",
         'list_entries'  => "${pkg}Entry::list",
         'list_pages'    => "${pkg}Page::list",
-        'list_comments' => {
-            handler    => "${pkg}Comment::list",
-            permission => 'view_feedback',
-        },
+        'list_comments' => "${pkg}Comment::list",
         'list_authors'      => "${pkg}User::list",
         'list_assets'       => "${pkg}Asset::list",
         'list_cat'          => "${pkg}Category::list",
@@ -1247,20 +1241,14 @@
                     my $perms
                         = $app->user->permissions( $app->param('blog_id') );
                     return 1
-                        if $perms->can_create_post
-                            || $perms->can_manage_feedback
-                            || $perms->can_edit_all_posts
-                            || $perms->can_comment;
+                        if $perms && $perms->can_view_feedback;
                 }
                 else {
                     require MT::Permission;
                     my @blogs
                         = map { $_->blog_id }
                         grep {
-                               $_->can_create_post
-                            || $_->can_manage_feedback
-                            || $_->can_edit_all_posts
-                            || $_->can_comment
+                            $_->can_view_feedback
                         } MT::Permission->load(
                         { author_id => $app->user->id } );
                     return 1 if @blogs;
Index: lib/MT/App/Comments.pm
===================================================================
--- lib/MT/App/Comments.pm	(revision 92)
+++ lib/MT/App/Comments.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Comments.pm 3494 2009-03-05 06:01:37Z takayama $
+# $Id: Comments.pm 3742 2009-05-26 15:13:38Z jmarcotte $
 
 package MT::App::Comments;
 use strict;
@@ -889,6 +889,8 @@
         $app->translate( "An error occurred: [_1]", $app->errstr() ) )
         unless $comment;
 
+    $app->run_callbacks( 'api_post_save.comment', $app, $comment, $commenter );
+    
     my $remember = $q->param('bakecookie') || 0;
     $remember = 0 if $remember eq 'Forget Info';    # another value for '0'
     if ( $commenter && $remember ) {
@@ -1656,6 +1658,7 @@
                 {   'body_class'                => 'mt-comment-pending',
                     'comment_response_template' => 1,
                     'comment_pending'           => 1,
+                    'return_to'                 => $entry->permalink || '',
                     'system_template'           => 1
                 }
             );
@@ -1667,6 +1670,7 @@
                 {   'body_class'                => 'mt-comment-error',
                     'comment_response_template' => 1,
                     'comment_error'             => 1,
+                    'return_to'                 => $app->param('return_url') || '',
                     'system_template'           => 1
                 }
             );
Index: lib/MT/App/Search.pm
===================================================================
--- lib/MT/App/Search.pm	(revision 92)
+++ lib/MT/App/Search.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Search.pm 3455 2009-02-23 02:29:31Z auno $
+# $Id: Search.pm 3696 2009-05-12 19:07:31Z jmarcotte $
 
 package MT::App::Search;
 
@@ -135,10 +135,13 @@
 
     my $processed = 0;
     my $list      = {};
+	if ( my $blog_id = $q->param('blog_id') ) {
+	    $q->param('IncludeBlogs', $blog_id);
+    }
     if ( $app->run_callbacks( 'search_blog_list', $app, $list, \$processed ) )
     {
         if ($processed) {
-            $app->{searchparam}{IncludeBlogs} = $list;
+            $app->{searchparam}{IncludeBlogs} = $list if ($list && %$list);
         }
         else {
             my $blog_list = $app->create_blog_list(%no_override);
@@ -147,15 +150,8 @@
                     && %$blog_list
                     && $blog_list->{IncludeBlogs}
                     && %{ $blog_list->{IncludeBlogs} };
-            if ( !exists( $app->{searchparam}{IncludeBlogs} )
-                && ( my $blog_id = $q->param('blog_id') ) )
-            {
-                $blog_id =~ s/\D//g;
-                $app->{searchparam}{IncludeBlogs}{$blog_id} = 1
-                    if $blog_id;
-            }
             return $app->error( $app->translate('Invalid request.') )
-                if !exists $app->{searchparam}{IncludeBlogs} || !%{$app->{searchparam}{IncludeBlogs}};
+                if ! $processed && ( !exists $app->{searchparam}{IncludeBlogs} || !%{$app->{searchparam}{IncludeBlogs}} );
         }
     }
     else {
@@ -251,7 +247,7 @@
     ## If IncludeBlogs has not been set, we need to build a list of
     ## the blogs to search. If ExcludeBlogs was set, exclude any blogs
     ## set in that list from our final list.
-    if ( %{$blog_list{ExcludeBlogs}} && !%{$blog_list{IncludeBlogs}} ) {
+    unless ( %{$blog_list{IncludeBlogs}} ) {
         my $exclude = $blog_list{ExcludeBlogs};
         my $iter    = $app->model('blog')->load_iter;
         while ( my $blog = $iter->() ) {
@@ -999,6 +995,7 @@
     if ( my $cache_driver = $app->{cache_driver} ) {
         $cache_driver->purge_stale( 2 * $app->config->SearchCacheTTL );
     }
+    delete $app->{searchparam};
     1;
 }
 
Index: lib/MT/App/Wizard.pm
===================================================================
--- lib/MT/App/Wizard.pm	(revision 92)
+++ lib/MT/App/Wizard.pm	(working copy)
@@ -84,6 +84,15 @@
         }
     }
 
+    # If mt-check.cgi exists, redirect to errro screen
+    my $cfg_exists = $app->is_config_exists();
+    if ($cfg_exists && lc $step ne 'seed' && lc $mode ne 'retry') {
+        my %param;
+        $param{cfg_exists} = 1;
+        $app->mode('pre_start');
+        return $app->build_page( "start.tmpl", \%param );
+    }
+
     $app->param( 'next_step', $new_step );
     $app->mode('run_step');
 }
@@ -335,15 +344,12 @@
     my %param;
 
     eval { use File::Spec; };
-    my ( $cfg, $cfg_exists, $static_file_path );
+    my ( $static_file_path );
     if ( !$@ ) {
-        $cfg = File::Spec->catfile( $app->{mt_dir}, 'mt-config.cgi' );
-        $cfg_exists |= 1 if -f $cfg;
-
         $static_file_path = File::Spec->catfile( $app->static_file_path );
     }
 
-    $param{cfg_exists}        = $cfg_exists;
+    $param{cfg_exists}        = $app->is_config_exists;
     $param{valid_static_path} = 1
         if $app->is_valid_static_path( $app->static_path );
     $param{mt_static_exists} = $app->mt_static_exists;
@@ -1095,6 +1101,19 @@
         and ( $response->content_length() != 0 )
         && ( $response->content =~ m/function\s+openManual/s );
 }
+
+sub is_config_exists {
+    my $app = shift;
+
+    eval { use File::Spec; };
+    my ( $cfg, $cfg_exists, $static_file_path );
+    if ( !$@ ) {
+        $cfg = File::Spec->catfile( $app->{mt_dir}, 'mt-config.cgi' );
+        $cfg_exists |= 1 if -f $cfg;
+    }
+    return $cfg_exists;
+}
+
 1;
 __END__
 
Index: lib/MT/Asset/Image.pm
===================================================================
--- lib/MT/Asset/Image.pm	(revision 92)
+++ lib/MT/Asset/Image.pm	(working copy)
@@ -53,6 +53,9 @@
 
     eval { require Image::Size; };
     return undef if $@;
+    if ( ! -e $asset->file_path || ! -r $asset->file_path ) {
+        return undef;
+    }
     my ( $w, $h, $id ) = Image::Size::imgsize($asset->file_path);
     $asset->meta('image_height', $h);
     if ($asset->id) {
@@ -68,6 +71,9 @@
 
     eval { require Image::Size; };
     return undef if $@;
+    if ( ! -e $asset->file_path || ! -r $asset->file_path ) {
+        return undef;
+    }
     my ( $w, $h, $id ) = Image::Size::imgsize($asset->file_path);
     $asset->meta('image_width', $w);
     if ($asset->id) {
Index: lib/MT/Author.pm
===================================================================
--- lib/MT/Author.pm	(revision 92)
+++ lib/MT/Author.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Author.pm 3504 2009-03-08 00:12:17Z fumiakiy $
+# $Id: Author.pm 3691 2009-05-12 18:06:46Z jmarcotte $
 
 package MT::Author;
 
@@ -108,15 +108,10 @@
 
 sub remove_sessions {
     my $auth = shift;
+    return if ( ! $auth or ! $auth->id );
     require MT::Session;
-    my $sess_iter = MT::Session->load_iter({ kind => 'US' });
-    my @sess;
-    while (my $sess = $sess_iter->()) {
-        my $id = $sess->get('author_id');
-        next unless $id == $auth->id;
-        push @sess, $sess;
-    }
-    $_->remove foreach @sess;
+    my $sess_iter = MT::Session->remove({ kind => 'US', name => $auth->id });
+    return 1;
 }
 
 sub set_password {
@@ -437,14 +432,13 @@
 
 sub entry_prefs {
     my $author = shift;
-    my @prefs = split /,/, ($author->column('entry_prefs') || '');
+    my @prefs = split /,/, ((@_ ? $_[0] : $author->column('entry_prefs')) || '');
     my %prefs;
     foreach (@prefs) {
         my ($name, $value) = split /=/, $_, 2;
         $prefs{$name} = $value;
     }
     if (@_) {
-        %prefs = (%prefs, @_);
         my $pref = '';
         foreach (keys %prefs) {
             $pref .= ',' if $pref ne '';
Index: lib/MT/BackupRestore.pm
===================================================================
--- lib/MT/BackupRestore.pm	(revision 92)
+++ lib/MT/BackupRestore.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: BackupRestore.pm 3455 2009-02-23 02:29:31Z auno $
+# $Id: BackupRestore.pm 3703 2009-05-12 20:26:18Z jmarcotte $
 
 package MT::BackupRestore;
 use strict;
@@ -92,6 +92,13 @@
         'ts_funcmap'    => {
             'skip' => 1
         },
+        # group and touch object should be skipped too; touch object creates issues with restore process (https://roundup.apperceptive.com/issues/issue11526)
+        'touch' => {
+            'skip' => 1
+        },
+        'group' => {
+            'skip' => 1
+        },
     };
 }
 
@@ -218,8 +225,11 @@
 sub backup {
     my $class = shift;
     my ($blog_ids, $printer, $splitter, $finisher, $progress, $size, $enc, $metadata) = @_;
-    push @$blog_ids, '0'
-        if defined($blog_ids) && scalar(@$blog_ids);
+
+	# removed global items from backup for blog-specific backups as this creates multiple copies of global items
+	# when multiple blogs from the same instance are restored one-by-one. ideally, this should be a user setting on the backup form
+	# push @$blog_ids, '0' if defined($blog_ids) && scalar(@$blog_ids);
+
     my $obj_to_backup = $class->_populate_obj_to_backup( $blog_ids );
 
     my $header .= "{skip} += 1;
                         }
                         else {
-                            $self->{callback}->("\n");
                             MT->log({ message => MT->translate(
                                 "User with the same name '[_1]' found (ID:[_2]).  Restore replaced this user with the data backed up.",
                                                   $obj->name, $obj->id),
Index: lib/MT/Blog.pm
===================================================================
--- lib/MT/Blog.pm	(revision 92)
+++ lib/MT/Blog.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Blog.pm 3455 2009-02-23 02:29:31Z auno $
+# $Id: Blog.pm 3803 2009-06-08 03:20:26Z fumiakiy $
 
 package MT::Blog;
 
@@ -576,7 +576,7 @@
 
     # Cloning blog
     my $new_blog = $blog->clone($params);
-    $new_blog->name(MT->translate($blog_name ? $blog_name : "Clone of [_1]", $blog->name));
+    $new_blog->name($blog_name ? $blog_name : MT->translate("Clone of [_1]", $blog->name));
     delete $new_blog->{column_values}->{id};
     delete $new_blog->{changed_cols}->{id};
     $new_blog->save or die $new_blog->errstr;
Index: lib/MT/Bootstrap.pm
===================================================================
--- lib/MT/Bootstrap.pm	(revision 92)
+++ lib/MT/Bootstrap.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Bootstrap.pm 3455 2009-02-23 02:29:31Z auno $
+# $Id: Bootstrap.pm 3829 2009-06-10 03:45:26Z takayama $
 
 package MT::Bootstrap;
 
@@ -34,6 +34,23 @@
         if $orig_dir && ($orig_dir ne $dir);
 }
 
+my $fcgi_exit_requested = 0;
+my $fcgi_handling_request = 0;
+
+sub fcgi_sig_handler {
+    my $sig = shift;
+    $fcgi_exit_requested = $sig;
+    if ($fcgi_handling_request) {
+        # With exit requested flag set, FastCGI loop will exit when it is done.
+        print STDERR "Movable Type: SIG$sig caught. Exiting gracefully after current request.\n";
+    }
+    else {
+        # Not currently handling a request, so just go ahead and exit.
+        print STDERR "Movable Type: SIG$sig caught. Exiting gracefully.\n";
+        exit(1);
+    }
+}
+
 sub import {
     my ($pkg, %param) = @_;
 
@@ -47,11 +64,11 @@
         my $not_fast_cgi = 0;
         $not_fast_cgi ||= exists $ENV{$_}
             for qw(HTTP_HOST GATEWAY_INTERFACE SCRIPT_FILENAME SCRIPT_URL);
-         my $fast_cgi = defined $param{FastCGI} ? $param{FastCGI} : (!$not_fast_cgi);
-         if ($fast_cgi) {
-             eval 'require CGI::Fast;';
-             $fast_cgi = 0 if $@;
-         }
+        my $fast_cgi = defined $param{FastCGI} ? $param{FastCGI} : (!$not_fast_cgi);
+        if ($fast_cgi) {
+            eval 'require CGI::Fast;';
+            $fast_cgi = 0 if $@;
+        }
 
         # ready to run now... run inside an eval block so we can gracefully
         # die if something bad happens
@@ -62,8 +79,21 @@
             eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $class; 1;" or die $@;
             if ($fast_cgi) {
                 $ENV{FAST_CGI} = 1;
+                # Signal handling needs FAIL_ACCEPT_ON_INTR set:
+                # "If set, Accept will fail if interrupted. It not set, it
+                # will just keep on waiting."
+                require FCGI;
+                $CGI::Fast::Ext_Request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%ENV, 0, FCGI::FAIL_ACCEPT_ON_INTR());
                 my ($max_requests, $max_time, $cfg);
-                while (my $cgi = new CGI::Fast) {
+                # catch SIGUSR1 and SIGTERM and allow request to finish before
+                # exiting.
+                # TODO: handle SIGPIPE more gracefully.
+                $SIG{USR1} = \&fcgi_sig_handler;
+                $SIG{TERM} = \&fcgi_sig_handler;
+                $SIG{PIPE} = 'IGNORE';
+                # we set the "handling request" flag so the signal handler can exit
+                # immediately when requests aren't being handled.
+                while ($fcgi_handling_request = (my $cgi = new CGI::Fast)) {
                     $app = $class->new( %param, CGIObject => $cgi )
                         or die $class->errstr;
 
@@ -80,13 +110,21 @@
                     MT->set_instance($app);
                     $app->init_request(CGIObject => $cgi);
                     $app->run;
+                    # force closing of connection here
+                    $CGI::Fast::Ext_Request->Finish();
 
+                    $fcgi_handling_request = 0;
+                    # Check for caught signal
+                    if ( $fcgi_exit_requested ) {
+                        print STDERR "Movable Type: FastCGI request loop exiting. Caught signal SIG$fcgi_exit_requested.\n";
+                        last;
+                    }
                     # Check for timeout for this process
-                    if ( $max_time && ( time - $app->{fcgi_startup_time} >= $max_time ) ) {
+                    elsif ( $max_time && ( time - $app->{fcgi_startup_time} >= $max_time ) ) {
                         last;
                     }
                     # Check for max executions for this process
-                    if ( $max_requests && ( $app->{fcgi_request_count} >= $max_requests ) ) {
+                    elsif ( $max_requests && ( $app->{fcgi_request_count} >= $max_requests ) ) {
                         last;
                     }
                 }
@@ -97,6 +135,31 @@
             }
         };
         if (my $err = $@) {
+            if (!$app && $err =~ m/Missing configuration file/) {
+                my $host = $ENV{SERVER_NAME} || $ENV{HTTP_HOST};
+                $host =~ s/:\d+//;
+                my $port = $ENV{SERVER_PORT};
+                my $uri = $ENV{REQUEST_URI} || $ENV{SCRIPT_NAME};
+                if ($uri =~ m/(\/mt\.(f?cgi|f?pl)(\?.*)?)$/) {
+                    my $script = $1;
+                    my $ext = $2;
+
+                    if (-f File::Spec->catfile($ENV{MT_HOME}, "mt-wizard.$ext")) {
+                        $uri =~ s/\Q$script\E//;
+                        $uri .= '/mt-wizard.' . $ext;
+
+                        my $prot = $port == 443 ? 'https' : 'http';
+                        my $cgipath = "$prot://$host";
+                        $cgipath .= ":$port"
+                            unless $port == 443 or $port == 80;
+                        $cgipath .= $uri;
+                        print "Status: 302 Moved\n";
+                        print "Location: " . $cgipath . "\n\n";
+                        exit;
+                    }
+                }
+            }
+
             my $charset = 'utf-8';
             eval {
                 # line __LINE__ __FILE__
@@ -127,31 +190,6 @@
                     exit;
                 };
                 $err = $@;
-            } else {
-                if ($err =~ m/Missing configuration file/) {
-                    my $host = $ENV{SERVER_NAME} || $ENV{HTTP_HOST};
-                    $host =~ s/:\d+//;
-                    my $port = $ENV{SERVER_PORT};
-                    my $uri = $ENV{REQUEST_URI} || $ENV{SCRIPT_NAME};
-                    if ($uri =~ m/(\/mt\.(f?cgi|f?pl)(\?.*)?)$/) {
-                        my $script = $1;
-                        my $ext = $2;
-
-                        if (-f File::Spec->catfile($ENV{MT_HOME}, "mt-wizard.$ext")) {
-                            $uri =~ s/\Q$script\E//;
-                            $uri .= '/mt-wizard.' . $ext;
-
-                            my $prot = $port == 443 ? 'https' : 'http';
-                            my $cgipath = "$prot://$host";
-                            $cgipath .= ":$port"
-                                unless $port == 443 or $port == 80;
-                            $cgipath .= $uri;
-                            print "Status: 302 Moved\n";
-                            print "Location: " . $cgipath . "\n\n";
-                            exit;
-                        }
-                    }
-                }
             }
             if (!$MT::DebugMode && ($err =~ m/^(.+?)( at .+? line \d+)(.*)$/s)) {
                 $err = $1;
Index: lib/MT/CMS/Blog.pm
===================================================================
--- lib/MT/CMS/Blog.pm	(revision 92)
+++ lib/MT/CMS/Blog.pm	(working copy)
@@ -1817,65 +1817,48 @@
             description => $blog->description,
             site_url    => $blog->site_url
         };
-
-        # we should use count by group here...
-        $row->{num_entries} =
-          ( $entry_count ? $entry_count->{$blog_id} : $entry_count->{$blog_id} =
-              MT::Entry->count( { blog_id => $blog_id } ) )
-          || 0;
-        $row->{num_comments} = (
-              $comment_count
-            ? $comment_count->{$blog_id}
-            : $comment_count->{$blog_id} = MT::Comment->count(
-                { blog_id => $blog_id, junk_status => MT::Comment::NOT_JUNK() }
-            )
-          )
-          || 0;
-        $row->{num_pings} = (
-            $ping_count ? $ping_count->{$blog_id} : $ping_count->{$blog_id} =
-              MT::TBPing->count(
-                { blog_id => $blog_id, junk_status => MT::TBPing::NOT_JUNK() }
-              )
-        ) || 0;
-        $row->{num_authors} = 0;
-
-        # FIXME: This isn't efficient
-        my $iter = MT::Permission->load_iter(
-            {
-                blog_id => [ 0, $blog_id ],
-
-                #    role_mask => [ 2, undef ]
-                #}, {
-                #    range_incl => { 'role_mask' => 1 }
-            }
-        );
-        my %a;
-        while ( my $p = $iter->() ) {
-            next if exists $a{ $p->author_id };
-            $a{ $p->author_id } = 1;
-            $row->{num_authors}++ if $p->can_create_post;
-        }
-        if ( $author->is_superuser ) {
-            $row->{can_create_post}       = 1;
-            $row->{can_edit_entries}      = 1;
-            $row->{can_edit_templates}    = 1;
-            $row->{can_edit_config}       = 1;
-            $row->{can_set_publish_paths} = 1;
-            $row->{can_administer_blog}   = 1;
-        }
-        else {
-            my $perms = $author->permissions($blog_id);
-            $row->{can_create_post}  = $perms->can_create_post;
-            $row->{can_edit_entries} = $perms->can_create_post
-              || $perms->can_edit_all_posts
-              || $perms->can_publish_post;
-            $row->{can_edit_templates} = $perms->can_edit_templates;
-            $row->{can_edit_config}    = $perms->can_edit_config
-              || $perms->can_administer_blog;
-            $row->{can_set_publish_paths} = $perms->can_set_publish_paths
-              || $perms->can_administer_blog;
-            $row->{can_administer_blog} = $perms->can_administer_blog;
-        }
+        if ($app->mode ne 'dialog_select_weblog') {
+			# we should use count by group here...
+			$row->{num_entries} =
+			  ( $entry_count ? $entry_count->{$blog_id} : $entry_count->{$blog_id} =
+				  MT::Entry->count( { blog_id => $blog_id } ) )
+			  || 0;
+			$row->{num_comments} = (
+				  $comment_count
+				? $comment_count->{$blog_id}
+				: $comment_count->{$blog_id} = MT::Comment->count(
+					{ blog_id => $blog_id, junk_status => MT::Comment::NOT_JUNK() }
+				)
+			  )
+			  || 0;
+			$row->{num_pings} = (
+				$ping_count ? $ping_count->{$blog_id} : $ping_count->{$blog_id} =
+				  MT::TBPing->count(
+					{ blog_id => $blog_id, junk_status => MT::TBPing::NOT_JUNK() }
+				  )
+			) || 0;
+			if ( $author->is_superuser ) {
+				$row->{can_create_post}       = 1;
+				$row->{can_edit_entries}      = 1;
+				$row->{can_edit_templates}    = 1;
+				$row->{can_edit_config}       = 1;
+				$row->{can_set_publish_paths} = 1;
+				$row->{can_administer_blog}   = 1;
+			}
+			else {
+				my $perms = $author->permissions($blog_id);
+				$row->{can_create_post}  = $perms->can_create_post;
+				$row->{can_edit_entries} = $perms->can_create_post
+				  || $perms->can_edit_all_posts
+				  || $perms->can_publish_post;
+				$row->{can_edit_templates} = $perms->can_edit_templates;
+				$row->{can_edit_config}    = $perms->can_edit_config
+				  || $perms->can_administer_blog;
+				$row->{can_set_publish_paths} = $perms->can_set_publish_paths
+				  || $perms->can_administer_blog;
+				$row->{can_administer_blog} = $perms->can_administer_blog;
+			}
+		}
         $row->{object} = $blog;
         push @data, $row;
     }
Index: lib/MT/CMS/Comment.pm
===================================================================
--- lib/MT/CMS/Comment.pm	(revision 92)
+++ lib/MT/CMS/Comment.pm	(working copy)
@@ -171,6 +171,23 @@
     my $user  = $app->user;
     my $admin = $user->is_superuser
       || ( $perms && $perms->can_administer_blog );
+
+    unless ($app->user->is_superuser) {
+        if ( $app->param('blog_id') ) {
+            return $app->errtrans("Permission denied.")
+                unless $perms && $perms->can_view_feedback;
+        } else {
+            require MT::Permission;
+            my @blogs
+                = map { $_->blog_id }
+                grep {
+                    $_->can_view_feedback
+                } MT::Permission->load(
+                { author_id => $app->user->id } );
+            return $app->errtrans("Permission denied.") unless @blogs;
+        }
+    }
+
     my $can_empty_junk = $admin
       || ( $perms && $perms->can_manage_feedback )
       ? 1 : 0;
Index: lib/MT/CMS/Dashboard.pm
===================================================================
--- lib/MT/CMS/Dashboard.pm	(revision 92)
+++ lib/MT/CMS/Dashboard.pm	(working copy)
@@ -124,6 +124,24 @@
         $param->{comment_count} = $count;
     }
 
+    require MT::Permission;
+    my @perm = MT::Permission->load(
+        { author_id => $app->user->id } );
+    my @blogs
+        = map { $_->blog_id }
+        grep {
+        $_->can_create_post
+            || $_->can_publish_post
+            || $_->can_edit_all_posts
+        } @perm;
+    $param->{can_list_entries} = @blogs ? 1: 0;
+    @blogs
+        = map { $_->blog_id }
+        grep {
+            $_->can_view_feedback
+        } @perm;
+    $param->{can_list_comments} = @blogs ? 1 : 0;
+
     my $last_post = MT::Entry->load(
         {
             author_id => $user->id,
@@ -140,6 +158,10 @@
         $param->{last_post_blog_id} = $last_post->blog_id;
         $param->{last_post_blog_name} = $last_post->blog->name;
         $param->{last_post_ts}      = $last_post->authored_on;
+        my $perms = MT::Permission->load( 
+            { blog_id => $last_post->blog_id, author_id => $app->user->id } );
+        $param->{last_post_can_edit}
+            = $perms && $perms->can_edit_entry($last_post, $app->user);
     }
 
     if (my ($url) = $user->userpic_url()) {
Index: lib/MT/CMS/Entry.pm
===================================================================
--- lib/MT/CMS/Entry.pm	(revision 92)
+++ lib/MT/CMS/Entry.pm	(working copy)
@@ -446,24 +446,42 @@
 
     my $q     = $app->param;
     my $perms = $app->permissions;
-    if ( $type eq 'page' ) {
-        if ( $perms
-            && ( !$perms->can_manage_pages ) )
-        {
-            return $app->errtrans("Permission denied.");
+    unless ($app->user->is_superuser) {
+        if ( $type eq 'page' ) {
+            if ( $app->param('blog_id') ) {
+                return $app->errtrans("Permission denied.")
+                    unless $perms && $perms->can_manage_pages;
+            } else {
+                require MT::Permission;
+                my @blogs
+                    = map { $_->blog_id }
+                    grep {
+                    $_->can_manage_pages
+                    } MT::Permission->load(
+                    { author_id => $app->user->id } );
+                return $app->errtrans("Permission denied.") unless @blogs;
+            }
+        } else {
+            if ( $app->param('blog_id') ) {
+                return $app->errtrans("Permission denied.")
+                    unless $perms && ( 
+                               $perms->can_create_post
+                            || $perms->can_publish_post
+                            || $perms->can_edit_all_posts );
+            } else {
+                require MT::Permission;
+                my @blogs
+                    = map { $_->blog_id }
+                    grep {
+                    $_->can_create_post
+                        || $_->can_publish_post
+                        || $_->can_edit_all_posts
+                    } MT::Permission->load(
+                    { author_id => $app->user->id } );
+                return $app->errtrans("Permission denied.") unless @blogs;
+            }
         }
     }
-    else {
-        if (
-            $perms
-            && (   !$perms->can_edit_all_posts
-                && !$perms->can_create_post
-                && !$perms->can_publish_post )
-          )
-        {
-            return $app->errtrans("Permission denied.");
-        }
-    }
 
     my $list_pref = $app->list_pref($type);
     my %param     = %$list_pref;
@@ -2136,10 +2154,21 @@
     my %rebuild_these;
     require MT::Entry;
 
+    my $app_author = $app->user;
+    my $perms      = $app->permissions;
+
     foreach my $id (@ids) {
         my $entry = MT::Entry->load($id)
           or return $app->errtrans(
             "One of the entries ([_1]) did not actually exist", $id );
+
+        return $app->error( $app->translate('Permission denied.') )
+            unless $app_author->is_superuser
+                || ( ( $entry->class eq 'entry' )
+                    && $perms && $perms->can_edit_entry( $entry, $app_author, 1 ) )
+                || ( ( $entry->class eq 'page' )
+                    && $perms && $perms->can_manage_pages );
+
         if ( $app->config('DeleteFilesAtRebuild')
             && ( MT::Entry::RELEASE() eq $entry->status ) )
         {
Index: lib/MT/CMS/Search.pm
===================================================================
--- lib/MT/CMS/Search.pm	(revision 92)
+++ lib/MT/CMS/Search.pm	(working copy)
@@ -159,7 +159,11 @@
             'can_search_by_date' => 1,
             'setup_terms_args'   => sub {
                 my ($terms, $args, $blog_id) = @_;
-                $terms->{class} = '*';
+                $terms->{class}
+                    = ( $app->param('filter') 
+                        && $app->param('filter_val')
+                        && $app->param('filter') eq 'class'
+                        && $app->param('filter_val') eq 'image' ) ? 'image' : '*';
                 $terms->{blog_id} = $blog_id if $blog_id;
             }
         },
@@ -196,7 +200,7 @@
                 return 1 if $author->is_superuser;
                 if ($blog_id) {
                     my $perm = $author->permissions($blog_id);
-                    return $perm->can_administer_blog;
+                    return $perm->can_administer_blog || $perm->can_manage_users;
                 }
                 return 0;
             },
@@ -383,6 +387,7 @@
     ## Sometimes we need to pass in the search columns like 'title,text', so
     ## we look for a comma (not a valid character in a column name) and split
     ## on it if it's there.
+    my $plain_search = $search;
     if ( ($search || '') ne '' ) {
         $search = quotemeta($search) unless $is_regex;
         $search = '(?i)' . $search   unless $case;
@@ -391,8 +396,15 @@
     my $api   = $search_api->{$type};
     my $class = $app->model($api->{object_type} || $type);
     my %param = %$list_pref;
-    my $limit = $q->param('limit') || 125;    # FIXME: mt.cfg setting?
-    $limit =~ s/\D//g if $limit ne 'all';
+    my $limit;
+    # type-specific directives override global CMSSearchLimit
+    my $directive = 'CMSSearchLimit' . ucfirst($type);
+	$limit = MT->config->$directive || MT->config->CMSSearchLimit || 125;
+	# don't allow passed limit to be higher than config limit
+	if ($q->param('limit') && ($q->param('limit') < $limit)) {
+		$limit = $q->param('limit');
+	}
+    $limit =~ s/\D//g;
     my $matches;
     $date_col = $api->{date_column} || 'created_on';
     if ( ( $do_search && $search ne '' ) || $show_all || $do_replace ) {
@@ -404,7 +416,7 @@
             if ($blog_id) {
                 my $perm = $author->permissions($blog_id);
                 return $app->errtrans('Permission denied.')
-                    unless $perm->can_administer_blog;
+                    unless $perm->can_administer_blog || $perm->can_manage_users;
             }
             $blog_id = 0;
         }
@@ -438,6 +450,22 @@
                   [ $datefrom . '000000', $dateto . '235959' ];
             }
         }
+        my @terms;
+        # MT::Object doesn't like multi-term hashes within arrays
+        if (%terms) {
+        	for my $key (keys %terms) {
+        		push(@terms, { $key => $terms{$key} });
+        	}
+        	push(@terms, '-and');
+        }
+        my @col_terms;
+        my $query_string = "%$plain_search%";
+        for my $col (@cols) {
+			push(@col_terms, { $col => { like => $query_string } }, '-or' );
+        }
+        delete $col_terms[$#col_terms];
+        push(@terms, \@col_terms);
+        $args{limit} = $limit + 1;
         my $iter;
         if ($do_replace) {
             $iter = sub {
@@ -450,13 +478,13 @@
               || ( $type eq 'blog' )
               || ( $app->mode eq 'dialog_grant_role' ) )
             {
-                $iter = $class->load_iter( \%terms, \%args ) or die $class->errstr;
+                $iter = $class->load_iter( \@terms, \%args ) or die $class->errstr;
             }
             else {
 
                 my @streams;
                 if ( $author->is_superuser ) {
-                    @streams = ( { iter => $class->load_iter( \%terms, \%args ) } );
+                    @streams = ( { iter => $class->load_iter( \@terms, \%args ) } );
                 } 
                 else {
                     # Get an iter for each accessible blog
@@ -466,12 +494,10 @@
                     );
                     if (@perms) {
                         @streams = map {
+                            $terms[0]{blog_id} = $_->blog_id;
                             {
                                 iter => $class->load_iter(
-                                    {
-                                        blog_id => $_->blog_id,
-                                        %terms
-                                    },
+                                    \@terms,
                                     \%args
                                 )
                             }
Index: lib/MT/CMS/Tools.pm
===================================================================
--- lib/MT/CMS/Tools.pm	(revision 92)
+++ lib/MT/CMS/Tools.pm	(working copy)
@@ -32,25 +32,26 @@
     $param{user_count} = $author_class->count(
         { type => MT::Author::AUTHOR() } );
 
-    # commeters: users with only comment permission and MT::Author::COMMENTER
-    my $cmntrs = $author_class->count(
-        { type => MT::Author::COMMENTER() } );
+    $param{commenter_count} = q[N/A];
+    $param{screen_id} = "system-check";
 
-    my @perms = $app->model('permission')->load(
-      {
-        permissions => "%'comment'%", 
-        blog_id     => '0',
-      },
-      {
-        'like' => { 'permissions' => 1 },
-        'not'  => { 'blog_id'     => 1 },
-      }
-    );
-    @perms = grep { $_->permissions =~ m/'comment'/ } @perms;
-    $param{commenter_count} = scalar(@perms) + $cmntrs;
-    $param{screen_id} = "system-check";
+    require MT::Memcached;
+    if (MT::Memcached->is_available) {
+        $param{memcached_enabled} = 1;
+        my $inst = MT::Memcached->instance;
+        my $key = 'syscheck-' . $$;
+        $inst->add($key, $$);
+        if ($inst->get($key) == $$) {
+            $inst->delete($key);
+            $param{memcached_active} = 1;
+        }
+    }
+
+    $param{server_modperl} = 1 if $ENV{MOD_PERL};
+    $param{server_fastcgi} = 1 if $ENV{FAST_CGI};
+
     $param{syscheck_html} = get_syscheck_content($app) || '';
-    
+
     $app->load_tmpl( 'system_check.tmpl', \%param );
 }
 
Index: lib/MT/Comment.pm
===================================================================
--- lib/MT/Comment.pm	(revision 92)
+++ lib/MT/Comment.pm	(working copy)
@@ -1,8 +1,8 @@
-# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
+# Movable Type (r) Open Source (C) 2001-2009 Six Apart, Ltd.
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Comment.pm 2642 2008-06-26 01:43:15Z auno $
+# $Id: Comment.pm 3730 2009-05-15 16:05:34Z jmarcotte $
 
 package MT::Comment;
 
@@ -25,25 +25,21 @@
         'email' => 'string(75)',
         'url' => 'string(255)',
         'text' => 'text',
-        'ip' => 'string(16)',
+        'ip' => 'string(50)',
         'last_moved_on' => 'datetime not null',
         'junk_score' => 'float',
         'junk_log' => 'text',
         'parent_id' => 'integer',
     },
     indexes => {
-        created_on => 1,
         entry_visible => {
             columns => [ 'entry_id', 'visible', 'created_on' ],
         },
+		author => 1,
         email => 1,
         commenter_id => 1,
-        parent_id => 1,
         last_moved_on => 1, # used for junk expiration
-        # For comment throttle check
-        blog_ip_date => {
-            columns => [ 'blog_id', 'ip', 'created_on' ],
-        },
+
         # For URL lookups to aid spam filtering
         blog_url => {
             columns => [ 'blog_id', 'visible', 'url' ],
@@ -54,12 +50,12 @@
         blog_visible => {
             columns => [ 'blog_id', 'visible', 'created_on', 'id' ],
         },
+		dd_coment_vis_mod => {
+			columns => [ 'visible', 'modified_on' ],
+		},
         visible_date => {
             columns => [ 'visible', 'created_on' ],
         },
-        junk_date => {
-            columns => [ 'junk_status', 'created_on' ],
-        },
     },
     meta => 1,
     defaults => {
Index: lib/MT/Component.pm
===================================================================
--- lib/MT/Component.pm	(revision 92)
+++ lib/MT/Component.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Component.pm 3455 2009-02-23 02:29:31Z auno $
+# $Id: Component.pm 3473 2009-02-27 20:23:25Z bchoate $
 
 package MT::Component;
 
@@ -50,9 +50,6 @@
 sub init {
     my $c = shift;
     $c->init_registry() or return;
-
-    # plugin callbacks are initialized after they finish loading.
-    $c->init_callbacks() unless $c->isa('MT::Plugin');
     $c;
 }
 
Index: lib/MT/ConfigMgr.pm
===================================================================
--- lib/MT/ConfigMgr.pm	(revision 92)
+++ lib/MT/ConfigMgr.pm	(working copy)
@@ -9,7 +9,7 @@
 use strict;
 use base qw( MT::ErrorHandler );
 
-use vars qw( $cfg );
+our $cfg;
 sub instance {
     return $cfg if $cfg;
     $cfg = __PACKAGE__->new;
@@ -242,9 +242,11 @@
             $data .= $mgr->{__settings}{$_}{key} . ' ' . $settings->{$_} . "\n";
         }
     }
-    require MT::Config;
-    my ($config) = MT::Config->load() || new MT::Config;
 
+    my $cfg_class = MT->model('config') or return;
+
+    my ($config) = $cfg_class->load() || $cfg_class->new;
+
     if ($data !~ m/schemaversion/i) {
         if ($config->id && (($config->data || '') =~ m/schemaversion/i)) {
             require Carp;
@@ -290,9 +292,11 @@
 sub read_config_db {
     my $class = shift;
     my $mgr = $class->instance;
-    require MT::Config;
-    my ($config) = eval { MT::Config->search };
+    my $cfg_class = MT->model('config') or return;
+
+    my ($config) = eval { $cfg_class->search };
     if ($config) {
+        my $was_dirty = $mgr->is_dirty;
         my $data = $config->data;
         my @data = split /[\r?\n]/, $data;
         my $line = 0;
@@ -305,6 +309,7 @@
             next unless $var && defined($val);
             $mgr->set($var, $val, 1);
         }
+        $mgr->clear_dirty unless $was_dirty;
     }
     $mgr->{__read_db} = 1;
     1;
Index: lib/MT/Core.pm
===================================================================
--- lib/MT/Core.pm	(revision 92)
+++ lib/MT/Core.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Core.pm 3459 2009-02-24 07:02:20Z auno $
+# $Id: Core.pm 3828 2009-06-10 02:28:14Z takayama $
 
 package MT::Core;
 
@@ -288,6 +288,9 @@
                 path    => 1,
             },
             'ObjectDriver'  => undef,
+            'ObjectCacheLimit' => { default => 1000 },
+            'ObjectCacheDisabled'  => undef,
+            'DisableObjectCache' => { default => 0, },
             'AllowedTextFilters' => undef,
             'Serializer'    => { default => 'MT', },
             'SendMailPath'  => { default => '/usr/lib/sendmail', },
@@ -814,12 +817,11 @@
     require MT::Session;
 
     my $expired = MT->config->UserSessionTimeout;
-    my @sesss = MT::Session->load(
-        { kind => 'US', start => [ undef, time - $expired ] },
+    MT::Session->remove(
+        { kind  => 'US',
+          start => [ undef, time - $expired ],
+          data  => { not_like => '%remember-%' } },
         { range => { start => 1 } } );
-    foreach my $s (@sesss) {
-        $s->remove if !$s->get('remember');
-    }
     return '';
 }
 
Index: lib/MT/Entry.pm
===================================================================
--- lib/MT/Entry.pm	(revision 92)
+++ lib/MT/Entry.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: Entry.pm 3512 2009-03-09 05:55:46Z asawada $
+# $Id: Entry.pm 3728 2009-05-15 15:59:31Z jmarcotte $
 
 package MT::Entry;
 
@@ -56,8 +56,12 @@
         author_id => 1,
         created_on => 1,
         modified_on => 1,
-        authored_on => 1,
         # For lookups 
+        comment_count => 1,
+		# TODO: Figure out how we benefit from this (from Percona-Advance recommendation)
+        auth_stat_class => {
+            columns => [ 'author_id', 'status', 'class' ],
+        },
         blog_basename => {
             columns => [ 'blog_id', 'basename' ],
         },
@@ -86,6 +90,11 @@
         blog_stat_date => {
             columns => ['blog_id', 'class', 'status', 'authored_on', 'id'],
         },
+		# TODO: Figure out how we benefit from this (from Percona-Advance recommendation)
+		# TODO: Figure out why this looks surprisingly like tag_count
+		dd_entry_tag_count => {
+			columns => ['blog_id', 'status', 'class', 'id'],
+		},
         # for tag count
         tag_count => {
             columns => ['status', 'class', 'blog_id', 'id'],
Index: lib/MT/L10N/de-iso-8859-1.pm
===================================================================
--- lib/MT/L10N/de-iso-8859-1.pm	(revision 92)
+++ lib/MT/L10N/de-iso-8859-1.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: de.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: de.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::de;
 use strict;
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'Erinnerungsfrage nicht gesetzt; neues Passwort kann deshalb nicht angefordert werden',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Ungltiger Versuch einer Passwortanforderung (verwendeter Erinnerungssatz: \'[_1]\'',
 	'User does not have email address' => 'Benutzer hat keine E-Mail-Adresse',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Link zum Zurcksetzen des Passworts fr Benutzer \'[_1]\' (#[_2]) an [_3] geschickt.', # Translate - New # OK
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Link zum Zurcksetzen des Passworts fr Benutzer \'[_1]\' (#[_2]) an [_3] geschickt.',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Einige Objekte wurden nicht wiederhergestellt, da ihre Elternobjekte ebenfalls nicht widerhergestellt wurden. Details finden Sie im Aktivittsprotokoll.',
 	'[_1] is not a directory.' => '[_1] ist kein Verzeichnis.',
 	'Error occured during restore process.' => 'Bei der Wiederherstellung ist ein Fehler aufgetreten.',
@@ -2109,7 +2109,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Um mit dem Konfigurationshelfer eine neue Konfigurationsdatei zu erzeugen, entfernen Sie die vorhandene Konfigurationsdatei und laden Sie diese Seite neu.',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type erfordert JavaScript. Bitte aktivieren Sie es in Ihren Browsereinstellungen und laden diese Seite dann neu.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Dieser Konfigurationshelfer hilft Ihnen, die zum Betrieb von Movable Type erforderlichen Grundeinstellungen vorzunehmen.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fehler: \'[_1]\' konnte nicht gefunden werden. Bitte kopieren Sie erst die statischen Dateien in den Ordner oder berprfen Sie, falls das bereits geschehen ist, die Einstellungen.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fehler: \'[_1]\' nicht gefunden. Bitte verschieben Sie die statischen Dateien erst in das Verzeichnis oder berprfen Sie die Einstellungen.', # Translate - New # OK
 	'Configure Static Web Path' => 'Statischen Web-Pfad konfigurieren',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type wird mit einem Verzeichnis namens [_1] ausgeliefert, das einige wichtige Bild-, JavaScript- und Stylesheet-Dateien enthlt.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'Der [_1]-Ordner befindet sich im Hauptverzeichnis von Movable Type, ist aufgrund der Serverkonfiguration vom Webserver aber nicht erreichbar. Verschieben Sie den Ordner [_1] daher an einen Ort, auf dem der Webserver zugreifen kann (z.B. Document Root).',
@@ -2734,7 +2734,7 @@
 	'Save display options' => 'Anzeigeoptionen speichern',
 	'OK' => 'OK',
 	'Close display options' => 'Anzeigeoptionen schlieen',
-	'This post was held for review, due to spam filtering.' => 'Dieser Eintrag wurde vom Spam-Filter zur Moderation zurckgehalten.', # Translate - New # OK
+	'This post was held for review, due to spam filtering.' => 'Dieser Eintrag wurde vom Spam-Filter zur Moderation zurckgehalten.',
 	'This post was classified as spam.' => 'Dieser Eintrag wurde als Spam erfasst.',
 	'Spam Details' => 'Spam-Details',
 	'Score' => 'Bewertung',
@@ -3234,6 +3234,7 @@
 	'Create widget template' => 'Widgetvorlage anlegen',
 	'Widget Template' => 'Widgetvorlage',
 	'Widget Templates' => 'Widgetvorlagen',
+	'widget templates' => 'Widgetvorlagen', # Translate - Case # OK
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => '[_1] zum Adressbuch hinzugefgt.',
@@ -3780,7 +3781,7 @@
 	'New Password' => 'Neues Passwort',
 	'Enter the new password.' => 'Neues Passwort eingeben',
 	'Password recovery word/phrase' => 'Erinnerungssatz',
-	'This word or phrase is not used in the password recovery.' => 'Dieser Ausdruck ist nicht Teil des Erinnerungssatzes', # Translate - New # OK
+	'This word or phrase is not used in the password recovery.' => 'Dieser Ausdruck ist nicht Teil des Erinnerungssatzes',
 	'Preferred language of this user.' => 'Bevorzugte Sprache des Benutzers',
 	'Text Format' => 'Textformatierung',
 	'Preferred text format option.' => 'Bevorzugte Formatierungsoption',
@@ -3848,9 +3849,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'Ihr letzter Eintrag war [_2] in [_4]',
+ 	'Your last entry was [_1] in [_3].' => 'Ihr letzter Eintrag war [_1] auf [_3].', # Translate - New # OK
 	'You have [quant,_2,draft,drafts].' => 'Sie haben [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Sie haben [quant,_2,Eintrag,Eintrge] mit [quant,_4,Kommentar,Kommentaren] geschrieben.',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Sie haben [quant,_1,Eintrag,Eintrge] mit [quant,_3,Kommentar,Kommentaren] geschrieben.', # Translate - New # OK
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Sie haben [quant,_1,Eintrag,Eintrge] mit [quant,_2,Kommentar,Kommentaren] geschrieben.', # Translate - New # OK
 	'You\'ve written [quant,_2,entry,entries].' => 'Sie haben [quant,_2,Eintrag,Eintrge] geschrieben.',
+	'You\'ve written [quant,_1,entry,entries].' => 'Sie haben [quant,_1,Eintrag,Eintrge] geschrieben.', # Translate - New # OK
 	'Edit your profile' => 'Profil bearbeiten',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3898,6 +3904,8 @@
 	'Total Users' => 'Benutzer insgesamt',
 	'Active Users' => 'Aktive Benutzer',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Benutzer, die sich innerhalb der letzten 90 Tage eingeloggt haben, gelten nach den Movable Type-Lizenzbedingungen als aktiv.',
+	'Memcache Status' => 'Memcache-Status', # Translate - New # OK
+	'Server Model' => 'Server-Modell', # Translate - New # OK
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type konnte die Datei \'mt-check.cgi\' nicht finden. Stellen Sie sicher, da die Datei vorhanden ist und MTCheckScript die richtigen Pfadangaben enthlt.',
 
 ## tmpl/cms/restore.tmpl
@@ -4062,8 +4070,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Community',
-	'Pending Entries' => 'Wartende Eintrge', # Translate - New # OK
-	'Spam Entries' => 'Spam-Eintrge', # Translate - New # OK
+	'Pending Entries' => 'Wartende Eintrge',
+	'Spam Entries' => 'Spam-Eintrge',
 	'Following Users' => 'Benutzern folgen',
 	'Being Followed' => 'Gefolgt werden',
 	'Sanitize' => 'Bereinigen',
@@ -4072,15 +4080,15 @@
 	'Most Popular Entries' => 'Beliebteste Eintrge',
 	'Registrations' => 'Registrierungen',
 	'Login Form' => 'Anmeldeformular',
-	'Password Reset Form' => 'Formular zum Zurcksetzen des Passworts', # Translate - Improved (3) # OK
+	'Password Reset Form' => 'Formular zum Zurcksetzen des Passworts',
 	'Registration Form' => 'Registrierungsformular',
 	'Registration Confirmation' => 'Registrierungsbesttigung',
 	'Profile Error' => 'Profilfehler',
 	'Profile View' => 'Profilansicht',
-	'Profile Edit Form' => 'Formular zur Profilbearbeitung', # Translate - Improved (3) # OK
-	'Profile Feed' => 'Profil-Feed', 
-	'New Password Form' => 'Formular zur Anforderung neuer Passwrter', # Translate - New # OK
-	'New Password Reset Form' => 'Formular zum Zurcksetzen neuer Passwrter', # Translate - New # OK
+	'Profile Edit Form' => 'Formular zur Profilbearbeitung',
+	'Profile Feed' => 'Profil-Feed',
+	'New Password Form' => 'Formular zur Anforderung neuer Passwrter',
+	'New Password Reset Form' => 'Formular zum Zurcksetzen neuer Passwrter',
 	'Form Field' => 'Formularfeld',
 	'Status Message' => 'Statusnachricht',
 	'Simple Header' => 'Einfache Kopfzeile',
@@ -4094,12 +4102,12 @@
 	'New entry notification' => 'Eintragsbenachrichtigung',
 	'Community Blog' => 'Community-Blog',
 	'Atom ' => 'Atom ',
-	'Entry Response' => 'Antwort auf Eintrag', # Translate - Improved (2) # OK
+	'Entry Response' => 'Antwort auf Eintrag',
 	'Displays error, pending or confirmation message when submitting an entry.' => 'Zeigt Besttigungs-, Moderations- und Fehlermeldungen zu neuen Beitrgen an.',
 	'Comment Detail' => 'Kommentardetails',
 	'Entry Detail' => 'Eintragsdetails',
 	'Entry Metadata' => 'Eintrags-Metadaten',
-	'Page Detail' => 'Seitendetails', # Translate - Improved (2) # OK
+	'Page Detail' => 'Seitendetails',
 	'Entry Form' => 'Eintragsformular',
 	'Content Navigation' => 'Inhaltsnavigation',
 	'Activity Widgets' => 'Aktivitten-Widgets',
@@ -4119,7 +4127,7 @@
 	'Your confirmation have expired. Please register again.' => 'Ihre Anmeldung ist abgelaufen. Bitte registrieren Sie sich erneut.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'Benutzer \'[_1]\' (ID:[_2]) erfolgreich registriert.',
 	'Thanks for the confirmation.  Please sign in.' => 'Danke fr die Besttigung. Bitte melden Sie sich an.',
-	'[_1] registered to Movable Type.' => '[_1] hat sich bei Movable Type registriert', # Translate - New # OK
+	'[_1] registered to Movable Type.' => '[_1] hat sich bei Movable Type registriert',
 	'Login required' => 'Anmeldung erforderlich',
 	'Title or Content is required.' => 'Titel oder Text erforderlich',
 	'System template entry_response not found in blog: [_1]' => 'Systemvorlage entry_response fr Blog [_1] nicht gefunden',
@@ -5291,7 +5299,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Ein Movable Type-Thema mit strukturierten Eintrgen und Action Streams.',
 	'Adjusting field types for embed custom fields...' => 'Passe Feldtypen fr eingebettete individuelle Felder an...',
 	'Updating favoriting namespace for Motion...' => 'Aktualisieren Favoriten-Namespace fr Motion...',
-	'Reinstall Motion Templates' => 'Motion-Vorlagen neu installieren',
 	'Motion Themes' => 'Motion-Designs',
 	'Themes for Motion template set' => 'Designs fr die Motion-Vorlagengruppe',
 	'Motion' => 'Motion',
@@ -5311,8 +5318,8 @@
 	'Profile Feed' => 'Profil-Feed',
 	'Login Form' => 'Anmeldeformular',
 	'Register Confirmation' => 'Registrierungs-Besttigung',
-	'Password Reset' => 'Passwort zurcksetzen',
-	'New Password Form' => 'Formular fr neues Passwort', # Translate - New # OK
+	'New Password Reset Form' => 'Formular zum Zurcksetzen neuer Passwrter',
+	'New Password Form' => 'Formular fr neues Passwort',
 	'User Profile' => 'Benutzerprofil',
 	'Actions (Local)' => 'Aktionen (lokal)',
 	'Comment Detail' => 'Kommentardetails',
@@ -5434,7 +5441,7 @@
 	'Remove service' => 'Dienst entfernen',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Anmelden', # Translate - New # OK
+	'Sign In' => 'Anmelden',
 	'Not a member? Register' => 'Noch kein Mitglied? Sign In)' => '(oder anmelden)',
 	'No posting privileges.' => 'Keine Verffentlichungs-Rechte.',
@@ -5452,7 +5459,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] kommentierte auf [_2]',
-	'[_1] favorited [_2]' => '[_1] hat [_2] zum Favoriten gemacht', # Translate - New # OK
+	'[_1] favorited [_2]' => '[_1] hat [_2] zum Favoriten gemacht',
 	'No recent actions.' => 'Keine aktuellen Aktionen',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5536,7 +5543,7 @@
 	'Profile Data' => 'Profil-Daten',
 	'More Entries by [_1]' => 'Weitere Eintrge von [_1]',
 	'Recent Actions' => 'Aktuelle Aktionen',
-	'_PROFILE_COMMENT_LENGTH' => '10', # Translate - New # OK
+	'_PROFILE_COMMENT_LENGTH' => '10',
 	'Comment Threads' => 'Kommentar-Threads',
 	'[_1] commented on ' => '[_1] kommentierte',
 	'No responses to comments.' => 'Keine Kommentarantworten',
@@ -5567,8 +5574,8 @@
 ## plugins/FacebookCommenters/tmpl/blog_config_template.tmpl
 	'Facebook Application Key' => 'Facebook Application Key',
 	'The key for the Facebook application associated with your blog.' => 'Der Application Key der mit Ihrem Blog verknpften Facebook-Anwendung',
-	'Edit Facebook App' => 'Facebook-Anwendung bearbeiten', # Translate - Improved (2) # OK
-	'Create Facebook App' => 'Facebook-Anwendung erstellen', # Translate - New # OK
+	'Edit Facebook App' => 'Facebook-Anwendung bearbeiten',
+	'Create Facebook App' => 'Facebook-Anwendung erstellen',
 	'Facebook Application Secret' => 'Facebook Application Secret',
 	'The secret for the Facebook application associated with your blog.' => 'Das Application Secret der mit Ihrem Blog verknpften Facebook-Anwendung',
 
@@ -5722,7 +5729,7 @@
 	'1up.com' => '1up.com',
 	'43Things' => '43Things',
 	'Screen name' => 'Bildschirmname',
-	'backtype' => 'backtype', # Translate - New # OK
+	'backtype' => 'backtype',
 	'Bebo' => 'Bebo',
 	'Catster' => 'Catster',
 	'COLOURlovers' => 'COLOURlovers',
@@ -5855,9 +5862,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] aktualisiert [_2]-Ereignisse fr [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Fehler bei der Aktualisierung der Ereignisse fr [_1]s [_2]-Stream (Typ [_3], Ident [_4]): [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Konnte Klasse [_1] fr Stream [_2] [_3] nicht laden: [_4]',
-	'No URL to fetch for [_1] results' => 'Keine URL zum Einlesen von [_1]-Ergebnissen', # Translate - New # OK
-	'Could not fetch [_1]: [_2]' => '[_1] konnte nicht einlesen gewerden: [_2]', # Translate - New # OK
-	'Aborted fetching [_1]: [_2]' => 'Einlesen von [_1] abgebrochen: [_2]', # Translate - New # OK
+	'No URL to fetch for [_1] results' => 'Keine URL zum Einlesen von [_1]-Ergebnissen',
+	'Could not fetch [_1]: [_2]' => '[_1] konnte nicht einlesen gewerden: [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Einlesen von [_1] abgebrochen: [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'Ihr Benutzername oder Ihre ID ist erforderlich.',
@@ -5888,7 +5895,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Profil bei einem Social Network oder Instant Messaging-Dienst hinzufgen',
 	'Select a service where you already have an account.' => 'Whlen Sie einen Dienst, bei dem Sie bereits ein Benutzerkonto haben.',
-	'Add Profile (s)' => 'Profil hinzufgen (s)', # Translate - New # OK
+	'Add Profile (s)' => 'Profil hinzufgen (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Die gewhlten Ereignisse wurden gelscht.',
@@ -5922,9 +5929,10 @@
 	'Rebuild Indexes' => 'Indizes neu aufbauen',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Falls aktiviert, werden die Indizes dieses Blogs neu aufgebaut, wenn neue Action Stream-Ereignisse eintreffen',
 	'Enable rebuilding' => 'Neuaufbau aktivieren',
+	'Clone of [_1]' => 'Klon von [_1]', # Translate - New
 
 );
 
-## New words: 96
+## New words: 110
 
 1;
Index: lib/MT/L10N/de.pm
===================================================================
--- lib/MT/L10N/de.pm	(revision 92)
+++ lib/MT/L10N/de.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: de.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: de.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::de;
 use strict;
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'Erinnerungsfrage nicht gesetzt; neues Passwort kann deshalb nicht angefordert werden',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Ungültiger Versuch einer Passwortanforderung (verwendeter Erinnerungssatz: \'[_1]\'',
 	'User does not have email address' => 'Benutzer hat keine E-Mail-Adresse',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Link zum Zurücksetzen des Passworts für Benutzer \'[_1]\' (#[_2]) an [_3] geschickt.', # Translate - New # OK
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Link zum Zurücksetzen des Passworts für Benutzer \'[_1]\' (#[_2]) an [_3] geschickt.',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Einige Objekte wurden nicht wiederhergestellt, da ihre Elternobjekte ebenfalls nicht widerhergestellt wurden. Details finden Sie im Aktivitätsprotokoll.',
 	'[_1] is not a directory.' => '[_1] ist kein Verzeichnis.',
 	'Error occured during restore process.' => 'Bei der Wiederherstellung ist ein Fehler aufgetreten.',
@@ -2109,7 +2109,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Um mit dem Konfigurationshelfer eine neue Konfigurationsdatei zu erzeugen, entfernen Sie die vorhandene Konfigurationsdatei und laden Sie diese Seite neu.',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type erfordert JavaScript. Bitte aktivieren Sie es in Ihren Browsereinstellungen und laden diese Seite dann neu.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Dieser Konfigurationshelfer hilft Ihnen, die zum Betrieb von Movable Type erforderlichen Grundeinstellungen vorzunehmen.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fehler: \'[_1]\' konnte nicht gefunden werden. Bitte kopieren Sie erst die statischen Dateien in den Ordner oder überprüfen Sie, falls das bereits geschehen ist, die Einstellungen.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fehler: \'[_1]\' nicht gefunden. Bitte verschieben Sie die statischen Dateien erst in das Verzeichnis oder überprüfen Sie die Einstellungen.', # Translate - New # OK
 	'Configure Static Web Path' => 'Statischen Web-Pfad konfigurieren',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type wird mit einem Verzeichnis namens [_1] ausgeliefert, das einige wichtige Bild-, JavaScript- und Stylesheet-Dateien enthält.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'Der [_1]-Ordner befindet sich im Hauptverzeichnis von Movable Type, ist aufgrund der Serverkonfiguration vom Webserver aber nicht erreichbar. Verschieben Sie den Ordner [_1] daher an einen Ort, auf dem der Webserver zugreifen kann (z.B. Document Root).',
@@ -2734,7 +2734,7 @@
 	'Save display options' => 'Anzeigeoptionen speichern',
 	'OK' => 'OK',
 	'Close display options' => 'Anzeigeoptionen schließen',
-	'This post was held for review, due to spam filtering.' => 'Dieser Eintrag wurde vom Spam-Filter zur Moderation zurückgehalten.', # Translate - New # OK
+	'This post was held for review, due to spam filtering.' => 'Dieser Eintrag wurde vom Spam-Filter zur Moderation zurückgehalten.',
 	'This post was classified as spam.' => 'Dieser Eintrag wurde als Spam erfasst.',
 	'Spam Details' => 'Spam-Details',
 	'Score' => 'Bewertung',
@@ -3234,6 +3234,7 @@
 	'Create widget template' => 'Widgetvorlage anlegen',
 	'Widget Template' => 'Widgetvorlage',
 	'Widget Templates' => 'Widgetvorlagen',
+	'widget templates' => 'Widgetvorlagen', # Translate - Case # OK
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => '[_1] zum Adressbuch hinzugefügt.',
@@ -3780,7 +3781,7 @@
 	'New Password' => 'Neues Passwort',
 	'Enter the new password.' => 'Neues Passwort eingeben',
 	'Password recovery word/phrase' => 'Erinnerungssatz',
-	'This word or phrase is not used in the password recovery.' => 'Dieser Ausdruck ist nicht Teil des Erinnerungssatzes', # Translate - New # OK
+	'This word or phrase is not used in the password recovery.' => 'Dieser Ausdruck ist nicht Teil des Erinnerungssatzes',
 	'Preferred language of this user.' => 'Bevorzugte Sprache des Benutzers',
 	'Text Format' => 'Textformatierung',
 	'Preferred text format option.' => 'Bevorzugte Formatierungsoption',
@@ -3848,9 +3849,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'Ihr letzter Eintrag war [_2] in [_4]',
+ 	'Your last entry was [_1] in [_3].' => 'Ihr letzter Eintrag war [_1] auf [_3].', # Translate - New # OK
 	'You have [quant,_2,draft,drafts].' => 'Sie haben [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Sie haben [quant,_2,Eintrag,Einträge] mit [quant,_4,Kommentar,Kommentaren] geschrieben.',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Sie haben [quant,_1,Eintrag,Einträge] mit [quant,_3,Kommentar,Kommentaren] geschrieben.', # Translate - New # OK
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Sie haben [quant,_1,Eintrag,Einträge] mit [quant,_2,Kommentar,Kommentaren] geschrieben.', # Translate - New # OK
 	'You\'ve written [quant,_2,entry,entries].' => 'Sie haben [quant,_2,Eintrag,Einträge] geschrieben.',
+	'You\'ve written [quant,_1,entry,entries].' => 'Sie haben [quant,_1,Eintrag,Einträge] geschrieben.', # Translate - New # OK
 	'Edit your profile' => 'Profil bearbeiten',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3898,6 +3904,8 @@
 	'Total Users' => 'Benutzer insgesamt',
 	'Active Users' => 'Aktive Benutzer',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Benutzer, die sich innerhalb der letzten 90 Tage eingeloggt haben, gelten nach den Movable Type-Lizenzbedingungen als aktiv.',
+	'Memcache Status' => 'Memcache-Status', # Translate - New # OK
+	'Server Model' => 'Server-Modell', # Translate - New # OK
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type konnte die Datei \'mt-check.cgi\' nicht finden. Stellen Sie sicher, daß die Datei vorhanden ist und MTCheckScript die richtigen Pfadangaben enthält.',
 
 ## tmpl/cms/restore.tmpl
@@ -4062,8 +4070,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Community',
-	'Pending Entries' => 'Wartende Einträge', # Translate - New # OK
-	'Spam Entries' => 'Spam-Einträge', # Translate - New # OK
+	'Pending Entries' => 'Wartende Einträge',
+	'Spam Entries' => 'Spam-Einträge',
 	'Following Users' => 'Benutzern folgen',
 	'Being Followed' => 'Gefolgt werden',
 	'Sanitize' => 'Bereinigen',
@@ -4072,15 +4080,15 @@
 	'Most Popular Entries' => 'Beliebteste Einträge',
 	'Registrations' => 'Registrierungen',
 	'Login Form' => 'Anmeldeformular',
-	'Password Reset Form' => 'Formular zum Zurücksetzen des Passworts', # Translate - Improved (3) # OK
+	'Password Reset Form' => 'Formular zum Zurücksetzen des Passworts',
 	'Registration Form' => 'Registrierungsformular',
 	'Registration Confirmation' => 'Registrierungsbestätigung',
 	'Profile Error' => 'Profilfehler',
 	'Profile View' => 'Profilansicht',
-	'Profile Edit Form' => 'Formular zur Profilbearbeitung', # Translate - Improved (3) # OK
-	'Profile Feed' => 'Profil-Feed', 
-	'New Password Form' => 'Formular zur Anforderung neuer Passwörter', # Translate - New # OK
-	'New Password Reset Form' => 'Formular zum Zurücksetzen neuer Passwörter', # Translate - New # OK
+	'Profile Edit Form' => 'Formular zur Profilbearbeitung',
+	'Profile Feed' => 'Profil-Feed',
+	'New Password Form' => 'Formular zur Anforderung neuer Passwörter',
+	'New Password Reset Form' => 'Formular zum Zurücksetzen neuer Passwörter',
 	'Form Field' => 'Formularfeld',
 	'Status Message' => 'Statusnachricht',
 	'Simple Header' => 'Einfache Kopfzeile',
@@ -4094,12 +4102,12 @@
 	'New entry notification' => 'Eintragsbenachrichtigung',
 	'Community Blog' => 'Community-Blog',
 	'Atom ' => 'Atom ',
-	'Entry Response' => 'Antwort auf Eintrag', # Translate - Improved (2) # OK
+	'Entry Response' => 'Antwort auf Eintrag',
 	'Displays error, pending or confirmation message when submitting an entry.' => 'Zeigt Bestätigungs-, Moderations- und Fehlermeldungen zu neuen Beiträgen an.',
 	'Comment Detail' => 'Kommentardetails',
 	'Entry Detail' => 'Eintragsdetails',
 	'Entry Metadata' => 'Eintrags-Metadaten',
-	'Page Detail' => 'Seitendetails', # Translate - Improved (2) # OK
+	'Page Detail' => 'Seitendetails',
 	'Entry Form' => 'Eintragsformular',
 	'Content Navigation' => 'Inhaltsnavigation',
 	'Activity Widgets' => 'Aktivitäten-Widgets',
@@ -4119,7 +4127,7 @@
 	'Your confirmation have expired. Please register again.' => 'Ihre Anmeldung ist abgelaufen. Bitte registrieren Sie sich erneut.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'Benutzer \'[_1]\' (ID:[_2]) erfolgreich registriert.',
 	'Thanks for the confirmation.  Please sign in.' => 'Danke für die Bestätigung. Bitte melden Sie sich an.',
-	'[_1] registered to Movable Type.' => '[_1] hat sich bei Movable Type registriert', # Translate - New # OK
+	'[_1] registered to Movable Type.' => '[_1] hat sich bei Movable Type registriert',
 	'Login required' => 'Anmeldung erforderlich',
 	'Title or Content is required.' => 'Titel oder Text erforderlich',
 	'System template entry_response not found in blog: [_1]' => 'Systemvorlage entry_response für Blog [_1] nicht gefunden',
@@ -5291,7 +5299,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Ein Movable Type-Thema mit strukturierten Einträgen und Action Streams.',
 	'Adjusting field types for embed custom fields...' => 'Passe Feldtypen für eingebettete individuelle Felder an...',
 	'Updating favoriting namespace for Motion...' => 'Aktualisieren Favoriten-Namespace für Motion...',
-	'Reinstall Motion Templates' => 'Motion-Vorlagen neu installieren',
 	'Motion Themes' => 'Motion-Designs',
 	'Themes for Motion template set' => 'Designs für die Motion-Vorlagengruppe',
 	'Motion' => 'Motion',
@@ -5311,8 +5318,8 @@
 	'Profile Feed' => 'Profil-Feed',
 	'Login Form' => 'Anmeldeformular',
 	'Register Confirmation' => 'Registrierungs-Bestätigung',
-	'Password Reset' => 'Passwort zurücksetzen',
-	'New Password Form' => 'Formular für neues Passwort', # Translate - New # OK
+	'New Password Reset Form' => 'Formular zum Zurücksetzen neuer Passwörter',
+	'New Password Form' => 'Formular für neues Passwort',
 	'User Profile' => 'Benutzerprofil',
 	'Actions (Local)' => 'Aktionen (lokal)',
 	'Comment Detail' => 'Kommentardetails',
@@ -5434,7 +5441,7 @@
 	'Remove service' => 'Dienst entfernen',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Anmelden', # Translate - New # OK
+	'Sign In' => 'Anmelden',
 	'Not a member? Register' => 'Noch kein Mitglied? Sign In)' => '(oder anmelden)',
 	'No posting privileges.' => 'Keine Veröffentlichungs-Rechte.',
@@ -5452,7 +5459,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] kommentierte auf [_2]',
-	'[_1] favorited [_2]' => '[_1] hat [_2] zum Favoriten gemacht', # Translate - New # OK
+	'[_1] favorited [_2]' => '[_1] hat [_2] zum Favoriten gemacht',
 	'No recent actions.' => 'Keine aktuellen Aktionen',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5536,7 +5543,7 @@
 	'Profile Data' => 'Profil-Daten',
 	'More Entries by [_1]' => 'Weitere Einträge von [_1]',
 	'Recent Actions' => 'Aktuelle Aktionen',
-	'_PROFILE_COMMENT_LENGTH' => '10', # Translate - New # OK
+	'_PROFILE_COMMENT_LENGTH' => '10',
 	'Comment Threads' => 'Kommentar-Threads',
 	'[_1] commented on ' => '[_1] kommentierte',
 	'No responses to comments.' => 'Keine Kommentarantworten',
@@ -5567,8 +5574,8 @@
 ## plugins/FacebookCommenters/tmpl/blog_config_template.tmpl
 	'Facebook Application Key' => 'Facebook Application Key',
 	'The key for the Facebook application associated with your blog.' => 'Der Application Key der mit Ihrem Blog verknüpften Facebook-Anwendung',
-	'Edit Facebook App' => 'Facebook-Anwendung bearbeiten', # Translate - Improved (2) # OK
-	'Create Facebook App' => 'Facebook-Anwendung erstellen', # Translate - New # OK
+	'Edit Facebook App' => 'Facebook-Anwendung bearbeiten',
+	'Create Facebook App' => 'Facebook-Anwendung erstellen',
 	'Facebook Application Secret' => 'Facebook Application Secret',
 	'The secret for the Facebook application associated with your blog.' => 'Das Application Secret der mit Ihrem Blog verknüpften Facebook-Anwendung',
 
@@ -5722,7 +5729,7 @@
 	'1up.com' => '1up.com',
 	'43Things' => '43Things',
 	'Screen name' => 'Bildschirmname',
-	'backtype' => 'backtype', # Translate - New # OK
+	'backtype' => 'backtype',
 	'Bebo' => 'Bebo',
 	'Catster' => 'Catster',
 	'COLOURlovers' => 'COLOURlovers',
@@ -5855,9 +5862,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] aktualisiert [_2]-Ereignisse für [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Fehler bei der Aktualisierung der Ereignisse für [_1]s [_2]-Stream (Typ [_3], Ident [_4]): [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Konnte Klasse [_1] für Stream [_2] [_3] nicht laden: [_4]',
-	'No URL to fetch for [_1] results' => 'Keine URL zum Einlesen von [_1]-Ergebnissen', # Translate - New # OK
-	'Could not fetch [_1]: [_2]' => '[_1] konnte nicht einlesen gewerden: [_2]', # Translate - New # OK
-	'Aborted fetching [_1]: [_2]' => 'Einlesen von [_1] abgebrochen: [_2]', # Translate - New # OK
+	'No URL to fetch for [_1] results' => 'Keine URL zum Einlesen von [_1]-Ergebnissen',
+	'Could not fetch [_1]: [_2]' => '[_1] konnte nicht einlesen gewerden: [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Einlesen von [_1] abgebrochen: [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'Ihr Benutzername oder Ihre ID ist erforderlich.',
@@ -5888,7 +5895,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Profil bei einem Social Network oder Instant Messaging-Dienst hinzufügen',
 	'Select a service where you already have an account.' => 'Wählen Sie einen Dienst, bei dem Sie bereits ein Benutzerkonto haben.',
-	'Add Profile (s)' => 'Profil hinzufügen (s)', # Translate - New # OK
+	'Add Profile (s)' => 'Profil hinzufügen (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Die gewählten Ereignisse wurden gelöscht.',
@@ -5922,9 +5929,10 @@
 	'Rebuild Indexes' => 'Indizes neu aufbauen',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Falls aktiviert, werden die Indizes dieses Blogs neu aufgebaut, wenn neue Action Stream-Ereignisse eintreffen',
 	'Enable rebuilding' => 'Neuaufbau aktivieren',
+	'Clone of [_1]' => 'Klon von [_1]', # Translate - New
 
 );
 
-## New words: 96
+## New words: 110
 
 1;
Index: lib/MT/L10N/en_us.pm
===================================================================
--- lib/MT/L10N/en_us.pm	(revision 92)
+++ lib/MT/L10N/en_us.pm	(working copy)
@@ -2,7 +2,7 @@
 # This program is distributed under the terms of the
 # GNU General Public License, version 2.
 #
-# $Id: en_us.pm 3465 2009-02-27 07:18:17Z takayama $
+# $Id: en_us.pm 3477 2009-02-27 21:01:48Z bchoate $
 
 package MT::L10N::en_us;   # American English
 
Index: lib/MT/L10N/es-iso-8859-1.pm
===================================================================
--- lib/MT/L10N/es-iso-8859-1.pm	(revision 92)
+++ lib/MT/L10N/es-iso-8859-1.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: es.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: es.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::es;
 use strict;
@@ -725,7 +725,7 @@
 	'Your request to change your password has expired.' => 'Expir su solicitud de cambio de contrasea.',
 	'Invalid password reset request' => 'Solicitud de reinicio de contrasea no vlida',
 	'Please confirm your new password' => 'Por favor, confirme su nueva contrasea',
-	'Passwords do not match' => 'Las contraseas no coinciden', # Translate - New
+	'Passwords do not match' => 'Las contraseas no coinciden',
 	'That action ([_1]) is apparently not implemented!' => 'La accin ([_1]) aparentemente no est implementada!',
 	'Invalid password recovery attempt; can\'t recover password in this configuration' => 'Intento de recuperacin de contrasea no vlido; no se pudo recuperar la clave con esta configuracin',
 	'Invalid author_id' => 'author_id no vlido',
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'El usuario no ha configurado una pista para la contrasea; no se pudo recuperar',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Intento invlido de recuperacin de la contrasea (pista usada \'[_1]\')',
 	'User does not have email address' => 'El usario sin direccin de correo electrnico',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Se ha envado el enlace del reinicio de la contrasea para el usuario \'[_1]\' a [_3] (usario #[_2]).', # Translate - New
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Se ha envado el enlace del reinicio de la contrasea para el usuario \'[_1]\' a [_3] (usario #[_2]).',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Algunos objetos no se restauraron porque sus objetos padres no se restauraron. Dispone de informacin detallada en el registro de actividad.',
 	'[_1] is not a directory.' => '[_1] no es un directorio.',
 	'Error occured during restore process.' => 'Ocurri un error durante el proceso de restauracin.',
@@ -1066,7 +1066,7 @@
 	'[_1]: [_2]' => '[_1]: [_2]',
 	'Moving metadata storage for categories...' => 'Migrando los metadatos de las categoras...',
 	'Upgrading metadata storage for [_1]' => 'Migrando los metadatos de [_1]',
-	'Updating password recover email template...' => 'Actualizando la plantilla del correo de recuperacin de contrasea...', # Translate - New
+	'Updating password recover email template...' => 'Actualizando la plantilla del correo de recuperacin de contrasea...',
 	'Migrating Nofollow plugin settings...' => 'Migrando ajustes de la extensin Nofollow...',
 	'Updating system search template records...' => 'Actualizando registros de las plantillas de bsqueda del sistema...',
 	'Custom ([_1])' => 'Personalizado ([_1])',
@@ -2111,7 +2111,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Para crear una nueva configuracin del archivo usando Wizard, borre la configuracin actual del archivo y actualice la pgina',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type necesita que JavaScript est disponible en el navegador. Por favor, active JavaScript y recargue esta pgina para continuar.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Este asistente le ayudar a configurar las opciones bsicas necesarias para ejecutar Movable Type.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Error: \'[_1]\' no ha sido encontrado. Por favor,mueva sus archivos estticos al primer directorio o corrija la configuracin si no es correcta.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Error: \'[_1]\' no se pudo encontrar.  Por favor, mueva los ficheros estticos al primer directorio o corrija la configuracin si no es correcta.', # Translate - New
 	'Configure Static Web Path' => 'Configurar ruta del web esttico',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type viene con un directorio nombrado [_1] el cual contiene un nmero de archivos importantes tales como imgenes, archivos javascript y hojas de estilo en cascadas.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'El directorio [_1] est en el directorio principal de Movable Type que recide en el script de instalacin, pero depende de la configuracin de su web server, el directorio [_1] no es accesible en este lugar y debe ser removido a un lugar de web accesible (e.g., su documento de raz del directorio web)',
@@ -2736,7 +2736,7 @@
 	'Save display options' => 'Guardar opciones de visualizacin',
 	'OK' => 'Aceptar',
 	'Close display options' => 'Cerrar opciones de visualizacin',
-	'This post was held for review, due to spam filtering.' => 'Esta entrada est retenida para su aprobacin, debido al filtro antispam.', # Translate - New
+	'This post was held for review, due to spam filtering.' => 'Esta entrada est retenida para su aprobacin, debido al filtro antispam.',
 	'This post was classified as spam.' => 'Esta entrada fue clasificada como spam.',
 	'Spam Details' => 'Detalles de spam',
 	'Score' => 'Puntuacin',
@@ -3236,6 +3236,7 @@
 	'Create widget template' => 'Crear plantilla de widget',
 	'Widget Template' => 'Plantilla de widget',
 	'Widget Templates' => 'Plantillas de widget',
+	'widget templates' => 'Plantillas de widget', # Translate - Case
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => 'Ha aadido [_1] a su agenda de direcciones.',
@@ -3782,7 +3783,7 @@
 	'New Password' => 'Nueva contrasea',
 	'Enter the new password.' => 'Introduzca la nueva contrasea.',
 	'Password recovery word/phrase' => 'Palabra/frase para la recuperacin de contrasea',
-	'This word or phrase is not used in the password recovery.' => 'Esta palabra o frase no se usa en la recuperacin de la contrasea.', # Translate - New
+	'This word or phrase is not used in the password recovery.' => 'Esta palabra o frase no se usa en la recuperacin de la contrasea.',
 	'Preferred language of this user.' => 'Idioma preferido por este usuario.',
 	'Text Format' => 'Formato de texto',
 	'Preferred text format option.' => 'Opcin de formato de texto preferido.',
@@ -3850,9 +3851,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'La ltima entrada estaba [_2] en [_4].',
+	'Your last entry was [_1] in [_3].' => 'Su ltima entrada fue [_1] en [_3].', # Translate - New
 	'You have [quant,_2,draft,drafts].' => 'Tiene [quant,_2,borrador,borradores].',
+	'You have [quant,_1,draft,drafts].' => 'Tiene [quant,_1,borrador,borradores].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Usted ha escrito [quant,_2,entrada,entradas] con [quant,_4,comentario,comentarios].',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Ha escrito [quant,_1,entrada,entradas] con [quant,_3,comentario,comentarios].', # Translate - New
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Ha escrito [quant,_1,entrada,entradas] con [quant,_2,comentario,comentarios].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries].' => 'Usted ha escrito [quant,_2,entrada,entradas].',
+	'You\'ve written [quant,_1,entry,entries].' => 'Ha escrito [quant,_1,entrada,entradas].', # Translate - New
 	'Edit your profile' => 'Edite su perfil',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3900,6 +3906,8 @@
 	'Total Users' => 'Usuarios Totales',
 	'Active Users' => 'Usuarios Activos',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Los usuarios que se hayan identificado a lo largo de los ltimos 90 das son considerados como activos segn la licence Movable Type.',
+	'Memcache Status' => 'Estado de memcache', # Translate - New
+	'Server Model' => 'Modelo de servidor', # Translate - New
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type no ha podido encontrar el script nombrado \'mt-check.cgi\'. Para resolver este problema, asegurese de que el script mt-check.cgi script existe y/o que la configuracin de los parmetros de MTCheckScript este correctamente referenciado.',
 
 ## tmpl/cms/restore.tmpl
@@ -4064,8 +4072,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Configuracin de la comunidad',
-	'Pending Entries' => 'Entradas pendientes', # Translate - New
-	'Spam Entries' => 'Entradas spam', # Translate - New
+	'Pending Entries' => 'Entradas pendientes',
+	'Spam Entries' => 'Entradas spam',
 	'Following Users' => 'Usuarios que sigue',
 	'Being Followed' => 'Seguidores',
 	'Sanitize' => 'Esterilizar',
@@ -4081,8 +4089,8 @@
 	'Profile View' => 'Ver perfil',
 	'Profile Edit Form' => 'Formulario de edicin del perfil',
 	'Profile Feed' => 'Sindicacin del perfil',
-	'New Password Form' => 'Formulario de nueva contrasea', # Translate - New
-	'New Password Reset Form' => 'Formulario de reinicio de contrasea', # Translate - New
+	'New Password Form' => 'Formulario de nueva contrasea',
+	'New Password Reset Form' => 'Formulario de reinicio de contrasea',
 	'Form Field' => 'Campo del formulario',
 	'Status Message' => 'Mensaje de estado',
 	'Simple Header' => 'Cabecera simple',
@@ -4121,7 +4129,7 @@
 	'Your confirmation have expired. Please register again.' => 'Su confirmacin ha caducado. Por favor, regstrese de nuevo.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'El usuario \'[_1]\' (ID:[_2]) se registr con xito.',
 	'Thanks for the confirmation.  Please sign in.' => 'Gracias por la confirmacin. Por favor, inicie la sesin.',
-	'[_1] registered to Movable Type.' => '[_1] se registr en Movable Type.', # Translate - New
+	'[_1] registered to Movable Type.' => '[_1] se registr en Movable Type.',
 	'Login required' => 'Requerido inicio de sesin',
 	'Title or Content is required.' => 'El ttulo o contenido es obligatorio.',
 	'System template entry_response not found in blog: [_1]' => 'La plantilla del sistema entry_response no se encontr en el blog: [_1]',
@@ -5290,7 +5298,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Tema de Movable Type con entradas estructuradas y torrentes de acciones.',
 	'Adjusting field types for embed custom fields...' => 'Ajustando los tipos de campos para campos personalizados embebidos...',
 	'Updating favoriting namespace for Motion...' => 'Actualizando el espacio de nombres de los favoritos para Motion...',
-	'Reinstall Motion Templates' => 'Reinstalar plantillas de Motion',
 	'Motion Themes' => 'Temas de Motion',
 	'Themes for Motion template set' => 'Temas para el conjunto de plantillas Motion',
 	'Motion' => 'Motion',
@@ -5310,8 +5317,8 @@
 	'Profile Feed' => 'Sindicacin del perfil',
 	'Login Form' => 'Formulario de inicio de sesin',
 	'Register Confirmation' => 'Confirmacin de registro',
-	'Password Reset' => 'Reiniciar contrasea',
-	'New Password Form' => 'Formulario de nueva contrasea', # Translate - New
+	'New Password Reset Form' => 'Formulario de reinicio de contrasea',
+	'New Password Form' => 'Formulario de nueva contrasea',
 	'User Profile' => 'Perfil del usuario',
 	'Actions (Local)' => 'Acciones (local)',
 	'Comment Detail' => 'Detalle del comentario',
@@ -5433,7 +5440,7 @@
 	'Remove service' => 'Eliminar servicio',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Identifquese', # Translate - New
+	'Sign In' => 'Identifquese',
 	'Not a member? Register' => 'No es miembro? Registrarse',
 	'(or Sign In)' => '(o identifquese)',
 	'No posting privileges.' => 'Sin privilegios de publicacin.',
@@ -5451,7 +5458,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] coment en [_2]',
-	'[_1] favorited [_2]' => '[_1] marc como favorito [_2]', # Translate - New
+	'[_1] favorited [_2]' => '[_1] marc como favorito [_2]',
 	'No recent actions.' => 'Ninguna accin reciente',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5567,7 +5574,7 @@
 	'Facebook Application Key' => 'Clave de la aplicacin de Facebook',
 	'The key for the Facebook application associated with your blog.' => 'La clave de la aplicacin de Facebook asociada con su blog.',
 	'Edit Facebook App' => 'Editar aplicacin de Facebook',
-	'Create Facebook App' => 'Crear aplicacin de Facebook', # Translate - New
+	'Create Facebook App' => 'Crear aplicacin de Facebook',
 	'Facebook Application Secret' => 'Secreto de la aplicacin de Facebook',
 	'The secret for the Facebook application associated with your blog.' => 'El secreto de la aplicacin de Facebook asociada con su blog.',
 
@@ -5854,9 +5861,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] actualizando [_2] eventos para [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Error actualizando eventos para el torrente [_2] de [_1] (tipo [_3] ident [_4]): [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'No se pudo cargar la clase [_1] del torrente [_2] [_3]: [_4]',
-	'No URL to fetch for [_1] results' => 'Sin URL para obtener resultados de [_1]', # Translate - New
-	'Could not fetch [_1]: [_2]' => 'No se pudo obtener [_1]: [_2]', # Translate - New
-	'Aborted fetching [_1]: [_2]' => 'Se abort durante la obtencin de [_1]: [_2]', # Translate - New
+	'No URL to fetch for [_1] results' => 'Sin URL para obtener resultados de [_1]',
+	'Could not fetch [_1]: [_2]' => 'No se pudo obtener [_1]: [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Se abort durante la obtencin de [_1]: [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'El usuario o el ID es obligatorio.',
@@ -5887,7 +5894,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Aadir un perfil de una red social o servicio de mensajera instantnea.',
 	'Select a service where you already have an account.' => 'Seleccione un servicio donde ya tenga una cuenta.',
-	'Add Profile (s)' => 'Aadir perfil (s)', # Translate - New
+	'Add Profile (s)' => 'Aadir perfil (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Se borraron los eventos seleccionados.',
@@ -5921,9 +5928,10 @@
 	'Rebuild Indexes' => 'Reconstruir ndices',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Si se selecciona, los ndices de este blog se reconstruirn al descubrir nuevos eventos de los torrentes de acciones.',
 	'Enable rebuilding' => 'Activar reconstruccin',
+	'Clone of [_1]' => 'Clon de [_1]', # Translate - New
 
 );
 
-## New words: 100
+## New words: 110
 
 1;
Index: lib/MT/L10N/es.pm
===================================================================
--- lib/MT/L10N/es.pm	(revision 92)
+++ lib/MT/L10N/es.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: es.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: es.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::es;
 use strict;
@@ -725,7 +725,7 @@
 	'Your request to change your password has expired.' => 'Expiró su solicitud de cambio de contraseña.',
 	'Invalid password reset request' => 'Solicitud de reinicio de contraseña no válida',
 	'Please confirm your new password' => 'Por favor, confirme su nueva contraseña',
-	'Passwords do not match' => 'Las contraseñas no coinciden', # Translate - New
+	'Passwords do not match' => 'Las contraseñas no coinciden',
 	'That action ([_1]) is apparently not implemented!' => '¡La acción ([_1]) aparentemente no está implementada!',
 	'Invalid password recovery attempt; can\'t recover password in this configuration' => 'Intento de recuperación de contraseña no válido; no se pudo recuperar la clave con esta configuración',
 	'Invalid author_id' => 'author_id no válido',
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'El usuario no ha configurado una pista para la contraseña; no se pudo recuperar',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Intento inválido de recuperación de la contraseña (pista usada \'[_1]\')',
 	'User does not have email address' => 'El usario sin dirección de correo electrónico',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Se ha envíado el enlace del reinicio de la contraseña para el usuario \'[_1]\' a [_3] (usario #[_2]).', # Translate - New
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Se ha envíado el enlace del reinicio de la contraseña para el usuario \'[_1]\' a [_3] (usario #[_2]).',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Algunos objetos no se restauraron porque sus objetos padres no se restauraron. Dispone de información detallada en el registro de actividad.',
 	'[_1] is not a directory.' => '[_1] no es un directorio.',
 	'Error occured during restore process.' => 'Ocurrió un error durante el proceso de restauración.',
@@ -1066,7 +1066,7 @@
 	'[_1]: [_2]' => '[_1]: [_2]',
 	'Moving metadata storage for categories...' => 'Migrando los metadatos de las categorías...',
 	'Upgrading metadata storage for [_1]' => 'Migrando los metadatos de [_1]',
-	'Updating password recover email template...' => 'Actualizando la plantilla del correo de recuperación de contraseña...', # Translate - New
+	'Updating password recover email template...' => 'Actualizando la plantilla del correo de recuperación de contraseña...',
 	'Migrating Nofollow plugin settings...' => 'Migrando ajustes de la extensión Nofollow...',
 	'Updating system search template records...' => 'Actualizando registros de las plantillas de búsqueda del sistema...',
 	'Custom ([_1])' => 'Personalizado ([_1])',
@@ -2111,7 +2111,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Para crear una nueva configuración del archivo usando Wizard, borre la configuración actual del archivo y actualice la página',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type necesita que JavaScript esté disponible en el navegador. Por favor, active JavaScript y recargue esta página para continuar.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Este asistente le ayudará a configurar las opciones básicas necesarias para ejecutar Movable Type.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Error: \'[_1]\' no ha sido encontrado. Por favor,mueva sus archivos estáticos al primer directorio o corrija la configuración si no es correcta.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Error: \'[_1]\' no se pudo encontrar.  Por favor, mueva los ficheros estáticos al primer directorio o corrija la configuración si no es correcta.', # Translate - New
 	'Configure Static Web Path' => 'Configurar ruta del web estático',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type viene con un directorio nombrado [_1] el cual contiene un número de archivos importantes tales como imágenes, archivos javascript y hojas de estilo en cascadas.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'El directorio [_1] está en el directorio principal de Movable Type que recide en el script de instalación, pero depende de la configuración de su web server, el directorio [_1] no es accesible en este lugar y debe ser removido a un lugar de web accesible (e.g., su documento de raíz del directorio web)',
@@ -2736,7 +2736,7 @@
 	'Save display options' => 'Guardar opciones de visualización',
 	'OK' => 'Aceptar',
 	'Close display options' => 'Cerrar opciones de visualización',
-	'This post was held for review, due to spam filtering.' => 'Esta entrada está retenida para su aprobación, debido al filtro antispam.', # Translate - New
+	'This post was held for review, due to spam filtering.' => 'Esta entrada está retenida para su aprobación, debido al filtro antispam.',
 	'This post was classified as spam.' => 'Esta entrada fue clasificada como spam.',
 	'Spam Details' => 'Detalles de spam',
 	'Score' => 'Puntuación',
@@ -3236,6 +3236,7 @@
 	'Create widget template' => 'Crear plantilla de widget',
 	'Widget Template' => 'Plantilla de widget',
 	'Widget Templates' => 'Plantillas de widget',
+	'widget templates' => 'Plantillas de widget', # Translate - Case
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => 'Ha añadido [_1] a su agenda de direcciones.',
@@ -3782,7 +3783,7 @@
 	'New Password' => 'Nueva contraseña',
 	'Enter the new password.' => 'Introduzca la nueva contraseña.',
 	'Password recovery word/phrase' => 'Palabra/frase para la recuperación de contraseña',
-	'This word or phrase is not used in the password recovery.' => 'Esta palabra o frase no se usa en la recuperación de la contraseña.', # Translate - New
+	'This word or phrase is not used in the password recovery.' => 'Esta palabra o frase no se usa en la recuperación de la contraseña.',
 	'Preferred language of this user.' => 'Idioma preferido por este usuario.',
 	'Text Format' => 'Formato de texto',
 	'Preferred text format option.' => 'Opción de formato de texto preferido.',
@@ -3850,9 +3851,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'La última entrada estaba [_2] en [_4].',
+	'Your last entry was [_1] in [_3].' => 'Su última entrada fue [_1] en [_3].', # Translate - New
 	'You have [quant,_2,draft,drafts].' => 'Tiene [quant,_2,borrador,borradores].',
+	'You have [quant,_1,draft,drafts].' => 'Tiene [quant,_1,borrador,borradores].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Usted ha escrito [quant,_2,entrada,entradas] con [quant,_4,comentario,comentarios].',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Ha escrito [quant,_1,entrada,entradas] con [quant,_3,comentario,comentarios].', # Translate - New
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Ha escrito [quant,_1,entrada,entradas] con [quant,_2,comentario,comentarios].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries].' => 'Usted ha escrito [quant,_2,entrada,entradas].',
+	'You\'ve written [quant,_1,entry,entries].' => 'Ha escrito [quant,_1,entrada,entradas].', # Translate - New
 	'Edit your profile' => 'Edite su perfil',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3900,6 +3906,8 @@
 	'Total Users' => 'Usuarios Totales',
 	'Active Users' => 'Usuarios Activos',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Los usuarios que se hayan identificado a lo largo de los últimos 90 días son considerados como activos según la licence Movable Type.',
+	'Memcache Status' => 'Estado de memcache', # Translate - New
+	'Server Model' => 'Modelo de servidor', # Translate - New
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type no ha podido encontrar el script nombrado \'mt-check.cgi\'. Para resolver este problema, asegurese de que el script mt-check.cgi script existe y/o que la configuración de los parámetros de MTCheckScript este correctamente referenciado.',
 
 ## tmpl/cms/restore.tmpl
@@ -4064,8 +4072,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Configuración de la comunidad',
-	'Pending Entries' => 'Entradas pendientes', # Translate - New
-	'Spam Entries' => 'Entradas spam', # Translate - New
+	'Pending Entries' => 'Entradas pendientes',
+	'Spam Entries' => 'Entradas spam',
 	'Following Users' => 'Usuarios que sigue',
 	'Being Followed' => 'Seguidores',
 	'Sanitize' => 'Esterilizar',
@@ -4081,8 +4089,8 @@
 	'Profile View' => 'Ver perfil',
 	'Profile Edit Form' => 'Formulario de edición del perfil',
 	'Profile Feed' => 'Sindicación del perfil',
-	'New Password Form' => 'Formulario de nueva contraseña', # Translate - New
-	'New Password Reset Form' => 'Formulario de reinicio de contraseña', # Translate - New
+	'New Password Form' => 'Formulario de nueva contraseña',
+	'New Password Reset Form' => 'Formulario de reinicio de contraseña',
 	'Form Field' => 'Campo del formulario',
 	'Status Message' => 'Mensaje de estado',
 	'Simple Header' => 'Cabecera simple',
@@ -4121,7 +4129,7 @@
 	'Your confirmation have expired. Please register again.' => 'Su confirmación ha caducado. Por favor, regístrese de nuevo.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'El usuario \'[_1]\' (ID:[_2]) se registró con éxito.',
 	'Thanks for the confirmation.  Please sign in.' => 'Gracias por la confirmación. Por favor, inicie la sesión.',
-	'[_1] registered to Movable Type.' => '[_1] se registró en Movable Type.', # Translate - New
+	'[_1] registered to Movable Type.' => '[_1] se registró en Movable Type.',
 	'Login required' => 'Requerido inicio de sesión',
 	'Title or Content is required.' => 'El título o contenido es obligatorio.',
 	'System template entry_response not found in blog: [_1]' => 'La plantilla del sistema entry_response no se encontró en el blog: [_1]',
@@ -5290,7 +5298,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Tema de Movable Type con entradas estructuradas y torrentes de acciones.',
 	'Adjusting field types for embed custom fields...' => 'Ajustando los tipos de campos para campos personalizados embebidos...',
 	'Updating favoriting namespace for Motion...' => 'Actualizando el espacio de nombres de los favoritos para Motion...',
-	'Reinstall Motion Templates' => 'Reinstalar plantillas de Motion',
 	'Motion Themes' => 'Temas de Motion',
 	'Themes for Motion template set' => 'Temas para el conjunto de plantillas Motion',
 	'Motion' => 'Motion',
@@ -5310,8 +5317,8 @@
 	'Profile Feed' => 'Sindicación del perfil',
 	'Login Form' => 'Formulario de inicio de sesión',
 	'Register Confirmation' => 'Confirmación de registro',
-	'Password Reset' => 'Reiniciar contraseña',
-	'New Password Form' => 'Formulario de nueva contraseña', # Translate - New
+	'New Password Reset Form' => 'Formulario de reinicio de contraseña',
+	'New Password Form' => 'Formulario de nueva contraseña',
 	'User Profile' => 'Perfil del usuario',
 	'Actions (Local)' => 'Acciones (local)',
 	'Comment Detail' => 'Detalle del comentario',
@@ -5433,7 +5440,7 @@
 	'Remove service' => 'Eliminar servicio',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Identifíquese', # Translate - New
+	'Sign In' => 'Identifíquese',
 	'Not a member? Register' => '¿No es miembro? Registrarse',
 	'(or Sign In)' => '(o identifíquese)',
 	'No posting privileges.' => 'Sin privilegios de publicación.',
@@ -5451,7 +5458,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] comentó en [_2]',
-	'[_1] favorited [_2]' => '[_1] marcó como favorito [_2]', # Translate - New
+	'[_1] favorited [_2]' => '[_1] marcó como favorito [_2]',
 	'No recent actions.' => 'Ninguna acción reciente',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5567,7 +5574,7 @@
 	'Facebook Application Key' => 'Clave de la aplicación de Facebook',
 	'The key for the Facebook application associated with your blog.' => 'La clave de la aplicación de Facebook asociada con su blog.',
 	'Edit Facebook App' => 'Editar aplicación de Facebook',
-	'Create Facebook App' => 'Crear aplicación de Facebook', # Translate - New
+	'Create Facebook App' => 'Crear aplicación de Facebook',
 	'Facebook Application Secret' => 'Secreto de la aplicación de Facebook',
 	'The secret for the Facebook application associated with your blog.' => 'El secreto de la aplicación de Facebook asociada con su blog.',
 
@@ -5854,9 +5861,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] actualizando [_2] eventos para [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Error actualizando eventos para el torrente [_2] de [_1] (tipo [_3] ident [_4]): [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'No se pudo cargar la clase [_1] del torrente [_2] [_3]: [_4]',
-	'No URL to fetch for [_1] results' => 'Sin URL para obtener resultados de [_1]', # Translate - New
-	'Could not fetch [_1]: [_2]' => 'No se pudo obtener [_1]: [_2]', # Translate - New
-	'Aborted fetching [_1]: [_2]' => 'Se abortó durante la obtención de [_1]: [_2]', # Translate - New
+	'No URL to fetch for [_1] results' => 'Sin URL para obtener resultados de [_1]',
+	'Could not fetch [_1]: [_2]' => 'No se pudo obtener [_1]: [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Se abortó durante la obtención de [_1]: [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'El usuario o el ID es obligatorio.',
@@ -5887,7 +5894,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Añadir un perfil de una red social o servicio de mensajería instantánea.',
 	'Select a service where you already have an account.' => 'Seleccione un servicio donde ya tenga una cuenta.',
-	'Add Profile (s)' => 'Añadir perfil (s)', # Translate - New
+	'Add Profile (s)' => 'Añadir perfil (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Se borraron los eventos seleccionados.',
@@ -5921,9 +5928,10 @@
 	'Rebuild Indexes' => 'Reconstruir índices',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Si se selecciona, los índices de este blog se reconstruirán al descubrir nuevos eventos de los torrentes de acciones.',
 	'Enable rebuilding' => 'Activar reconstrucción',
+	'Clone of [_1]' => 'Clon de [_1]', # Translate - New
 
 );
 
-## New words: 100
+## New words: 110
 
 1;
Index: lib/MT/L10N/fr-iso-8859-1.pm
===================================================================
--- lib/MT/L10N/fr-iso-8859-1.pm	(revision 92)
+++ lib/MT/L10N/fr-iso-8859-1.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: fr.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: fr.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::fr;
 use strict;
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'L\'utilisateur n\'a pas fourni d\'indice de mot de passe; impossible de rcuprer le mot de passe',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Tentative invalide de rcupration du mot de passe (indice de \'utilisateur \'[_1]\')',
 	'User does not have email address' => 'L\'utilisateur n\'a pas d\'adresse email',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Un lien de rinitialisation du mot de passe a t envoy  [_3] concernant l\'utilisateur \'[_1]\' (utilisateur #[_2]).', # Translate - New
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Un lien de rinitialisation du mot de passe a t envoy  [_3] concernant l\'utilisateur \'[_1]\' (utilisateur #[_2]).',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Certains objets n\'ont pas t restaurs car leurs objets parents n\'ont pas t restaurs. Des informations dtailles se trouvent dans le journal d\'activit.',
 	'[_1] is not a directory.' => '[_1] n\'est pas un rpertoire.',
 	'Error occured during restore process.' => 'Une erreur s\'est produite pendant la procdure de restauration.',
@@ -2110,7 +2110,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Pour crer un nouveau fichier de configuration avec l\'assistant, supprimez le fichier de configuration actuel puis rechargez cette page',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Pour utiliser Movable Type, vous devez activer les JavaScript sur votre navigateur. Merci de les activer et de relancer le navigateur pour commencer.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Vous allez maintenant, grce  cet assistant de configuration, mettre en place les paramtres de base afin d\'assurer le fonctionnement de Movable Type.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Erreur: \'[_1]\' n\'a pas pu tre trouv(e).  Veuillez dplacer vos fichiers statiques vers le rpertoire premier ou mettre  jour les paramtres si ncessaire.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Erreur: \'[_1]\' ne peut pas tre trouv.  Veuillez d\'abord dplacer vos fichiers statiques dans le rpertoire ou corriger les paramtres s\'ils sont incorrects.', # Translate - New
 	'Configure Static Web Path' => 'Configurer le chemin web statique',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type est fourni avec un rpertoire nomm [_1] contenant un nombre important de fichiers comme des images, fichiers javascripts et feuilles de style.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'Le rpertoire [_1] est le rpertoire principal de Movable Type contenant les scripts de cet assistant, mais  cause de la configuration de votre serveur web, le rpertoire [_1] n\'est pas accessible  cette adresse et doit tre dplac vers un serveur web (par exemple, le rpertoire document  la racine). ',
@@ -2735,7 +2735,7 @@
 	'Save display options' => 'Enregistrer les options d\'affichage',
 	'OK' => 'OK',
 	'Close display options' => 'Fermer les options d\'affichage',
-	'This post was held for review, due to spam filtering.' => 'Cette note a t retenue pour vrification,  cause du filtrage spam.', # Translate - New
+	'This post was held for review, due to spam filtering.' => 'Cette note a t retenue pour vrification,  cause du filtrage spam.',
 	'This post was classified as spam.' => 'Cette note a t marque comme tant du spam.',
 	'Spam Details' => 'Dtails du spam',
 	'Score' => 'Score',
@@ -3235,6 +3235,7 @@
 	'Create widget template' => 'Crer un gabarit de widget',
 	'Widget Template' => 'Gabarit de Widget',
 	'Widget Templates' => 'Gabarits de Widget',
+	'widget templates' => 'gabarits de widget', # Translate - Case
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => 'Vous avez ajout [_1]  votre carnet d\'adresses.',
@@ -3781,7 +3782,7 @@
 	'New Password' => 'Nouveau mot de passe',
 	'Enter the new password.' => 'Saisissez le nouveau mot de passe.',
 	'Password recovery word/phrase' => 'Indice de rcupration du mot de passe',
-	'This word or phrase is not used in the password recovery.' => 'Ce mot ou cette phrase n\'est pas utilis dans la rcupration du mot de passe.', # Translate - New
+	'This word or phrase is not used in the password recovery.' => 'Ce mot ou cette phrase n\'est pas utilis dans la rcupration du mot de passe.',
 	'Preferred language of this user.' => 'Langue prfre de cet utilisateur.',
 	'Text Format' => 'Format du texte',
 	'Preferred text format option.' => 'Option de format de texte prfr.',
@@ -3849,9 +3850,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'Votre dernire note a t [_2] dans [_4].',
+	'Your last entry was [_1] in [_3].' => 'Votre dernire note a t [_1] dans [_3].', # Translate - New
 	'You have [quant,_2,draft,drafts].' => 'Vous avez [quant,_2,brouillon,brouillons].',
+	'You have [quant,_1,draft,drafts].' => 'Vous avez [quant,_1,brouillon,brouillons]', # Translate - New
 	'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Vous avez crit [quant,_2,note,notes] avec [quant,_4,commentaire,commentaires].',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Vous avez rdig [quant,_1,note,notes] avec [quant,_3,commentaire,commentaires].', # Translate - New
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Vous avez rdig [quant,_1,note,notes] avec [quant,_2,commentaire,commentaires].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries].' => 'Vous avez crit [quant,_2,note,notes].',
+	'You\'ve written [quant,_1,entry,entries].' => 'Vous avez rdig [quant,_1,note,notes].', # Translate - New
 	'Edit your profile' => 'Modifier votre profil',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3899,6 +3905,8 @@
 	'Total Users' => 'Utilisateurs au total',
 	'Active Users' => 'Utilisateurs actifs',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Les utilisateurs qui se sont connects dans les 90 derniers jours sont considrs comme actifs dans les accords de licence Movable Type',
+	'Memcache Status' => 'Statut Memcache', # Translate - New
+	'Server Model' => 'Modle du serveur', # Translate - New
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type n\'a pu trouver le script nomm \'mt-check.cgi\'. Pour rsoudre ce problme, assurez-vous que le script mt-check.cgi script existe et/ou que la configuration des paramtres de MTCheckScript le rfrence convenablement.',
 
 ## tmpl/cms/restore.tmpl
@@ -4063,8 +4071,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Rglages de la communaut',
-	'Pending Entries' => 'Notes en attente', # Translate - New
-	'Spam Entries' => 'Notes indsirables', # Translate - New
+	'Pending Entries' => 'Notes en attente',
+	'Spam Entries' => 'Notes indsirables',
 	'Following Users' => 'Utilisateurs suiveurs',
 	'Being Followed' => 'tre suivi',
 	'Sanitize' => 'Nettoyer',
@@ -4080,8 +4088,8 @@
 	'Profile View' => 'Vue du profil',
 	'Profile Edit Form' => 'Formulaire de modification du profil',
 	'Profile Feed' => 'Flux du profil',
-	'New Password Form' => 'Nouveau formulaire de mot de passe', # Translate - New
-	'New Password Reset Form' => 'Nouveau formulaire de rinitialisation du mot de passe', # Translate - New
+	'New Password Form' => 'Nouveau formulaire de mot de passe',
+	'New Password Reset Form' => 'Nouveau formulaire de rinitialisation du mot de passe',
 	'Form Field' => 'Champ de formulaire',
 	'Status Message' => 'Message de statut',
 	'Simple Header' => 'Tte de page simple',
@@ -4120,7 +4128,7 @@
 	'Your confirmation have expired. Please register again.' => 'Votre confirmation a expir. Merci de vous inscrire  nouveau.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'L\'utilisateur \'[_1]\' (ID:[_2]) a t enregistr avec succs.',
 	'Thanks for the confirmation.  Please sign in.' => 'Merci pour la confirmation. Identifiez-vous.',
-	'[_1] registered to Movable Type.' => '[_1] s\'est enregistr(e)  Movable Type.', # Translate - New
+	'[_1] registered to Movable Type.' => '[_1] s\'est enregistr(e)  Movable Type.',
 	'Login required' => 'Authentification obligatoire',
 	'Title or Content is required.' => 'Le titre ou le contenu est requis.',
 	'System template entry_response not found in blog: [_1]' => 'Gabarit systme entry_response introuvable dans le blog: [_1]',
@@ -5292,7 +5300,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Un thme Movable Type avec des notes structures et des flux d\'actions.',
 	'Adjusting field types for embed custom fields...' => 'Ajustement des types de champs pour les champs personnaliss d\'lments embarqus...',
 	'Updating favoriting namespace for Motion...' => 'Mise  jour des espaces de nom favoris pour Motion...',
-	'Reinstall Motion Templates' => 'Rinstaller les gabarits Motion',
 	'Motion Themes' => 'Thmes Motion',
 	'Themes for Motion template set' => 'Thmes pour le jeu de gabarits Motion',
 	'Motion' => 'Motion',
@@ -5312,8 +5319,8 @@
 	'Profile Feed' => 'Flux du profil',
 	'Login Form' => 'Formulaire d\'identification',
 	'Register Confirmation' => 'Confirmation d\'inscription',
-	'Password Reset' => 'Rinitialisation du mot de passe',
-	'New Password Form' => 'Nouveau formulaire de mot de passe', # Translate - New
+	'New Password Reset Form' => 'Nouveau formulaire de rinitialisation du mot de passe',
+	'New Password Form' => 'Nouveau formulaire de mot de passe',
 	'User Profile' => 'Profil de l\'utilisateur',
 	'Actions (Local)' => 'Actions (locales)',
 	'Comment Detail' => 'Dtail du Commentaire',
@@ -5435,7 +5442,7 @@
 	'Remove service' => 'Retirer le service',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Identifiez-vous', # Translate - New
+	'Sign In' => 'Identifiez-vous',
 	'Not a member? Register' => 'Pas encore membre? Enregistrez-vous',
 	'(or Sign In)' => '(ou Identifiez-vous)',
 	'No posting privileges.' => 'Pas les droits ncessaires pour publier.',
@@ -5453,7 +5460,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] a comment sur [_2]',
-	'[_1] favorited [_2]' => '[_1] apprcie [_2]', # Translate - New
+	'[_1] favorited [_2]' => '[_1] apprcie [_2]',
 	'No recent actions.' => 'Plus d\'actions rcentes.',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5563,13 +5570,13 @@
 	'{*actor*} commented on the blog post {*post_title*}.' => '{*actor*} a comment la note {*post_title*}.',
 	'Could not register story template with Facebook: [_1]. Did you enter the correct application secret?' => 'Impossible d\'enregistrer le modle d\'histoire avec Facebook : [_1]. Avez-vous correctement entr le secret de l\'application ?',
 	'Could not register story template with Facebook: [_1]' => 'Impossible d\'enregistrer le modle d\'histoire avec Facebook : [_1].',
-	'Facebook' => 'Facebook', # Translate - Case
+	'Facebook' => 'Facebook',
 
 ## plugins/FacebookCommenters/tmpl/blog_config_template.tmpl
 	'Facebook Application Key' => 'Cl Application Facebook',
 	'The key for the Facebook application associated with your blog.' => 'La cl pour l\'application Facebook associe  votre blog.',
 	'Edit Facebook App' => 'diter l\'application Facebook',
-	'Create Facebook App' => 'Crer une application Facebook', # Translate - New
+	'Create Facebook App' => 'Crer une application Facebook',
 	'Facebook Application Secret' => 'Secret Application Facebook',
 	'The secret for the Facebook application associated with your blog.' => 'Le secret pour l\'application Facebook associe  votre blog.',
 
@@ -5856,9 +5863,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] mets  jour [_2] vnements pour [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Erreur lors de la mise  jour des vnements pour le flux [_2] de [_1] (type [_3] ident [_4]) : [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Impossible de charger la classe [_1] pour le flux [_2] [_3] : [_4]',
-	'No URL to fetch for [_1] results' => 'Aucune URL  joindre pour les rsultats [_1]', # Translate - New
-	'Could not fetch [_1]: [_2]' => 'Impossible de joindre [_1] : [_2]', # Translate - New
-	'Aborted fetching [_1]: [_2]' => 'Opration abandonne [_1] : [_2]', # Translate - New
+	'No URL to fetch for [_1] results' => 'Aucune URL  joindre pour les rsultats [_1]',
+	'Could not fetch [_1]: [_2]' => 'Impossible de joindre [_1] : [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Opration abandonne [_1] : [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'Votre nom d\'utilisateur ou ID est requis.',
@@ -5889,7 +5896,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Ajouter un profil sur un service de rseau social ou de messagerie instantane.',
 	'Select a service where you already have an account.' => 'Slectionnez un service o vous avez dj un compte.',
-	'Add Profile (s)' => 'Ajouter le Profil (s)', # Translate - New
+	'Add Profile (s)' => 'Ajouter le Profil (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Les vnements slectionns ont t supprims.',
@@ -5923,9 +5930,10 @@
 	'Rebuild Indexes' => 'Republier les index',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Si slectionner, les index des blogs seront republis lorsque de nouveaux vnements du flux d\'activit seront dcouverts.',
 	'Enable rebuilding' => 'Activer la republication',
+	'Clone of [_1]' => 'Clone de [_1]', # Translate - New
 
 );
 
-## New words: 91
+## New words: 110
 
 1;
Index: lib/MT/L10N/fr.pm
===================================================================
--- lib/MT/L10N/fr.pm	(revision 92)
+++ lib/MT/L10N/fr.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: fr.pm 3517 2009-03-09 14:05:29Z mschenk $
+# $Id: fr.pm 3810 2009-06-08 12:32:45Z mschenk $
 
 package MT::L10N::fr;
 use strict;
@@ -763,7 +763,7 @@
 	'User has not set pasword hint; cannot recover password' => 'L\'utilisateur n\'a pas fourni d\'indice de mot de passe; impossible de récupérer le mot de passe',
 	'Invalid attempt to recover password (used hint \'[_1]\')' => 'Tentative invalide de récupération du mot de passe (indice de \'utilisateur \'[_1]\')',
 	'User does not have email address' => 'L\'utilisateur n\'a pas d\'adresse email',
-	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Un lien de réinitialisation du mot de passe a été envoyé à [_3] concernant l\'utilisateur \'[_1]\' (utilisateur #[_2]).', # Translate - New
+	'A password reset link has been sent to [_3] for user  \'[_1]\' (user #[_2]).' => 'Un lien de réinitialisation du mot de passe a été envoyé à [_3] concernant l\'utilisateur \'[_1]\' (utilisateur #[_2]).',
 	'Some objects were not restored because their parent objects were not restored.  Detailed information is in the activity log.' => 'Certains objets n\'ont pas été restaurés car leurs objets parents n\'ont pas été restaurés. Des informations détaillées se trouvent dans le journal d\'activité.',
 	'[_1] is not a directory.' => '[_1] n\'est pas un répertoire.',
 	'Error occured during restore process.' => 'Une erreur s\'est produite pendant la procédure de restauration.',
@@ -2110,7 +2110,7 @@
 	'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Pour créer un nouveau fichier de configuration avec l\'assistant, supprimez le fichier de configuration actuel puis rechargez cette page',
 	'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Pour utiliser Movable Type, vous devez activer les JavaScript sur votre navigateur. Merci de les activer et de relancer le navigateur pour commencer.',
 	'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Vous allez maintenant, grâce à cet assistant de configuration, mettre en place les paramètres de base afin d\'assurer le fonctionnement de Movable Type.',
-	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Erreur: \'[_1]\' n\'a pas pu être trouvé(e).  Veuillez déplacer vos fichiers statiques vers le répertoire premier ou mettre à jour les paramètres si nécessaire.',
+	'Error: \'[_1]\' could not be found.  Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Erreur: \'[_1]\' ne peut pas être trouvé.  Veuillez d\'abord déplacer vos fichiers statiques dans le répertoire ou corriger les paramètres s\'ils sont incorrects.', # Translate - New
 	'Configure Static Web Path' => 'Configurer le chemin web statique',
 	'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type est fourni avec un répertoire nommé [_1] contenant un nombre important de fichiers comme des images, fichiers javascripts et feuilles de style.',
 	'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'Le répertoire [_1] est le répertoire principal de Movable Type contenant les scripts de cet assistant, mais à cause de la configuration de votre serveur web, le répertoire [_1] n\'est pas accessible à cette adresse et doit être déplacé vers un serveur web (par exemple, le répertoire document à la racine). ',
@@ -2735,7 +2735,7 @@
 	'Save display options' => 'Enregistrer les options d\'affichage',
 	'OK' => 'OK',
 	'Close display options' => 'Fermer les options d\'affichage',
-	'This post was held for review, due to spam filtering.' => 'Cette note a été retenue pour vérification, à cause du filtrage spam.', # Translate - New
+	'This post was held for review, due to spam filtering.' => 'Cette note a été retenue pour vérification, à cause du filtrage spam.',
 	'This post was classified as spam.' => 'Cette note a été marquée comme étant du spam.',
 	'Spam Details' => 'Détails du spam',
 	'Score' => 'Score',
@@ -3235,6 +3235,7 @@
 	'Create widget template' => 'Créer un gabarit de widget',
 	'Widget Template' => 'Gabarit de Widget',
 	'Widget Templates' => 'Gabarits de Widget',
+	'widget templates' => 'gabarits de widget', # Translate - Case
 
 ## tmpl/cms/list_notification.tmpl
 	'You have added [_1] to your address book.' => 'Vous avez ajouté [_1] à votre carnet d\'adresses.',
@@ -3781,7 +3782,7 @@
 	'New Password' => 'Nouveau mot de passe',
 	'Enter the new password.' => 'Saisissez le nouveau mot de passe.',
 	'Password recovery word/phrase' => 'Indice de récupération du mot de passe',
-	'This word or phrase is not used in the password recovery.' => 'Ce mot ou cette phrase n\'est pas utilisé dans la récupération du mot de passe.', # Translate - New
+	'This word or phrase is not used in the password recovery.' => 'Ce mot ou cette phrase n\'est pas utilisé dans la récupération du mot de passe.',
 	'Preferred language of this user.' => 'Langue préférée de cet utilisateur.',
 	'Text Format' => 'Format du texte',
 	'Preferred text format option.' => 'Option de format de texte préféré.',
@@ -3849,9 +3850,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => 'Votre dernière note a été [_2] dans [_4].',
+	'Your last entry was [_1] in [_3].' => 'Votre dernière note a été [_1] dans [_3].', # Translate - New
 	'You have [quant,_2,draft,drafts].' => 'Vous avez [quant,_2,brouillon,brouillons].',
+	'You have [quant,_1,draft,drafts].' => 'Vous avez [quant,_1,brouillon,brouillons]', # Translate - New
 	'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'Vous avez écrit [quant,_2,note,notes] avec [quant,_4,commentaire,commentaires].',
+	'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Vous avez rédigé [quant,_1,note,notes] avec [quant,_3,commentaire,commentaires].', # Translate - New
+	'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Vous avez rédigé [quant,_1,note,notes] avec [quant,_2,commentaire,commentaires].', # Translate - New
 	'You\'ve written [quant,_2,entry,entries].' => 'Vous avez écrit [quant,_2,note,notes].',
+	'You\'ve written [quant,_1,entry,entries].' => 'Vous avez rédigé [quant,_1,note,notes].', # Translate - New
 	'Edit your profile' => 'Modifier votre profil',
 
 ## tmpl/cms/widget/new_install.tmpl
@@ -3899,6 +3905,8 @@
 	'Total Users' => 'Utilisateurs au total',
 	'Active Users' => 'Utilisateurs actifs',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Les utilisateurs qui se sont connectés dans les 90 derniers jours sont considérés comme actifs dans les accords de licence Movable Type',
+	'Memcache Status' => 'Statut Memcache', # Translate - New
+	'Server Model' => 'Modèle du serveur', # Translate - New
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type n\'a pu trouver le script nommé \'mt-check.cgi\'. Pour résoudre ce problème, assurez-vous que le script mt-check.cgi script existe et/ou que la configuration des paramètres de MTCheckScript le référence convenablement.',
 
 ## tmpl/cms/restore.tmpl
@@ -4063,8 +4071,8 @@
 
 ## addons/Community.pack/config.yaml
 	'Community Settings' => 'Réglages de la communauté',
-	'Pending Entries' => 'Notes en attente', # Translate - New
-	'Spam Entries' => 'Notes indésirables', # Translate - New
+	'Pending Entries' => 'Notes en attente',
+	'Spam Entries' => 'Notes indésirables',
 	'Following Users' => 'Utilisateurs suiveurs',
 	'Being Followed' => 'Être suivi',
 	'Sanitize' => 'Nettoyer',
@@ -4080,8 +4088,8 @@
 	'Profile View' => 'Vue du profil',
 	'Profile Edit Form' => 'Formulaire de modification du profil',
 	'Profile Feed' => 'Flux du profil',
-	'New Password Form' => 'Nouveau formulaire de mot de passe', # Translate - New
-	'New Password Reset Form' => 'Nouveau formulaire de réinitialisation du mot de passe', # Translate - New
+	'New Password Form' => 'Nouveau formulaire de mot de passe',
+	'New Password Reset Form' => 'Nouveau formulaire de réinitialisation du mot de passe',
 	'Form Field' => 'Champ de formulaire',
 	'Status Message' => 'Message de statut',
 	'Simple Header' => 'Tête de page simple',
@@ -4120,7 +4128,7 @@
 	'Your confirmation have expired. Please register again.' => 'Votre confirmation a expiré. Merci de vous inscrire à nouveau.',
 	'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'L\'utilisateur \'[_1]\' (ID:[_2]) a été enregistré avec succès.',
 	'Thanks for the confirmation.  Please sign in.' => 'Merci pour la confirmation. Identifiez-vous.',
-	'[_1] registered to Movable Type.' => '[_1] s\'est enregistré(e) à Movable Type.', # Translate - New
+	'[_1] registered to Movable Type.' => '[_1] s\'est enregistré(e) à Movable Type.',
 	'Login required' => 'Authentification obligatoire',
 	'Title or Content is required.' => 'Le titre ou le contenu est requis.',
 	'System template entry_response not found in blog: [_1]' => 'Gabarit système entry_response introuvable dans le blog: [_1]',
@@ -5292,7 +5300,6 @@
 	'A Movable Type theme with structured entries and action streams.' => 'Un thème Movable Type avec des notes structurées et des flux d\'actions.',
 	'Adjusting field types for embed custom fields...' => 'Ajustement des types de champs pour les champs personnalisés d\'éléments embarqués...',
 	'Updating favoriting namespace for Motion...' => 'Mise à jour des espaces de nom favoris pour Motion...',
-	'Reinstall Motion Templates' => 'Réinstaller les gabarits Motion',
 	'Motion Themes' => 'Thèmes Motion',
 	'Themes for Motion template set' => 'Thèmes pour le jeu de gabarits Motion',
 	'Motion' => 'Motion',
@@ -5312,8 +5319,8 @@
 	'Profile Feed' => 'Flux du profil',
 	'Login Form' => 'Formulaire d\'identification',
 	'Register Confirmation' => 'Confirmation d\'inscription',
-	'Password Reset' => 'Réinitialisation du mot de passe',
-	'New Password Form' => 'Nouveau formulaire de mot de passe', # Translate - New
+	'New Password Reset Form' => 'Nouveau formulaire de réinitialisation du mot de passe',
+	'New Password Form' => 'Nouveau formulaire de mot de passe',
 	'User Profile' => 'Profil de l\'utilisateur',
 	'Actions (Local)' => 'Actions (locales)',
 	'Comment Detail' => 'Détail du Commentaire',
@@ -5435,7 +5442,7 @@
 	'Remove service' => 'Retirer le service',
 
 ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml
-	'Sign In' => 'Identifiez-vous', # Translate - New
+	'Sign In' => 'Identifiez-vous',
 	'Not a member? Register' => 'Pas encore membre? Enregistrez-vous',
 	'(or Sign In)' => '(ou Identifiez-vous)',
 	'No posting privileges.' => 'Pas les droits nécessaires pour publier.',
@@ -5453,7 +5460,7 @@
 
 ## plugins/Motion/templates/Motion/actions_local.mtml
 	'[_1] commented on [_2]' => '[_1] a commenté sur [_2]',
-	'[_1] favorited [_2]' => '[_1] apprécie [_2]', # Translate - New
+	'[_1] favorited [_2]' => '[_1] apprécie [_2]',
 	'No recent actions.' => 'Plus d\'actions récentes.',
 
 ## plugins/Motion/templates/Motion/main_index.mtml
@@ -5563,13 +5570,13 @@
 	'{*actor*} commented on the blog post {*post_title*}.' => '{*actor*} a commenté la note {*post_title*}.',
 	'Could not register story template with Facebook: [_1]. Did you enter the correct application secret?' => 'Impossible d\'enregistrer le modèle d\'histoire avec Facebook : [_1]. Avez-vous correctement entré le secret de l\'application ?',
 	'Could not register story template with Facebook: [_1]' => 'Impossible d\'enregistrer le modèle d\'histoire avec Facebook : [_1].',
-	'Facebook' => 'Facebook', # Translate - Case
+	'Facebook' => 'Facebook',
 
 ## plugins/FacebookCommenters/tmpl/blog_config_template.tmpl
 	'Facebook Application Key' => 'Clé Application Facebook',
 	'The key for the Facebook application associated with your blog.' => 'La clé pour l\'application Facebook associée à votre blog.',
 	'Edit Facebook App' => 'Éditer l\'application Facebook',
-	'Create Facebook App' => 'Créer une application Facebook', # Translate - New
+	'Create Facebook App' => 'Créer une application Facebook',
 	'Facebook Application Secret' => 'Secret Application Facebook',
 	'The secret for the Facebook application associated with your blog.' => 'Le secret pour l\'application Facebook associée à votre blog.',
 
@@ -5856,9 +5863,9 @@
 	'[_1] updating [_2] events for [_3]' => '[_1] mets à jour [_2] événements pour [_3]',
 	'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Erreur lors de la mise à jour des événements pour le flux [_2] de [_1] (type [_3] ident [_4]) : [_5]',
 	'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Impossible de charger la classe [_1] pour le flux [_2] [_3] : [_4]',
-	'No URL to fetch for [_1] results' => 'Aucune URL à joindre pour les résultats [_1]', # Translate - New
-	'Could not fetch [_1]: [_2]' => 'Impossible de joindre [_1] : [_2]', # Translate - New
-	'Aborted fetching [_1]: [_2]' => 'Opération abandonnée [_1] : [_2]', # Translate - New
+	'No URL to fetch for [_1] results' => 'Aucune URL à joindre pour les résultats [_1]',
+	'Could not fetch [_1]: [_2]' => 'Impossible de joindre [_1] : [_2]',
+	'Aborted fetching [_1]: [_2]' => 'Opération abandonnée [_1] : [_2]',
 
 ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl
 	'Your user name or ID is required.' => 'Votre nom d\'utilisateur ou ID est requis.',
@@ -5889,7 +5896,7 @@
 ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl
 	'Add a profile on a social networking or instant messaging service.' => 'Ajouter un profil sur un service de réseau social ou de messagerie instantanée.',
 	'Select a service where you already have an account.' => 'Sélectionnez un service où vous avez déjà un compte.',
-	'Add Profile (s)' => 'Ajouter le Profil (s)', # Translate - New
+	'Add Profile (s)' => 'Ajouter le Profil (s)',
 
 ## plugins/ActionStreams/tmpl/list_profileevent.tmpl
 	'The selected events were deleted.' => 'Les événements sélectionnés ont été supprimés.',
@@ -5923,9 +5930,10 @@
 	'Rebuild Indexes' => 'Republier les index',
 	'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Si sélectionner, les index des blogs seront republiés lorsque de nouveaux événements du flux d\'activité seront découverts.',
 	'Enable rebuilding' => 'Activer la republication',
+	'Clone of [_1]' => 'Clone de [_1]', # Translate - New
 
 );
 
-## New words: 91
+## New words: 110
 
 1;
Index: lib/MT/L10N/ja.pm
===================================================================
--- lib/MT/L10N/ja.pm	(revision 92)
+++ lib/MT/L10N/ja.pm	(working copy)
@@ -3,7 +3,7 @@
 # GNU General Public License, version 2.
 #
 #
-# $Id: ja.pm 3519 2009-03-10 03:14:52Z auno $
+# $Id: ja.pm 3762 2009-05-29 05:30:56Z fumiakiy $
 
 package MT::L10N::ja;
 use strict;
@@ -2558,6 +2558,8 @@
 	'Total Users' => '全ユーザー数',
 	'Active Users' => 'アクティブユーザー数',
 	'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => '90日以内にログインしたユーザーがMovable Typeの使用許諾に基づいてアクティブとみなされます。',
+	'Memcache Status' => 'Memcacheの状態',
+	'Server Model' => 'サーバーモデル',
 	'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'mt-check.cgiが見つかりませんでした。mt-check.cgiが存在すること、名前を変えた場合は構成ファイルのCheckScriptディレクティブに名前を指定してください。',
 
 ## tmpl/cms/list_ping.tmpl
@@ -3257,9 +3259,14 @@
 
 ## tmpl/cms/widget/this_is_you.tmpl
 	'Your last entry was [_2] in [_4].' => '最後にブログ記事を書いたのは[_2]です(ブログ: [_4] - 編集)。',
+	'Your last entry was [_1] in [_3].' => '最後にブログ記事を書いたのは[_1]です(ブログ: [_3])',
 	'You have [quant,_2,draft,drafts].' => '下書きが[quant,_2,件,件]あります。',
+	'You have [quant,_1,draft,drafts].' => '下書きが[quant,_1,件,件]あります。',
 	'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'ブログ記事[quant,_2,件,件]
コメント[quant,_4,件,件]', + 'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'ブログ記事[quant,_1,件,件]
コメント[quant,_3,件,件]', + 'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'ブログ記事[quant,_1,件,件]
コメント[quant,_2,件,件]', 'You\'ve written [quant,_2,entry,entries].' => 'ブログ記事[quant,_2,件,件]', + 'You\'ve written [quant,_1,entry,entries].' => 'ブログ記事[quant,_1,件,件]', 'Edit your profile' => 'ユーザー情報の編集', ## tmpl/cms/widget/new_user.tmpl @@ -3778,7 +3785,7 @@ 'Limited Fields' => '項目を指定する', 'Date Range' => '日付範囲', 'Reported as Spam?' => 'スパムコメント/トラックバック', - 'Search Fields:' => '検索対象フィールド', + 'Search Fields:' => '検索対象フィールド:', '_DATE_FROM' => '開始日', '_DATE_TO' => '終了日', 'Successfully replaced [quant,_1,record,records].' => '[quant,_1,件,件]のデータを置き換えました。', @@ -3820,6 +3827,7 @@ 'Create widget template' => 'ウィジェットテンプレートを作成', 'Widget Template' => 'ウィジェットテンプレート', 'Widget Templates' => 'ウィジェットテンプレート', + 'widget templates' => 'ウィジェットテンプレート', ## tmpl/cms/login.tmpl 'Your Movable Type session has ended.' => 'Movable Typeからログアウトしました。', Index: lib/MT/L10N/nl-iso-8859-1.pm =================================================================== --- lib/MT/L10N/nl-iso-8859-1.pm (revision 92) +++ lib/MT/L10N/nl-iso-8859-1.pm (working copy) @@ -3,7 +3,7 @@ # GNU General Public License, version 2. # # -# $Id: nl.pm 3532 2009-03-12 09:33:02Z mschenk $ +# $Id: nl.pm 3810 2009-06-08 12:32:45Z mschenk $ package MT::L10N::nl; use strict; @@ -763,7 +763,7 @@ 'User has not set pasword hint; cannot recover password' => 'Gebruiker heeft geen wachtwoordhint ingesteld; kan wachtwoord niet recupereren', 'Invalid attempt to recover password (used hint \'[_1]\')' => 'Ongeldige poging om wachtwoord te recupereren (gebruikte hint \'[_1]\')', 'User does not have email address' => 'Gebruiker heeft geen e-mail adres', - 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Een verzoek om het wachtwoord re resetten is naar [_3] gestuurd voor gebruiker \'[_1\' (gebruiker #[_2]).', # Translate - New + 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Een verzoek om het wachtwoord re resetten is naar [_3] gestuurd voor gebruiker \'[_1\' (gebruiker #[_2]).', 'Some objects were not restored because their parent objects were not restored. Detailed information is in the activity log.' => 'Sommige objecten werden niet gerecupereerd omdat hun ouder-objecten niet werden teruggezet. Gedetailleerde informatie is te vinden in het activiteitenlog.', '[_1] is not a directory.' => '[_1] is geen map.', 'Error occured during restore process.' => 'Er deed zich een fout voor tijdens het restore-proces.', @@ -2109,7 +2109,7 @@ 'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Om een nieuw configuratiebestand aan te maken met de Wizard moet u het huidige configuratiebestand verwijderen en deze pagina vernieuwen.', 'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type vereist dat JavaScript ingeschakeld is in uw browser. Gelieve het in te schakelen en herlaad deze pagina om opnieuw te proberen.', 'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Deze wizard zal u helpen met het configureren van de basisinstellingen om Movable Type te doen werken.', - 'Error: \'[_1]\' could not be found. Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fout: \'[_1]\' werd niet gevonden. Gelieve uw statische bestanden eerst te verplaatsen naar de map of corrigeer de instelling als ze niet juist is.', + 'Error: \'[_1]\' could not be found. Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fout: \'[_1]\' werd niet gevonden. Gelieve eerst uw statische bestanden in de map te plaatsen of pas de instelling aan als deze niet juist is.', # Translate - New 'Configure Static Web Path' => 'Statisch webpad instellen', 'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type wordt geleverd met een map genaamd [_1] die een aantal belangrijke bestanden bevat zoals afbeeldingen, javascript bestanden en stylesheets.', 'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'De map [_1] bevindt zich in de hoofdmap van Movable Type waar ook dit wizard script zich bevindt, maar door de configuratie van uw webserver is de [_1] map niet toegankelijk op deze locatie en moet deze dus verplaatst worden naar een locatie die toegankelijk is vanop het web (m.a.w. uw document root map).', @@ -2734,7 +2734,7 @@ 'Save display options' => 'Opties schermindeling opslaan', 'OK' => 'OK', 'Close display options' => 'Opties schermindeling sluiten', - 'This post was held for review, due to spam filtering.' => 'Dit bericht werd in de moderatiewachtrij geplaatst door de spamfilter.', # Translate - New + 'This post was held for review, due to spam filtering.' => 'Dit bericht werd in de moderatiewachtrij geplaatst door de spamfilter.', 'This post was classified as spam.' => 'Dit bericht werd geclassificeerd als spam.', 'Spam Details' => 'Spamdetails', 'Score' => 'Score', @@ -3234,6 +3234,7 @@ 'Create widget template' => 'Widgetsjabloon aanmaken', 'Widget Template' => 'Widgetsjabloon', 'Widget Templates' => 'Widgetsjablonen', + 'widget templates' => 'widgetsjablonen', # Translate - Case ## tmpl/cms/list_notification.tmpl 'You have added [_1] to your address book.' => 'U heeft [_1] toegevoegd aan uw adresboek.', @@ -3780,7 +3781,7 @@ 'New Password' => 'Nieuw wachtwoord', 'Enter the new password.' => 'Vul het nieuwe wachtwoord in', 'Password recovery word/phrase' => 'Woord/uitdrukking om wachtwoord terug te vinden', - 'This word or phrase is not used in the password recovery.' => 'Dit woord of deze uitdrukking wordt niet gebruikt in het woord of de uitdrukking voor het terugvinden van het wachtwoord.', # Translate - New + 'This word or phrase is not used in the password recovery.' => 'Dit woord of deze uitdrukking wordt niet gebruikt in het woord of de uitdrukking voor het terugvinden van het wachtwoord.', 'Preferred language of this user.' => 'Voorkeurstaal van deze gebruiker', 'Text Format' => 'Tekstformaat', 'Preferred text format option.' => 'Voorkeursoptie tekstformaat', @@ -3848,9 +3849,14 @@ ## tmpl/cms/widget/this_is_you.tmpl 'Your last entry was [_2] in [_4].' => 'Uw laatste bericht was [_2] op [_4].', + 'Your last entry was [_1] in [_3].' => 'Uw laatste bericht was [_1] in [_3].', # Translate - New 'You have [quant,_2,draft,drafts].' => 'U heeft [quant,_2,kladbericht, kladberichten].', + 'You have [quant,_1,draft,drafts].' => 'U heeft [quant,_1,kladbericht,kladberichten].', # Translate - New 'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'U heeft [quant,_2,bericht,berichten] geschreven met [quant,_4,reactie,reacties].', + 'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'U heeft [quant,_1,bericht,berichten] met [quant,_3,reactie,reacties].', # Translate - New + 'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'U heeft [quant,_1,bericht,berichten] geschreven met [quant,_2,reactie,reacties].', # Translate - New 'You\'ve written [quant,_2,entry,entries].' => 'U heeft [quant,_2,bericht,berichten] geschreven.', + 'You\'ve written [quant,_1,entry,entries].' => 'U heeft [quant,_1,bericht,berichten] geschreven.', # Translate - New 'Edit your profile' => 'Bewerk uw profiel', ## tmpl/cms/widget/new_install.tmpl @@ -3898,6 +3904,8 @@ 'Total Users' => 'Totaal aantal gebruikers', 'Active Users' => 'Actieve gebruikers', 'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Gebruikers die zich in de afgelopen 90 dagen hebben aangemeld worden als actief beschouwd voor de Movable Type licentieovereenkomst.', + 'Memcache Status' => 'Memcache Status', # Translate - New + 'Server Model' => 'Servertype', # Translate - New 'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type kon het script met de naam \'mt-check.cgi\' niet vinden. Om dit probleem op te lossen, gelieve te controleren dat het mt-check.cgi script bestaat en/of dat de MTCheckScript configuratieparameter er op de juiste manier naar verwijst.', ## tmpl/cms/restore.tmpl @@ -4062,8 +4070,8 @@ ## addons/Community.pack/config.yaml 'Community Settings' => 'Community instellingen', - 'Pending Entries' => 'Berichten in wachtrij', # Translate - New - 'Spam Entries' => 'Spamberichten', # Translate - New + 'Pending Entries' => 'Berichten in wachtrij', + 'Spam Entries' => 'Spamberichten', 'Following Users' => 'Gevolgde gebruikers', 'Being Followed' => 'Wordt gevolgd door', 'Sanitize' => 'Schoonmaakfilter', @@ -4079,8 +4087,8 @@ 'Profile View' => 'Profiel bekijken', 'Profile Edit Form' => 'Bewerkingsformulier profiel', 'Profile Feed' => 'Profielfeed', - 'New Password Form' => 'Formulier nieuw wachtwoord', # Translate - New - 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', # Translate - New + 'New Password Form' => 'Formulier nieuw wachtwoord', + 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', 'Form Field' => 'Veld in formulier', 'Status Message' => 'Statusboodschap', 'Simple Header' => 'Eenvoudige hoofding', @@ -4119,7 +4127,7 @@ 'Your confirmation have expired. Please register again.' => 'Uw bevestiging is verlopen. Gelieve opnieuw te registeren.', 'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'Gebruiker \'[_1]\' (ID:[_2]) werd met succes geregistreerd.', 'Thanks for the confirmation. Please sign in.' => 'Bedankt voor de bevestiging. Gelieve u aan te melden.', - '[_1] registered to Movable Type.' => '[_1] geregistreerd bij Movable Type', # Translate - New + '[_1] registered to Movable Type.' => '[_1] geregistreerd bij Movable Type', 'Login required' => 'Aanmelden vereist', 'Title or Content is required.' => 'Titel of inhoud is vereist.', 'System template entry_response not found in blog: [_1]' => 'Systeemsjabloon entry_response niet gevonden voor blog: [_1]', @@ -5291,7 +5299,6 @@ 'A Movable Type theme with structured entries and action streams.' => 'Een Movable Type thema met gestructureerde berichten en action streams.', 'Adjusting field types for embed custom fields...' => 'Veldtypes aan het aanpassen voor gepersonaliseerde velden van type embed...', 'Updating favoriting namespace for Motion...' => 'Favoriting namespace aan het bijwerken voor Motion...', - 'Reinstall Motion Templates' => 'Motion sjablonen opnieuw installeren', 'Motion Themes' => 'Motion sjablonen', 'Themes for Motion template set' => 'Thema\'s voor de Motion sjabloonset', 'Motion' => 'Motion', @@ -5311,8 +5318,8 @@ 'Profile Feed' => 'Profielfeed', 'Login Form' => 'Aanmeldformulier', 'Register Confirmation' => 'Bevestiging registratie', - 'Password Reset' => 'Wachtwoord vernieuwen', - 'New Password Form' => 'Formulier nieuw wachtwoord', # Translate - New + 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', + 'New Password Form' => 'Formulier nieuw wachtwoord', 'User Profile' => 'Gebruikersprofiel', 'Actions (Local)' => 'Acties (lokaal)', 'Comment Detail' => 'Details reactie', @@ -5434,7 +5441,7 @@ 'Remove service' => 'Service verwijderen', ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml - 'Sign In' => 'Aanmelden', # Translate - New + 'Sign In' => 'Aanmelden', 'Not a member? Register' => 'Nog geen lid? Registreer nu', '(or Sign In)' => '(of meld u aan)', 'No posting privileges.' => 'Geen rechten om berichten te publiceren', @@ -5452,7 +5459,7 @@ ## plugins/Motion/templates/Motion/actions_local.mtml '[_1] commented on [_2]' => '[_1] reageerde op [_2]', - '[_1] favorited [_2]' => '[1] markeerde [_2] als favoriet', # Translate - New + '[_1] favorited [_2]' => '[1] markeerde [_2] als favoriet', 'No recent actions.' => 'Geen recente acties.', ## plugins/Motion/templates/Motion/main_index.mtml @@ -5536,7 +5543,7 @@ 'Profile Data' => 'Profielgegevens', 'More Entries by [_1]' => 'Meer berichten van [_1]', 'Recent Actions' => 'Recente acties', - '_PROFILE_COMMENT_LENGTH' => '10', # Translate - New + '_PROFILE_COMMENT_LENGTH' => '10', 'Comment Threads' => 'Reactie threads', '[_1] commented on ' => '[_1] reageerde op ', 'No responses to comments.' => 'Geen antwoorden op reacties.', @@ -5568,7 +5575,7 @@ 'Facebook Application Key' => 'Facebook applicatiesleutel', 'The key for the Facebook application associated with your blog.' => 'De sleutel voor de Facebook-applicatie geassocieerd met uw blog.', 'Edit Facebook App' => 'Facebook app bewerken', - 'Create Facebook App' => 'Facebook app aanmaken', # Translate - New + 'Create Facebook App' => 'Facebook app aanmaken', 'Facebook Application Secret' => 'Facebook applicatiegeheim', 'The secret for the Facebook application associated with your blog.' => 'Het geheim voor de Facebook-applicatie geassocieerd met uw blog.', @@ -5855,9 +5862,9 @@ '[_1] updating [_2] events for [_3]' => '[_1] [_2] evenementen aan het bijwerken voor [_3]', 'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Fout bij het updaten van evenementen voor [_1]\'s [_2] stream (type [_3] ident [_4]: [5]', 'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Kon klasse [_1] voor stream [_2] [_3] niet laden: [_4]', - 'No URL to fetch for [_1] results' => 'Geen URL binnen te halen voor [_1] resultaten', # Translate - New - 'Could not fetch [_1]: [_2]' => 'Kon [_1] niet binnenhalen: [_2]', # Translate - New - 'Aborted fetching [_1]: [_2]' => 'Ophalen [_1] geannuleerd: [_2]', # Translate - New + 'No URL to fetch for [_1] results' => 'Geen URL binnen te halen voor [_1] resultaten', + 'Could not fetch [_1]: [_2]' => 'Kon [_1] niet binnenhalen: [_2]', + 'Aborted fetching [_1]: [_2]' => 'Ophalen [_1] geannuleerd: [_2]', ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl 'Your user name or ID is required.' => 'Uw gebruikersnaam of ID is vereist.', @@ -5888,7 +5895,7 @@ ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl 'Add a profile on a social networking or instant messaging service.' => 'Voeg een profiel toe op een sociaal netwerk of een instant messaging dienst.', 'Select a service where you already have an account.' => 'Selecteer een service waar u reeds een account heeft.', - 'Add Profile (s)' => 'Profiel Toevoegen (s)', # Translate - New + 'Add Profile (s)' => 'Profiel Toevoegen (s)', ## plugins/ActionStreams/tmpl/list_profileevent.tmpl 'The selected events were deleted.' => 'De geselecteerde gebeurtenissen werden verwijderd.', @@ -5922,9 +5929,10 @@ 'Rebuild Indexes' => 'Indexen herpubliceren', 'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Indien geselecteerd zullen de indexen van deze blog opnieuw worden gepubliceerd telkens nieuwe action stream gebeurtenissen worden ontdekt.', 'Enable rebuilding' => 'Herpubliceren toestaan', + 'Clone of [_1]' => 'Kloon van [_1]', # Translate - New ); -## New words: 95 +## New words: 110 1; Index: lib/MT/L10N/nl.pm =================================================================== --- lib/MT/L10N/nl.pm (revision 92) +++ lib/MT/L10N/nl.pm (working copy) @@ -3,7 +3,7 @@ # GNU General Public License, version 2. # # -# $Id: nl.pm 3532 2009-03-12 09:33:02Z mschenk $ +# $Id: nl.pm 3810 2009-06-08 12:32:45Z mschenk $ package MT::L10N::nl; use strict; @@ -763,7 +763,7 @@ 'User has not set pasword hint; cannot recover password' => 'Gebruiker heeft geen wachtwoordhint ingesteld; kan wachtwoord niet recupereren', 'Invalid attempt to recover password (used hint \'[_1]\')' => 'Ongeldige poging om wachtwoord te recupereren (gebruikte hint \'[_1]\')', 'User does not have email address' => 'Gebruiker heeft geen e-mail adres', - 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Een verzoek om het wachtwoord re resetten is naar [_3] gestuurd voor gebruiker \'[_1\' (gebruiker #[_2]).', # Translate - New + 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Een verzoek om het wachtwoord re resetten is naar [_3] gestuurd voor gebruiker \'[_1\' (gebruiker #[_2]).', 'Some objects were not restored because their parent objects were not restored. Detailed information is in the activity log.' => 'Sommige objecten werden niet gerecupereerd omdat hun ouder-objecten niet werden teruggezet. Gedetailleerde informatie is te vinden in het activiteitenlog.', '[_1] is not a directory.' => '[_1] is geen map.', 'Error occured during restore process.' => 'Er deed zich een fout voor tijdens het restore-proces.', @@ -2109,7 +2109,7 @@ 'To create a new configuration file using the Wizard, remove the current configuration file and then refresh this page' => 'Om een nieuw configuratiebestand aan te maken met de Wizard moet u het huidige configuratiebestand verwijderen en deze pagina vernieuwen.', 'Movable Type requires that you enable JavaScript in your browser. Please enable it and refresh this page to proceed.' => 'Movable Type vereist dat JavaScript ingeschakeld is in uw browser. Gelieve het in te schakelen en herlaad deze pagina om opnieuw te proberen.', 'This wizard will help you configure the basic settings needed to run Movable Type.' => 'Deze wizard zal u helpen met het configureren van de basisinstellingen om Movable Type te doen werken.', - 'Error: \'[_1]\' could not be found. Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fout: \'[_1]\' werd niet gevonden. Gelieve uw statische bestanden eerst te verplaatsen naar de map of corrigeer de instelling als ze niet juist is.', + 'Error: \'[_1]\' could not be found. Please move your static files to the directory first or correct the setting if it is incorrect.' => 'Fout: \'[_1]\' werd niet gevonden. Gelieve eerst uw statische bestanden in de map te plaatsen of pas de instelling aan als deze niet juist is.', # Translate - New 'Configure Static Web Path' => 'Statisch webpad instellen', 'Movable Type ships with directory named [_1] which contains a number of important files such as images, javascript files and stylesheets.' => 'Movable Type wordt geleverd met een map genaamd [_1] die een aantal belangrijke bestanden bevat zoals afbeeldingen, javascript bestanden en stylesheets.', 'The [_1] directory is in the main Movable Type directory which this wizard script resides, but due to your web server\'s configuration, the [_1] directory is not accessible in this location and must be moved to a web-accessible location (e.g., your web document root directory).' => 'De map [_1] bevindt zich in de hoofdmap van Movable Type waar ook dit wizard script zich bevindt, maar door de configuratie van uw webserver is de [_1] map niet toegankelijk op deze locatie en moet deze dus verplaatst worden naar een locatie die toegankelijk is vanop het web (m.a.w. uw document root map).', @@ -2734,7 +2734,7 @@ 'Save display options' => 'Opties schermindeling opslaan', 'OK' => 'OK', 'Close display options' => 'Opties schermindeling sluiten', - 'This post was held for review, due to spam filtering.' => 'Dit bericht werd in de moderatiewachtrij geplaatst door de spamfilter.', # Translate - New + 'This post was held for review, due to spam filtering.' => 'Dit bericht werd in de moderatiewachtrij geplaatst door de spamfilter.', 'This post was classified as spam.' => 'Dit bericht werd geclassificeerd als spam.', 'Spam Details' => 'Spamdetails', 'Score' => 'Score', @@ -3234,6 +3234,7 @@ 'Create widget template' => 'Widgetsjabloon aanmaken', 'Widget Template' => 'Widgetsjabloon', 'Widget Templates' => 'Widgetsjablonen', + 'widget templates' => 'widgetsjablonen', # Translate - Case ## tmpl/cms/list_notification.tmpl 'You have added [_1] to your address book.' => 'U heeft [_1] toegevoegd aan uw adresboek.', @@ -3780,7 +3781,7 @@ 'New Password' => 'Nieuw wachtwoord', 'Enter the new password.' => 'Vul het nieuwe wachtwoord in', 'Password recovery word/phrase' => 'Woord/uitdrukking om wachtwoord terug te vinden', - 'This word or phrase is not used in the password recovery.' => 'Dit woord of deze uitdrukking wordt niet gebruikt in het woord of de uitdrukking voor het terugvinden van het wachtwoord.', # Translate - New + 'This word or phrase is not used in the password recovery.' => 'Dit woord of deze uitdrukking wordt niet gebruikt in het woord of de uitdrukking voor het terugvinden van het wachtwoord.', 'Preferred language of this user.' => 'Voorkeurstaal van deze gebruiker', 'Text Format' => 'Tekstformaat', 'Preferred text format option.' => 'Voorkeursoptie tekstformaat', @@ -3848,9 +3849,14 @@ ## tmpl/cms/widget/this_is_you.tmpl 'Your last entry was [_2] in [_4].' => 'Uw laatste bericht was [_2] op [_4].', + 'Your last entry was [_1] in [_3].' => 'Uw laatste bericht was [_1] in [_3].', # Translate - New 'You have [quant,_2,draft,drafts].' => 'U heeft [quant,_2,kladbericht, kladberichten].', + 'You have [quant,_1,draft,drafts].' => 'U heeft [quant,_1,kladbericht,kladberichten].', # Translate - New 'You\'ve written [quant,_2,entry,entries] with [quant,_4,comment,comments].' => 'U heeft [quant,_2,bericht,berichten] geschreven met [quant,_4,reactie,reacties].', + 'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'U heeft [quant,_1,bericht,berichten] met [quant,_3,reactie,reacties].', # Translate - New + 'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'U heeft [quant,_1,bericht,berichten] geschreven met [quant,_2,reactie,reacties].', # Translate - New 'You\'ve written [quant,_2,entry,entries].' => 'U heeft [quant,_2,bericht,berichten] geschreven.', + 'You\'ve written [quant,_1,entry,entries].' => 'U heeft [quant,_1,bericht,berichten] geschreven.', # Translate - New 'Edit your profile' => 'Bewerk uw profiel', ## tmpl/cms/widget/new_install.tmpl @@ -3898,6 +3904,8 @@ 'Total Users' => 'Totaal aantal gebruikers', 'Active Users' => 'Actieve gebruikers', 'Users who have logged in within 90 days are considered active in Movable Type license agreement.' => 'Gebruikers die zich in de afgelopen 90 dagen hebben aangemeld worden als actief beschouwd voor de Movable Type licentieovereenkomst.', + 'Memcache Status' => 'Memcache Status', # Translate - New + 'Server Model' => 'Servertype', # Translate - New 'Movable Type could not find the script named \'mt-check.cgi\'. To resolve this issue, please ensure that the mt-check.cgi script exists and/or the CheckScript configuration parameter references it properly.' => 'Movable Type kon het script met de naam \'mt-check.cgi\' niet vinden. Om dit probleem op te lossen, gelieve te controleren dat het mt-check.cgi script bestaat en/of dat de MTCheckScript configuratieparameter er op de juiste manier naar verwijst.', ## tmpl/cms/restore.tmpl @@ -4062,8 +4070,8 @@ ## addons/Community.pack/config.yaml 'Community Settings' => 'Community instellingen', - 'Pending Entries' => 'Berichten in wachtrij', # Translate - New - 'Spam Entries' => 'Spamberichten', # Translate - New + 'Pending Entries' => 'Berichten in wachtrij', + 'Spam Entries' => 'Spamberichten', 'Following Users' => 'Gevolgde gebruikers', 'Being Followed' => 'Wordt gevolgd door', 'Sanitize' => 'Schoonmaakfilter', @@ -4079,8 +4087,8 @@ 'Profile View' => 'Profiel bekijken', 'Profile Edit Form' => 'Bewerkingsformulier profiel', 'Profile Feed' => 'Profielfeed', - 'New Password Form' => 'Formulier nieuw wachtwoord', # Translate - New - 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', # Translate - New + 'New Password Form' => 'Formulier nieuw wachtwoord', + 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', 'Form Field' => 'Veld in formulier', 'Status Message' => 'Statusboodschap', 'Simple Header' => 'Eenvoudige hoofding', @@ -4119,7 +4127,7 @@ 'Your confirmation have expired. Please register again.' => 'Uw bevestiging is verlopen. Gelieve opnieuw te registeren.', 'User \'[_1]\' (ID:[_2]) has been successfully registered.' => 'Gebruiker \'[_1]\' (ID:[_2]) werd met succes geregistreerd.', 'Thanks for the confirmation. Please sign in.' => 'Bedankt voor de bevestiging. Gelieve u aan te melden.', - '[_1] registered to Movable Type.' => '[_1] geregistreerd bij Movable Type', # Translate - New + '[_1] registered to Movable Type.' => '[_1] geregistreerd bij Movable Type', 'Login required' => 'Aanmelden vereist', 'Title or Content is required.' => 'Titel of inhoud is vereist.', 'System template entry_response not found in blog: [_1]' => 'Systeemsjabloon entry_response niet gevonden voor blog: [_1]', @@ -5291,7 +5299,6 @@ 'A Movable Type theme with structured entries and action streams.' => 'Een Movable Type thema met gestructureerde berichten en action streams.', 'Adjusting field types for embed custom fields...' => 'Veldtypes aan het aanpassen voor gepersonaliseerde velden van type embed...', 'Updating favoriting namespace for Motion...' => 'Favoriting namespace aan het bijwerken voor Motion...', - 'Reinstall Motion Templates' => 'Motion sjablonen opnieuw installeren', 'Motion Themes' => 'Motion sjablonen', 'Themes for Motion template set' => 'Thema\'s voor de Motion sjabloonset', 'Motion' => 'Motion', @@ -5311,8 +5318,8 @@ 'Profile Feed' => 'Profielfeed', 'Login Form' => 'Aanmeldformulier', 'Register Confirmation' => 'Bevestiging registratie', - 'Password Reset' => 'Wachtwoord vernieuwen', - 'New Password Form' => 'Formulier nieuw wachtwoord', # Translate - New + 'New Password Reset Form' => 'Formulier nieuw wachtwoord resetten', + 'New Password Form' => 'Formulier nieuw wachtwoord', 'User Profile' => 'Gebruikersprofiel', 'Actions (Local)' => 'Acties (lokaal)', 'Comment Detail' => 'Details reactie', @@ -5434,7 +5441,7 @@ 'Remove service' => 'Service verwijderen', ## plugins/Motion/templates/Motion/widget_main_column_registration.mtml - 'Sign In' => 'Aanmelden', # Translate - New + 'Sign In' => 'Aanmelden', 'Not a member? Register' => 'Nog geen lid? Registreer nu', '(or Sign In)' => '(of meld u aan)', 'No posting privileges.' => 'Geen rechten om berichten te publiceren', @@ -5452,7 +5459,7 @@ ## plugins/Motion/templates/Motion/actions_local.mtml '[_1] commented on [_2]' => '[_1] reageerde op [_2]', - '[_1] favorited [_2]' => '[1] markeerde [_2] als favoriet', # Translate - New + '[_1] favorited [_2]' => '[1] markeerde [_2] als favoriet', 'No recent actions.' => 'Geen recente acties.', ## plugins/Motion/templates/Motion/main_index.mtml @@ -5536,7 +5543,7 @@ 'Profile Data' => 'Profielgegevens', 'More Entries by [_1]' => 'Meer berichten van [_1]', 'Recent Actions' => 'Recente acties', - '_PROFILE_COMMENT_LENGTH' => '10', # Translate - New + '_PROFILE_COMMENT_LENGTH' => '10', 'Comment Threads' => 'Reactie threads', '[_1] commented on ' => '[_1] reageerde op ', 'No responses to comments.' => 'Geen antwoorden op reacties.', @@ -5568,7 +5575,7 @@ 'Facebook Application Key' => 'Facebook applicatiesleutel', 'The key for the Facebook application associated with your blog.' => 'De sleutel voor de Facebook-applicatie geassocieerd met uw blog.', 'Edit Facebook App' => 'Facebook app bewerken', - 'Create Facebook App' => 'Facebook app aanmaken', # Translate - New + 'Create Facebook App' => 'Facebook app aanmaken', 'Facebook Application Secret' => 'Facebook applicatiegeheim', 'The secret for the Facebook application associated with your blog.' => 'Het geheim voor de Facebook-applicatie geassocieerd met uw blog.', @@ -5855,9 +5862,9 @@ '[_1] updating [_2] events for [_3]' => '[_1] [_2] evenementen aan het bijwerken voor [_3]', 'Error updating events for [_1]\'s [_2] stream (type [_3] ident [_4]): [_5]' => 'Fout bij het updaten van evenementen voor [_1]\'s [_2] stream (type [_3] ident [_4]: [5]', 'Could not load class [_1] for stream [_2] [_3]: [_4]' => 'Kon klasse [_1] voor stream [_2] [_3] niet laden: [_4]', - 'No URL to fetch for [_1] results' => 'Geen URL binnen te halen voor [_1] resultaten', # Translate - New - 'Could not fetch [_1]: [_2]' => 'Kon [_1] niet binnenhalen: [_2]', # Translate - New - 'Aborted fetching [_1]: [_2]' => 'Ophalen [_1] geannuleerd: [_2]', # Translate - New + 'No URL to fetch for [_1] results' => 'Geen URL binnen te halen voor [_1] resultaten', + 'Could not fetch [_1]: [_2]' => 'Kon [_1] niet binnenhalen: [_2]', + 'Aborted fetching [_1]: [_2]' => 'Ophalen [_1] geannuleerd: [_2]', ## plugins/ActionStreams/tmpl/dialog_edit_profile.tmpl 'Your user name or ID is required.' => 'Uw gebruikersnaam of ID is vereist.', @@ -5888,7 +5895,7 @@ ## plugins/ActionStreams/tmpl/dialog_add_profile.tmpl 'Add a profile on a social networking or instant messaging service.' => 'Voeg een profiel toe op een sociaal netwerk of een instant messaging dienst.', 'Select a service where you already have an account.' => 'Selecteer een service waar u reeds een account heeft.', - 'Add Profile (s)' => 'Profiel Toevoegen (s)', # Translate - New + 'Add Profile (s)' => 'Profiel Toevoegen (s)', ## plugins/ActionStreams/tmpl/list_profileevent.tmpl 'The selected events were deleted.' => 'De geselecteerde gebeurtenissen werden verwijderd.', @@ -5922,9 +5929,10 @@ 'Rebuild Indexes' => 'Indexen herpubliceren', 'If selected, this blog\'s indexes will be rebuilt when new action stream events are discovered.' => 'Indien geselecteerd zullen de indexen van deze blog opnieuw worden gepubliceerd telkens nieuwe action stream gebeurtenissen worden ontdekt.', 'Enable rebuilding' => 'Herpubliceren toestaan', + 'Clone of [_1]' => 'Kloon van [_1]', # Translate - New ); -## New words: 95 +## New words: 110 1; Index: lib/MT/L10N/ru.pm =================================================================== --- lib/MT/L10N/ru.pm (revision 92) +++ lib/MT/L10N/ru.pm (working copy) @@ -1,4 +1,4 @@ -# Русский локализационный файл для Movable Type 4.25 +# Русский локализационный файл для Movable Type 4.26 # # Автор перевода: Андрей Серебряков # @@ -10,7 +10,7 @@ # за автоматизацию процесса перевода # и доработку функции, отвечающей за множественное число. # -# Дата публикации файла: 19 марта 2009 года. +# Дата публикации файла: 11 июня 2009 года. # Последнее изменение: см. последнюю строку комментариев. # # Перевод распространяется по лицензии GNU General Public License v2 @@ -74,7 +74,7 @@ '\'[_1]\' is not a valid function.' => '«[_1]» — это неправильная функция.', ## php/lib/function.mtremotesigninlink.php - 'TypePad authentication is not enabled in this blog. MTRemoteSignInLink can\'t be used.' => 'Авторизация через TypePad не активирована в этом блоге. Тег MTRemoteSignInLink не может быть использован.', + 'TypePad authentication is not enabled in this blog. MTRemoteSignInLink can\'t be used.' => 'Авторизация через TypePad не включена в этом блоге. MTRemoteSignInLink не может быть использована', ## php/lib/function.mtvar.php '\'[_1]\' is not a valid function for a hash.' => '«[_1]» — это неправильная функция для хэша.', @@ -120,8 +120,6 @@ ## php/lib/function.mtproductname.php '[_1] [_2]' => '[_1] [_2]', # Translate - Not translated -## php/lib/block.mtauthorhaspage.php - ## php/lib/function.mtassettype.php 'image' => 'изображение', 'Image' => 'Изображение', @@ -132,22 +130,12 @@ 'video' => 'видео', 'Video' => 'Видео', -## php/lib/block.mtassets.php - -## php/lib/function.mtcommentauthor.php - ## php/lib/MTUtil.php 'userpic-[_1]-%wx%h%x' => 'userpic-[_1]-%wx%h%x', # Translate - Not translated -## php/lib/block.mtif.php - -## php/lib/block.mtsetvarblock.php - ## php/lib/function.mtcommentreplytolink.php 'Reply' => 'Ответить', -## php/lib/block.mtsethashvar.php - ## default_templates/creative_commons.mtml 'This blog is licensed under a Creative Commons License.' => 'Содержимое блога распространяется в соответствии с лицензией Creative Commons.', @@ -296,8 +284,6 @@ ## default_templates/dynamic_error.mtml 'Page Not Found' => 'Страница не найдена', -## default_templates/monthly_entry_listing.mtml - ## default_templates/main_index_widgets_group.mtml 'This is a custom set of widgets that are conditioned to only appear on the homepage (or "main_index"). More info: [_1]' => 'Это произвольный набор виджетов, что обуславливает его включение только на домашней странице (или «main_index»). Дополнительная информация: [_1]', 'Recent Entries' => 'Последние записи', @@ -317,16 +303,12 @@ '[_1]: Monthly Archives' => '[_1]: архив за месяц', '[_1]' => '[_1]', # Translate - Not translated -## default_templates/main_index.mtml - ## default_templates/monthly_archive_list.mtml '[_1] Archives' => 'Архивы [_1]', ## default_templates/powered_by.mtml '_MTCOM_URL' => 'http://www.movabletype.com/', # Translate - No russian chars -## default_templates/category_archive_list.mtml - ## default_templates/comment_response.mtml 'Confirmation...' => 'Подтверждение…', 'Your comment has been submitted!' => 'Ваш комментарий добавлен!', @@ -336,8 +318,6 @@ 'Your comment submission failed for the following reasons: [_1]' => 'Ваш комментарий не добавлен по следующим причинам: [_1]', 'Return to the original entry.' => 'Вернуться к записи.', -## default_templates/current_author_monthly_archive_list.mtml - ## default_templates/date_based_category_archives.mtml 'Category Yearly Archives' => 'Архивы категорий по месяцам', 'Category Weekly Archives' => 'Архивы категорий по неделям', @@ -423,8 +403,6 @@ '[_1]Sign in[_2] to comment, or comment anonymously.' => '[_1]Авторизуйтесь[_2], чтобы прокомментировать эту запись, либо комментируйте анонимно.', 'Replying to comment from [_3]' => 'Ответ на комментарий от [_3]', -## default_templates/recent_entries.mtml - ## default_templates/verify-subscribe.mtml 'Thanks for subscribing to notifications about updates to [_1]. Follow the link below to confirm your subscription:' => 'Благодарим за подписку на уведомления о новых записях на ваш адрес [_1]. Для подтверждения подписки перейдите по следующей ссылке:', 'If the link is not clickable, just copy and paste it into your browser.' => 'Если ссылка не открывается, просто скопируйте её и вставьте в адресную строку браузера.', @@ -447,8 +425,6 @@ 'A request has been made to change your password in Movable Type. To complete this process click on the link below to select a new password.' => 'Сделан запрос на изменение пароля в Movable Type. Для завершения процесса, перейдите по ссылке, расположенной ниже:', 'If you did not request this change, you can safely ignore this email.' => 'Если вы не запрашивали изменение пароля, проигнорируйте это письмо.', -## default_templates/entry.mtml - ## lib/MT/AtomServer.pm '[_1]: Entries' => '[_1]: записи', 'PreSave failed [_1]' => 'Ошибка предварительного сохранения [_1]', @@ -555,13 +531,13 @@ 'This is the test email sent by your new installation of Movable Type.' => 'Это тестовое письмо, отправленное во время установки Movable Type.', 'This module is needed to encode special characters, but this feature can be turned off using the NoHTMLEntities option in mt-config.cgi.' => 'Модуль необходим для кодирования специальных символов. Но вы можете отключить эту возможность, используя опцию NoHTMLEntities в mt-config.cgi.', 'This module is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.' => 'Модуль необходим, если вы хотите использовать трекбэки и пинги сервисов (weblogs.com, technorati.com, blogs.google.com, и т.д.).', - 'HTML::Parser is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.' => 'HTML::Parser не обязателен. Он необходим, если вы хотите использовать трекбэки, а также для пингов различных сервисов.', + 'HTML::Parser is optional; It is needed if you wish to use the TrackBack system, the weblogs.com ping, or the MT Recently Updated ping.' => 'HTML::Parser не обязателен, но он необходим, если вы хотите использовать функцию трекбэков и отправлять уведомления на сервера типа weblogs.com или Яндекс.Блоги', 'This module is needed if you wish to use the MT XML-RPC server implementation.' => 'Модуль необходим, если вы хотите использовать MT XML-RPC (для работы с блогами через сторонние интерфейсы, например, через блогинг-редакторы).', 'This module is needed if you would like to be able to overwrite existing files when you upload.' => 'Модуль необходим для перезаписи файлов после загрузки.', 'List::Util is optional; It is needed if you want to use the Publish Queue feature.' => 'List:Util не обязателен, но он необходим, если вы хотите использовать очередь публикации.', 'Scalar::Util is optional; It is needed if you want to use the Publish Queue feature.' => 'Scalar::Util необязателен; он необходим, если вы хотите использовать функцию очереди публикации.', 'This module is needed if you would like to be able to create thumbnails of uploaded images.' => 'Модуль необходим, если вы хотите иметь возможность делать миниатюры загружаемых изображений.', - 'This module is needed if you would like to be able to use NetPBM as the image driver for MT.' => 'Модуль необходим для использования NetPBM в качестве инструмента обработки изображений.', + 'This module is needed if you would like to be able to use NetPBM as the image driver for MT.' => 'Модуль необходим, если вы хотите использовать в качестве обработчика картинок драйвер NetPBM.', 'This module is required by certain MT plugins available from third parties.' => 'Модуль обязателен для некоторых плагинов MT.', 'This module accelerates comment registration sign-ins.' => 'Модуль ускоряет регистрацию комментаторов.', 'This module and its dependencies are required in order to allow commenters to be authenticated by OpenID providers such as AOL and Yahoo! which require SSL support.' => 'Модуль необходим для авторизации комментаторов через OpenID с использованием протокола HTTPS (AOL, Yahoo).', @@ -818,8 +794,6 @@ 'association' => 'ассоциация', 'associations' => 'ассоциация', -## lib/MT/TBPing.pm - ## lib/MT/Template/Context.pm 'The attribute exclude_blogs cannot take \'all\' for a value.' => 'Атрибут exclude_blogs не может иметь значение «all».', 'You used an \'[_1]\' tag outside of the context of a author; perhaps you mistakenly placed it outside of an \'MTAuthors\' container?' => 'Вы использовали тег «[_1]» вне контекста (автор); возможно, вы поместили его вне контейнера «MTAuthors» ?', @@ -877,7 +851,7 @@ 'Can\'t load user.' => 'Не удалось загрузить пользователя.', 'Division by zero.' => 'Деление на ноль', 'name is required.' => 'имя обязательно.', - 'Specified WidgetSet \'[_1]\' not found.' => 'Указанная связка виджетов не найдена', + 'Specified WidgetSet \'[_1]\' not found.' => 'Указанная связка виджетов не найдена.', 'Can\'t find included template widget \'[_1]\'' => 'Не удалось найти включённый шаблон виджета «[_1]»', ## lib/MT/Bootstrap.pm @@ -932,10 +906,6 @@ 'SFTP get failed: [_1]' => 'Не удалось получить по SFTP: [_1]', 'SFTP put failed: [_1]' => 'Не удалось отправить по SFTP: [_1]', -## lib/MT/FileMgr/FTP.pm - -## lib/MT/FileMgr/Local.pm - ## lib/MT/TaskMgr.pm 'Unable to secure lock for executing system tasks. Make sure your TempDir location ([_1]) is writable.' => 'Не удаётся выполнить блокировку для выполнения системных задач. Разрешите запись в директории TempDir ([_1]).', 'Error during task \'[_1]\': [_2]' => 'Ошибка при выполнении задачи «[_1]» : [_2]', @@ -962,8 +932,6 @@ ## lib/MT/Asset/Video.pm 'Videos' => 'Видео', -## lib/MT/Asset/Audio.pm - ## lib/MT/Builder.pm '<[_1]> at line [_2] is unrecognized.' => '<[_1]> в строке [_2] не распознано.', '<[_1]> with no on line #' => '<[_1]> нет в строке #', @@ -1016,7 +984,7 @@ ## lib/MT/Entry.pm 'Category' => 'Категория', - 'record does not exist.' => 'объект не существует.', # проверить + 'record does not exist.' => 'объект не существует.', 'Draft' => 'Черновик', 'Review' => 'Обзор', 'Future' => 'Запланировано', @@ -1267,7 +1235,7 @@ 'File with name \'[_1]\' already exists; Tried to write to tempfile, but open failed: [_2]' => 'Файл с именем «[_1]» уже существует. Была осуществлена попытка записи временного файла, но не удалось открыть: [_2]', 'Could not create upload path \'[_1]\': [_2]' => 'Не удалось создать путь загрузки «[_1]»: [_2]', 'Error writing upload to \'[_1]\': [_2]' => 'Ошибка записи файла при загрузке в «[_1]»: [_2]', - 'Uploaded file is not an image.' => 'Загруженный файл — не изображение', + 'Uploaded file is not an image.' => 'Загруженный файл — не изображение.', '<' => '<', # Translate - Not translated ## lib/MT/CMS/AddressBook.pm @@ -1412,7 +1380,7 @@ 'User has not set pasword hint; cannot recover password' => 'Пользователь не указал слово/фразу для восстановления пароль; пароль не может быть восстановлен', 'Invalid attempt to recover password (used hint \'[_1]\')' => 'Неудачная попытка восстановления пароля (использована фраза «[_1]»)', 'User does not have email address' => 'У пользователя нет email адреса', - 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Ссылка для сброса пароля у пользователя [_1] (#[_2]) была отправлена по адресу [_3].', + 'A password reset link has been sent to [_3] for user \'[_1]\' (user #[_2]).' => 'Ссылка для сброса пароля пользователя [_1] (#[_2]) была отправлена по адресу [_3].', 'Some objects were not restored because their parent objects were not restored. Detailed information is in the activity log.' => 'Некоторые объекты не были восстановлены, так как не были восстановлены их родительские объекты. Подробная информация содержится в журнале активности.', '[_1] is not a directory.' => '[_1] — не директория.', 'Error occured during restore process.' => 'В процессе восстановления произошла ошибка.', @@ -1436,7 +1404,7 @@ 'Can\'t load role #[_1].' => 'Не удалось загрузить роль #[_1].', 'Roles' => 'Роли', 'Create Role' => 'Создать роль', - '(newly created user)' => '(новые зарегистрированные пользователи)', + '(newly created user)' => '(недавно созданный пользователь)', 'User Associations' => 'Пользовательские ассоциации', 'Role Users & Groups' => 'Роли пользователей и группы', '(Custom)' => '(Собственное)', @@ -1453,7 +1421,7 @@ 'Select a System Administrator' => 'Выберите администратора системы', 'Selected System Administrator' => 'Выбранный администратор системы', 'System Administrator' => 'Администратор системы', - 'represents a user who will be created afterwards' => 'новый зарегистрированный пользователь', + 'represents a user who will be created afterwards' => 'представляет пользователя, который будет впоследствии создан', 'Select Blogs' => 'Выберите блоги', 'Blogs Selected' => 'Выбранные блоги', 'Search Blogs' => 'Найти блоги', @@ -1566,7 +1534,7 @@ 'This weblog requires commenters to pass an email address. If you\'d like to do so you may log in again, and give the authentication service permission to pass your email address.' => 'В этом блоге необходимо указать email адрес. Пожалуйста, авторизуйтесь заново, но перед этим укажите в параметрах авторизационного сервиса, чтобы он по запросу передавал ваш email.', 'Couldn\'t get public key from url provided' => 'Не удалось получить публичный ключ.', 'No public key could be found to validate registration.' => 'Публичный ключ, необходимый для проверки регистрации, не найден.', -# 'TypePad signature verif\'n returned [_1] in [_2] seconds verifying [_3] with [_4]' => '', # Translate - Empty + 'TypePad signature verif\'n returned [_1] in [_2] seconds verifying [_3] with [_4]' => 'Проверка подписи TypePad возвратила [_1] за [_2] сек. проверив [_3] с [_4]', #проверить! 'The TypePad signature is out of date ([_1] seconds old). Ensure that your server\'s clock is correct' => 'Подпись TypePad устарела ([_1] сек. назад). Убедитесь, что часы вашего сервера установлены правильно.', ## lib/MT/Worker/Publish.pm @@ -1965,7 +1933,7 @@ 'Version [_1]' => 'Версия [_1]', 'http://www.sixapart.com/movabletype/' => 'http://www.sixapart.com/movabletype/', # Translate - Not translated 'OpenID URL' => 'OpenID URL', # Translate - Not translated - 'Sign in using your OpenID identity.' => 'Авторизоваться при помощи OpenID-идентификатора.', + 'Sign in using your OpenID identity.' => 'Авторизации при помощи идентификатора OpenID.', 'OpenID is an open and decentralized single sign-on identity system.' => 'OpenID — это открытая и децентрализованная система идентификации.', 'Sign in' => 'Авторизуйтесь', 'Learn more about OpenID.' => 'Узнать больше об OpenID.', @@ -1974,15 +1942,15 @@ 'Your Vox Blog URL' => 'Адрес вашего блога на Vox', 'Learn more about Vox.' => 'Узнать больше о Vox.', 'Sign in using your Gmail account' => 'Авторизоваться через GMail-аккаунт', - 'Sign in to Movable Type with your[_1] Account[_2]' => 'Авторизоваться в Movable Type, используя ваш [_1] аккаунт [_2]', # проверить - 'Turn on OpenID for your Yahoo! account now' => 'Активировать OpenID для своего аккаунта Yahoo! сейчас', + 'Sign in to Movable Type with your[_1] Account[_2]' => 'Авторизоваться в Movable Type, используя ваш [_1] аккаунт [_2]', + 'Turn on OpenID for your Yahoo! account now' => 'Активировать OpenID для своего аккаунта Yahoo!', 'Your AIM or AOL Screen Name' => 'Отображаемое имя в AIM или AOL (Screen Name)', 'Sign in using your AIM or AOL screen name. Your screen name will be displayed publicly.' => 'Авторизоваться с помощью отображаемого имени AIM или AOL. Отображаемое имя будет доступно публично.', 'Your Wordpress.com Username' => 'Имя пользователя Wordpress.com', 'Sign in using your WordPress.com username.' => 'Авторизоваться с помощью логина на Wordpress.com', - 'TypePad is a free, open system providing you a central identity for posting comments on weblogs and logging into other websites. You can register for free.' => 'TypePad — это бесплатная, свободная система, предоставляющая возможность централизованной идентификации для комментирования различных сайтов. Регистрация бесплатна.', + 'TypePad is a free, open system providing you a central identity for posting comments on weblogs and logging into other websites. You can register for free.' => 'TypePad — это бесплатная, открытая система, предоставляющая возможность централизованной идентификации для комментирования различных сайтов. Регистрация бесплатна.', 'Sign in or register with TypePad.' => 'Авторизоваться или зарегистрироваться в TypePad.', - 'Turn on OpenID for your Yahoo! Japan account now' => 'Активировать OpenID для своего Yahoo! Japan аккаунта', + 'Turn on OpenID for your Yahoo! Japan account now' => 'ктивировать OpenID для своего Yahoo! Japan', 'Your Hatena ID' => 'Ваш ID в Hatena', 'Hello, world' => 'Привет мир', 'Hello, [_1]' => 'Привет! Сегодня вы — [_1].', @@ -2079,8 +2047,6 @@ ## search_templates/results_feed.tmpl 'Search Results for [_1]' => 'Результат поиска по «[_1]»', -## search_templates/results_feed_rss2.tmpl - ## search_templates/comments.tmpl 'Search for new comments from:' => 'Поиск новых комментариев от:', 'the beginning' => 'начало', @@ -2303,7 +2269,7 @@ 'Native' => 'Встроенная', 'Require E-mail Address for Comments via TypePad' => 'Требовать email для авторизовавшихся через TypePad', 'If enabled, visitors must allow their TypePad account to share e-mail address when commenting.' => 'Если активно, то комментаторы должны разрешить в своём аккаунте TypePad передачу email адреса.', - 'One or more Perl module may be missing to use this authentication method.' => 'Один или несколько Perl-модулей, возможно, отсутствует для этого метода авторизации', + 'One or more Perl module may be missing to use this authentication method.' => 'Один или несколько Perl-модулей, возможно, отсутствует для этого метода авторизации.', 'Setup TypePad' => 'Настройка TypePad', 'OpenID providers disabled' => 'Провайдеры OpenID отключены', 'Required module (Digest::SHA1) for OpenID commenter authentication is missing.' => 'Модуль (Digest::SHA1), необходимый для авторизации через OpenID, не найден.', @@ -2527,7 +2493,7 @@ 'UTC-9 (Alaskan Time)' => 'UTC-9 (Аляска)', 'UTC-10 (Aleutians-Hawaii Time)' => 'UTC-10 (Время гавайских островов)', 'UTC-11 (Nome Time)' => 'UTC-11 (Время Нома)', - 'Blog language.' => 'Язык блога', + 'Blog language.' => 'Язык блога.', 'Create Blog (s)' => 'Создать блог (s)', ## tmpl/cms/popup/rebuild_confirm.tmpl @@ -2729,10 +2695,6 @@ 'Require E-mail Address for Anonymous Comments' => 'Обязать анонимных комментаторов указывать e-mail', 'If enabled, visitors must provide a valid e-mail address when commenting.' => 'Если эта опция активна, посетителю нужно будет ввести реальный e-mail, чтобы оставить комментарий.', -## tmpl/cms/include/cfg_content_nav.tmpl - -## tmpl/cms/include/login_mt.tmpl - ## tmpl/cms/include/member_table.tmpl 'Are you sure you want to remove the selected user from this blog?' => 'Вы уверены, что хотите удалить выбранного пользователя из этого блога?', 'Are you sure you want to remove the [_1] selected users from this blog?' => 'Вы уверены, что хотите удалить [_1] выбранных пользователей из этого блога?', @@ -2776,8 +2738,6 @@ 'Scheduled' => 'Запланировано', 'Static' => 'Статика', -## tmpl/cms/include/comment_detail.tmpl - ## tmpl/cms/include/import_end.tmpl 'All data imported successfully!' => 'Всё содержимое успешно импортировано!', 'Make sure that you remove the files that you imported from the \'import\' folder, so that if/when you run the import process again, those files will not be re-imported.' => 'Убедитесь, что вы удалили файлы, импортированные из папки «import». Если вы снова запустите процесс импорта, эти файлы не будут импортированы повторно.', @@ -2872,10 +2832,6 @@ ## tmpl/cms/include/blog_table.tmpl 'Delete selected blogs (x)' => 'Удалить выбранные блоги (x)', -## tmpl/cms/include/cfg_system_content_nav.tmpl - -## tmpl/cms/include/tools_content_nav.tmpl - ## tmpl/cms/include/log_table.tmpl 'No log records could be found.' => 'Нет записей для журнала активности.', '_LOG_TABLE_BY' => 'Пользователь', @@ -2909,7 +2865,7 @@ 'http://www.movabletype.org/feedback.html' => 'http://www.movabletype.org/feedback.html', # Translate - Not translated 'Send us Feedback' => 'Обратная связь', ' version [_2]' => ', версия [_2]', - 'with' => 'с', #включая + 'with' => 'с', ## tmpl/cms/include/calendar.tmpl '_LOCALE_WEEK_START' => '1', # Translate - No russian chars @@ -2983,8 +2939,6 @@ '_SEARCH_SIDEBAR' => 'Поиск', 'Show Activity Log' => 'Показать журнал активности', -## tmpl/cms/include/pagination.tmpl - ## tmpl/cms/include/backup_end.tmpl 'All of the data has been backed up successfully!' => 'Все данные были успешно сохранены!', 'Download This File' => 'Скачать этот файл', @@ -3045,7 +2999,7 @@ 'Only show scheduled entries' => 'Показать только запланированные записи', 'Only show scheduled pages' => 'Показать только запланированные страницы', 'Only show spam entries' => 'Показать только спам-записи', - 'Only show spam pages' => 'Показать только спам-записи', + 'Only show spam pages' => 'Показать только спам-страницы', 'Edit Entry' => 'Редактирование записи', 'Edit Page' => 'Редактирование страницы', 'View entry' => 'Посмотреть запись →', @@ -3531,7 +3485,7 @@ 'Six Apart Services' => 'Сервисы Six Apart', 'Your TypePad token is used to access Six Apart services like its free Authentication service.' => 'TypePad-токен используется для доступа к службам Six Apart, например, к бесплатному сервису авторизации.', 'TypePad is enabled.' => 'TypePad включен', - 'TypePad token:' => 'TypePad-токен', + 'TypePad token:' => 'TypePad-токен:', 'Clear TypePad Token' => 'Сбросить TypePad-токен', 'Please click the Save Changes button below to disable authentication.' => 'Пожалуйста, сохраните изменения, чтобы отключить авторизацию.', 'TypePad is not enabled.' => 'TypePad не активирован', @@ -3741,7 +3695,7 @@ 'To proceed, you must authenticate properly with your LDAP server.' => 'Для продолжения вам необходимо авторизоваться при помощи LDAP-сервера.', 'The name used by this user to login.' => 'Имя для входа в систему (login).', 'The user’s email address.' => 'Email адрес', - 'The email address used in the From: header of each email sent from the system.' => 'Этот email используется в заголовке From, который содержится в письмах, отправляемых Movable Type.', + 'The email address used in the From: header of each email sent from the system.' => 'Этот email используется в заголовке From, содержащихся в письмах, отправляемых Movable Type.', 'Use this as system email address' => 'Использовать как системный email', 'The user’s preferred language.' => 'Язык, предпочитаемый пользователем', 'Select a password for your account.' => 'Выбрать пароль для учетной записи.', @@ -4048,8 +4002,6 @@ 'By commenter email' => 'От комментатора с таким email', 'By commenter URL' => 'От комментатора с таким URL', -## tmpl/feeds/feed_entry.tmpl - ## tmpl/feeds/feed_ping.tmpl 'Source blog' => 'Блог-источник', 'By source blog' => 'С этого блога', @@ -4085,8 +4037,6 @@ 'Return to the original entry.' => 'Вернуться к записи.', 'Return to the original page.' => 'Вернуться к странице.', -## tmpl/comment/register.tmpl - ## tmpl/comment/error.tmpl 'Go Back (s)' => 'Вернуться назад', @@ -4227,8 +4177,272 @@ 'Duplicate entry (\'[_1]\') found. Skipping.' => 'Найдена повторяющаяся запись («[_1]»). Пропуск.', 'Saving page (\'[_1]\')...' => 'Сохранение страницы («[_1]»)…', -## plugins/WXRImporter/lib/WXRImporter/Import.pm +## plugins/WXRImporter/tmpl/options.tmpl + 'Before you import WordPress posts to Movable Type, we recommend that you configure your blog\'s publishing paths first.' => 'Прежде чем импортировать контент из Wordpress в Movable Type, рекомендуем настроить путь публикации блога.', + 'Upload path for this WordPress blog' => 'Путь к загруженным файлам этого WordPress блога', + 'Replace with' => 'Заменять', + 'Download attachments' => 'Скачать файлы', + 'Requires the use of a cron job to download attachments from WordPress powered blog in the background.' => 'Предполагается использование запланированного задания (CRON) для скачивания файлов в фоновом режиме из блога, работающего на WordPress.', + 'Download attachments (images and files) from the imported WordPress powered blog.' => 'Скачать файлы (картинки и другие файлы) из импортируемого блога WordPress.', +## plugins/Markdown/SmartyPants.pl + 'Easily translates plain punctuation characters into \'smart\' typographic punctuation.' => 'Позволяет преобразовать обычный текст в текст с правильно оформленной пунктуацией (например: кавычки, тире, и т.д.).', + +## plugins/Markdown/Markdown.pl + 'A plain-text-to-HTML formatting plugin.' => 'Плагин для форматирования обычного текста в HTML', + 'Markdown' => 'Markdown', # Translate - Not translated + 'Markdown With SmartyPants' => 'Markdown и SmartyPants', + +## plugins/MultiBlog/multiblog.pl + 'MultiBlog allows you to publish content from other blogs and define publishing rules and access controls between them.' => 'MultiBlog позволяет публиковать содержимое из нескольких блогов в одном, определяя правила публикации и контроль доступа между ними.', + 'MultiBlog' => 'MultiBlog', # Translate - Not translated + 'Create Trigger' => 'Создать условие', + 'Weblog Name' => 'Имя блога', + 'Search Weblogs' => 'Найти блоги', + 'When this' => 'когда это', + '* All Weblogs' => '* Все блоги', + 'Select to apply this trigger to all weblogs' => 'Нажмите, чтобы применить это условие ко всем блогам', + 'saves an entry' => 'сохраняется запись', + 'publishes an entry' => 'публикуется запись', + 'publishes a comment' => 'публикуется комментарий', + 'publishes a TrackBack' => 'публикуется трекбэк', + 'rebuild indexes.' => 'публиковать индексные шаблоны.', + 'rebuild indexes and send pings.' => 'публиковать индексные шаблоны и отправлять пинги.', + +## plugins/MultiBlog/lib/MultiBlog/Tags.pm + 'MTMultiBlog tags cannot be nested.' => 'Теги MTMultiBlog не могут быть вложенными.', + 'Unknown "mode" attribute value: [_1]. Valid values are "loop" and "context".' => 'Неизвестное значение атрибута "mode": [_1]. Правильные значения: "loop" и "context".', + +## plugins/MultiBlog/lib/MultiBlog.pm + 'The include_blogs, exclude_blogs, blog_ids and blog_id attributes cannot be used together.' => 'Атрибуты include_blogs, exclude_blogs, blog_ids не могут быть использованы вместе.', + 'The attribute exclude_blogs cannot take "all" for a value.' => 'Атрибубут exclude_blogs не может содержать значение «all».', + 'The value of the blog_id attribute must be a single blog ID.' => 'Значение атрибута blog_id должно содержать единственный ID блога.', + 'The value for the include_blogs/exclude_blogs attributes must be one or more blog IDs, separated by commas.' => 'Значения атрибутов include_blogs/exclude_blogs должны содержать один несколько ID блогов, разделённых запятыми.', + +## plugins/MultiBlog/tmpl/system_config.tmpl + 'Default system aggregation policy' => 'Системная политика агрегации по умолчанию', + 'Allow' => 'Разрешить', + 'Disallow' => 'Запретить', + 'Cross-blog aggregation will be allowed by default. Individual blogs can be configured through the blog-level MultiBlog settings to restrict access to their content by other blogs.' => 'Кросс-блоговая агрегация по умолчанию активна. В каждом блоге в параметрах MultiBlog можно запретить передачу контента в другие блоги.', + 'Cross-blog aggregation will be disallowed by default. Individual blogs can be configured through the blog-level MultiBlog settings to allow access to their content by other blogs.' => 'Кросс-блоговая агрегация по умолчанию выключена. В каждом блоге в параметрах MultiBlog можно разрешить передачу контента в другие блоги.', + +## plugins/MultiBlog/tmpl/blog_config.tmpl + 'When' => 'Когда', + 'Any Weblog' => 'Любой блог', + 'Weblog' => 'Блог', + 'Trigger' => 'Событие', + 'Action' => 'Действие', + 'Content Privacy' => 'Политика приватности', + 'Specify whether other blogs in the installation may publish content from this blog. This setting takes precedence over the default system aggregation policy found in the system-level MultiBlog configuration.' => 'Укажите, могут ли другие блоги получать контент с этого блога. Эта опция приоритетнее указанных настроек MultiBlog на системном уровне.', + 'Use system default' => 'Использовать параметры по умолчанию', + 'MTMultiBlog tag default arguments' => 'Аргументы тега MTMultiBlog по умолчанию', + 'Enables use of the MTMultiBlog tag without include_blogs/exclude_blogs attributes. Comma-separated BlogIDs or \'all\' (include_blogs only) are acceptable values.' => 'Разрешить использование тега MTMultiBlog без атрибутов include_blogs/exclude_blogs. Правильные значения здесь — ID блогов, разделённые запятыми, или значение «all» (только для include_blogs).', + 'Include blogs' => 'Включить блоги', + 'Exclude blogs' => 'Исключить блоги', + 'Rebuild Triggers' => 'Условия публикации', + 'Create Rebuild Trigger' => 'Создать условие публикации', + 'You have not defined any rebuild triggers.' => 'У вас ещё не создано условия для публикации.', + +## plugins/MultiBlog/tmpl/dialog_create_trigger.tmpl + 'Create MultiBlog Trigger' => 'Создать условие MultiBlog', + +## plugins/StyleCatcher/config.yaml + 'StyleCatcher lets you easily browse through styles and then apply them to your blog in just a few clicks. To find out more about Movable Type styles, or for new sources for styles, visit the Movable Type styles page.' => 'StyleCatcher позволяет быстро найти и установить стили для вашего блога. Чтобы узнать больше о стилях Movable Type или получить новые стили, посетите специальную страницу.', + 'MT 4 Style Library' => 'Стили MT4', + 'A collection of styles compatible with Movable Type 4 default templates.' => 'Коллекция стилей, совместимых с Movable Type 4.', + 'Styles' => 'Стили', + +## plugins/StyleCatcher/lib/StyleCatcher/CMS.pm + 'Your mt-static directory could not be found. Please configure \'StaticFilePath\' to continue.' => 'Ваша директория mt-static не найдена. Пожалуйста, настройте StaticFilePath в mt-config.cgi для продолжения.', + 'Could not create [_1] folder - Check that your \'themes\' folder is webserver-writable.' => 'Не удалось создать каталог [_1] - удостоверьте, что папка «themes», находящаяся в папке со статическими файлами, доступна для записи.', + 'Successfully applied new theme selection.' => 'Новый стиль успешно применён.', + 'Invalid URL: [_1]' => 'Неверный URL: [_1]', + +## plugins/StyleCatcher/tmpl/view.tmpl + 'Select a Style' => 'Выбрать стиль', + '3-Columns, Wide, Thin, Thin' => '3-колончатый, широкая, узкая, узкая', + '3-Columns, Thin, Wide, Thin' => '3-колончатый, узкая, широкая, узкая', + '3-Columns, Thin, Thin, Wide' => '3-колончатый, узкая, узкая, широкая', + '2-Columns, Thin, Wide' => '2-колончатый, узкая, широкая', + '2-Columns, Wide, Thin' => '2-колончатая, широкая, узкая', + '2-Columns, Wide, Medium' => '2-колончатая, широкая, средняя', + '2-Columns, Medium, Wide' => '2-колончатый, средняя, широкая', + '1-Column, Wide, Bottom' => '1-колончатый, широкая, подвал', + 'None available' => 'Ничего не доступно', + 'Applying...' => 'Применение…', + 'Apply Design' => 'Использовать дизайн', + 'Error applying theme: ' => 'Ошибка установке стиля:', + 'The selected theme has been applied, but as you have changed the layout, you will need to republish your blog to apply the new layout.' => 'Выбранный стиль установлен. Теперь вам необходимо полностью опубликовать ваш блог, чтобы изменения вступили в силу. Если шаблоны стилей не публикуются автоматически с публикацией индексных шаблонов, опубликуйте их вручную.', + 'The selected theme has been applied!' => 'Выбранный стиль установлен!', + 'Error loading themes! -- [_1]' => 'Ошибка при загрузке стиля! — [_1]', + 'Stylesheet or Repository URL' => 'URL таблицы стилей или репозитория', + 'Stylesheet or Repository URL:' => 'URL таблицы стилей или репозитория:', + 'Download Styles' => 'Скачать стиль', + 'Current theme for your weblog' => 'Текущий стилья вашего блога', + 'Current Style' => 'Текущий стиль', + 'Locally saved themes' => 'Локально сохранённые стили', + 'Saved Styles' => 'Сохранённые стили', + 'Default Styles' => 'Стиль по умолчанию', + 'Single themes from the web' => 'Отдельные стили из веб', + 'More Styles' => 'Больше стилей', + 'Selected Design' => 'Выбранный дизайн', + 'Layout' => 'Расположение', + +## plugins/Cloner/cloner.pl + 'Clones a blog and all of its contents.' => 'Клонирование блога и всего его содержимого', + 'Cloning blog \'[_1]\'...' => 'Клонирование блога «[_1]»…', + 'Finished! You can return to the blog listing or configure the Site root and URL of the new blog.' => 'Готово! Вы можете вернуться к списку блогов или настроить URL и путь публикации нового блога.', + 'No blog was selected to clone.' => 'Не выбран блог для клонирования', + 'This action can only be run for a single blog at a time.' => 'Одновременно это действие может выполнено только для одного блога.', + 'Invalid blog_id' => 'Неверный ID блога', + 'Clone Blog' => 'Клонировать блог', + +## lib/MT/Blog.pm + 'Clone of [_1]' => 'Клон [_1]', + +## tmpl/cms/system_check.tmpl + 'Memcache Status' => 'Стутус Memcache', + 'Server Model' => 'Серверная модель', #проверить + +## tmpl/cms/widget/this_is_you.tmpl + 'Your last entry was [_1] in [_3].' => 'Ваша последняя запись создана [_1] в блоге [_3].', + 'You have [quant,_1,draft,drafts].' => 'Также у вас есть [quant,_1,черновик,черновика,черновиков]', + 'You\'ve written [quant,_1,entry,entries] with [quant,_3,comment,comments].' => 'Всего вами создано [quant,_1,запись,записи,записей], которые прокомментировали [quant,_3,раз,раза,раз].', + 'You\'ve written [quant,_1,entry,entries] with [quant,_2,comment,comments].' => 'Всего вами создано [quant,_2,запись,записи,записей], которые прокомментировали [quant,_3,раз,раза,раз].', + 'You\'ve written [quant,_1,entry,entries].' => 'Всего вами создано [quant,_2,запись,записи,записей].', + +## tmpl/cms/list_widget.tmpl + 'widget templates' => 'Шаблоны виджетов', # Translate - Case + +## plugins/TypePadAntiSpam/TypePadAntiSpam.pl + 'TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."' => 'TypePad AntiSpam — это бесплатный сервис от Six Apart, который помогает защищать блог от спама в комментариях и трекбэках. Плагин TypePad AntiSpam отправляет каждый комментарий или трекбэк на проверку, после которой Movable Type сможет пометить эти элементы как спам, если TypePad AntiSpam решит, что это — спам. Если вы заметите, что TypePad AntiSpam неправильно классифицирует какой-то элемент, просто измените его классификацию, пометив флагом «Спам» или, наоборот, «Не спам» со страницы управления комментариями, и в дальнейшем TypePad AntiSpam будет обучаться от ваших действий. Благодаря подобным действиям, сервис будет постоянно улучшаться и, соответственно, спама будет меньше.', + 'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.' => 'На данный момент TypePad AntiSpam заблокировал [quant,_1,сообщение,сообщения,сообщений] в этом блоге и [quant,_1,сообщение,сообщения,сообщений] во всех блогах.', + 'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.' => 'На данный момент TypePad AntiSpam заблокировал [quant,_1,сообщение,сообщения,сообщений].', + 'Failed to verify your TypePad AntiSpam API key: [_1]' => 'Ошибка при проверке вашего API-ключа для TypePad AntiSpam', + 'The TypePad AntiSpam API key provided is invalid.' => 'Указанный API-ключ для TypePad AntiSpam неверный.', + 'TypePad AntiSpam' => 'TypePad AntiSpam', # Translate - Not translated + +## plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm + 'API key is a required parameter.' => 'Ключи API — обязательный параметр.', + +## plugins/TypePadAntiSpam/tmpl/config.tmpl + 'Junk Score Weight' => 'Рейтинг спама', + 'Least Weight' => 'Минимальный уровень', + 'Most Weight' => 'Максимальный уровень', + 'Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks.' => 'Комментарии и трекбэки помечаются как спам между -10 (определённо спам) и +10 (определённо не спам). Эти настроки помогут более точно управлять оценкой TypePad AntiSpam.', + +## plugins/TypePadAntiSpam/tmpl/system.tmpl + 'API Key' => 'API-ключ', + 'To enable this plugin, you\'ll need a free TypePad AntiSpam API key. You can get your free API key at [_1]antispam.typepad.com[_2]. Once you have your key, return to this page and enter it in the field below.' => 'Для включения этого плагина вам необходим бесплатный API-ключ для TypePad AntiSpam. Вы можете получить его на сайте [_1]antispam.typepad.com[_2]. Когда ключ будет у вас, вернитесь на эту страницу и укажите его в указанное ниже поле.', + 'Service Host' => 'Хост сервиса', + 'The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API.' => 'По умолчанию, хост сервиса TypePad AntiSpam — api.antispam.typepad.com. Его не стоит изменять, если вы не используете сторонние сервисы, совместимые с TypePad AntiSpam API.', + +## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl + 'widget_label_width' => 'widget_label_width', # Translate - Not translated + 'widget_totals_width' => 'widget_totals_width', # Translate - Not translated + 'Spam Blocked' => 'Заблокировано спама', + 'on this blog' => 'в этом блоге', + 'on this system' => 'во всей системе', + +## plugins/Textile/textile2.pl + 'A humane web text generator.' => 'Обработчик текста для веб', + 'Textile 2' => 'Textile 2', # Translate - Not translated + +## plugins/WidgetManager/WidgetManager.pl + 'Widget Manager version 1.1; This version of the plugin is to upgrade data from older version of Widget Manager that has been shipped with Movable Type to the Movable Type core schema. No other features are included. You can safely remove this plugin after installing/upgrading Movable Type.' => 'Менеджер виджетов, версия 1.1; Эта версия плагина предназначена для обновления данных со старой версии менеджера виджетов. Поскольку менеджер виджетов теперь встроен в Movable Type, вы можете удалить этот плагин после установки/обновления MT.', + 'Moving storage of Widget Manager [_1]...' => 'Перемещение данных менеджера виджетов [_1]…', + +## plugins/spamlookup/lib/spamlookup.pm + 'Failed to resolve IP address for source URL [_1]' => 'Не удалось проверить IP адрес для URL [_1]', + 'Moderating: Domain IP does not match ping IP for source URL [_1]; domain IP: [_2]; ping IP: [_3]' => 'Модерация: IP домена не соответствует IP адресу, с которого отправлен пинг: [_1]; IP домена: [_2]; IP пингующего: [_3]', + 'Domain IP does not match ping IP for source URL [_1]; domain IP: [_2]; ping IP: [_3]' => 'IP домена не соответствует IP адресу, с которого отправлен пинг: [_1]; IP домена: [_2]; IP пингующего: [_3]', + 'No links are present in feedback' => 'Не предоставлено ссылок', + 'Number of links exceed junk limit ([_1])' => 'Количество ссылок превысило допустимый лимит для спама ([_1])', + 'Number of links exceed moderation limit ([_1])' => 'Количество ссылок превысило допустимый лимит для модерации ([_1])', + 'Link was previously published (comment id [_1]).' => 'Ссылка уже была опубликована (id комментария [_1]).', + 'Link was previously published (TrackBack id [_1]).' => 'Ссылка уже была опубликована (id трекбэка [_1]).', + 'E-mail was previously published (comment id [_1]).' => 'Email уже был опубликован (id комментария [_1]).', + 'Word Filter match on \'[_1]\': \'[_2]\'.' => 'Фильтр по словам соответствует «[_1]»: «[_2]».', + 'Moderating for Word Filter match on \'[_1]\': \'[_2]\'.' => 'Модерация по фильтру слова «[_1]»: «[_2]».', + 'domain \'[_1]\' found on service [_2]' => 'домен «[_1]» присутствует в сервисе [_2]', + '[_1] found on service [_2]' => '[_1] присутствует в сервисе [_2]', + +## plugins/spamlookup/spamlookup.pl + 'SpamLookup module for using blacklist lookup services to filter feedback.' => 'Плагин SpamLookup используется для фильтрации комментариев с использованием чёрного списка.', + 'SpamLookup IP Lookup' => 'SpamLookup — проверка IP', + 'SpamLookup Domain Lookup' => 'SpamLookup — проверка доменов', + 'SpamLookup TrackBack Origin' => 'SpamLookup — происхождение трекбэков', + 'Despam Comments' => 'Комментарии не спам', + 'Despam TrackBacks' => 'Трекбэки не спам', + 'Despam' => 'Не спам', + +## plugins/spamlookup/spamlookup_urls.pl + 'SpamLookup - Link' => 'SpamLookup - Ссылки', + 'SpamLookup module for junking and moderating feedback based on link filters.' => 'Плагин SpamLookup используется для отправки на модерацию комментариев и трекбэков, отфильтрованных по ссылкам.', + 'SpamLookup Link Filter' => 'Фильтр ссылок SpamLookup', + 'SpamLookup Link Memory' => 'Политика ссылок SpamLookup', + 'SpamLookup Email Memory' => 'Политика email SpamLookup', + +## plugins/spamlookup/spamlookup_words.pl + 'SpamLookup module for moderating and junking feedback using keyword filters.' => 'Плагин SpamLookup отправляет на модерацию и помечает как спам комментарии и трекбэки согласно фильтрам по ключевым словам.', + 'SpamLookup Keyword Filter' => 'Фильтр ключевых слов SpamLookup', + +## plugins/spamlookup/tmpl/lookup_config.tmpl + 'Lookups monitor the source IP addresses and hyperlinks of all incoming feedback. If a comment or TrackBack comes from a blacklisted IP address or contains a blacklisted domain, it can be held for moderation or scored as junk and placed into the blog\'s Junk folder. Additionally, advanced lookups on TrackBack source data can be performed.' => 'Плагин Lookups отслеживает IP во всех комментариях и трекбэках. Если комментарий или трекбэк отправлен с IP, находящего в чёрном списке, или содержит доменное имя, также находящееся в чёрном списке, он может быть поставлен на модерирование, либо помечен как спам.', + 'IP Address Lookups' => 'Проверять IP адреса', + 'Moderate feedback from blacklisted IP addresses' => 'Отправлять на модерацию комментарии и трекбэки с IP из чёрного списка', + 'Junk feedback from blacklisted IP addresses' => 'Помечать как спам комментарии и трекбэки с IP из чёрного списка', + 'Adjust scoring' => 'Отрегулируйте значение', + 'Score weight:' => 'Вес значения:', + 'Less' => 'Меньше', + 'More' => 'Больше', + 'block' => 'заблокировать', + 'IP Blacklist Services' => 'Сервис, предоставляющий чёрный список IP', + 'Domain Name Lookups' => 'Проверять доменные имена', + 'Moderate feedback containing blacklisted domains' => 'Отправлять на модерацию сообщения с доменами из чёрного списка', + 'Junk feedback containing blacklisted domains' => 'Помечать как спам сообщения с доменами из чёрного списка', + 'Domain Blacklist Services' => 'Сервис, предоставляющий чёрный список доменов', + 'Advanced TrackBack Lookups' => 'Дополнительная проверка трекбэков', + 'Moderate TrackBacks from suspicious sources' => 'Отправлять на модерацию трекбэки с подозрительных сайтов', + 'Junk TrackBacks from suspicious sources' => 'Помечать как спам трекбэки с подозрительных сайтов', + 'Lookup Whitelist' => 'Проверять белый список', + 'To prevent lookups for specific IP addresses or domains, list each on a line by itself.' => 'Чтобы избежать проверки по конкретным IP-адресам или доменам, укажите их каждый на отдельной строке.', + +## plugins/spamlookup/tmpl/url_config.tmpl + 'Link filters monitor the number of hyperlinks in incoming feedback. Feedback with many links can be held for moderation or scored as junk. Conversely, feedback that does not contain links or only refers to previously published URLs can be positively rated. (Only enable this option if you are sure your site is already spam-free.)' => 'Фильтр ссылок следит за количеством ссылок в комментариях. Комментарии с большим количеством ссылок могут быть отправлены на модерацию или помечены как спам. Или наоборот, комментариям, не содержащим ссылку или содержащим опубликованную ранее ссылку, может быть выставлен положительный рейтинг.', + 'Link Limits' => 'Лимит ссылок', + 'Credit feedback rating when no hyperlinks are present' => 'Повышать рейтинг, если нет ссылки', + 'Moderate when more than' => 'Модерировать, когда больше', + 'link(s) are given' => 'ссылок', + 'Junk when more than' => 'Помечать как спам, когда больше', + 'Link Memory' => 'Политика ссылок', + 'Credit feedback rating when "URL" element of feedback has been published before' => 'Повышать рейтинг, если URL уже был опубликован', + 'Only applied when no other links are present in message of feedback.' => 'Применять только, когда нет других ссылок в комментарии.', + 'Exclude URLs from comments published within last [_1] days.' => 'Исключать URL из комментариев, опубликованных за последние [_1] дн.', + 'Email Memory' => 'Политика email', + 'Credit feedback rating when previously published comments are found matching on the "Email" address' => 'Повышать рейтинг, если в уже опубликованных комментариях был использован тот же email адрес', + 'Exclude Email addresses from comments published within last [_1] days.' => 'Исключать email адреса из комментариев, опубликованных за последние [_1] дн.', + +## plugins/spamlookup/tmpl/word_config.tmpl + 'Incomming feedback can be monitored for specific keywords, domain names, and patterns. Matches can be held for moderation or scored as junk. Additionally, junk scores for these matches can be customized.' => 'Комментарии и трекбэки могут быть проанализированы на наличие ключевых слов, доменных имён и специальных шаблонов. Элементы, в которых будут найдены запрещённые данные, могут быть отправлены на модерацию или помечены как спам.', + 'Keywords to Moderate' => 'Ключевые слова для отправки на модерацию', + 'Keywords to Junk' => 'Ключевые слова, чтобы пометить как спам', + +## plugins/WXRImporter/WXRImporter.pl + 'Import WordPress exported RSS into MT.' => 'Импортировать экспортируемый WordPress RSS в MT', + 'WordPress eXtended RSS (WXR)' => 'WordPress eXtended RSS (WXR)', # Translate - Not translated + 'Download WP attachments via HTTP.' => 'Загрузить файлы WP через HTTP.', + +## plugins/WXRImporter/lib/WXRImporter/WXRHandler.pm + 'File is not in WXR format.' => 'Файл не в формате WXR.', + 'Creating new tag (\'[_1]\')...' => 'Создание нового тега («[_1]»)…', + 'Saving tag failed: [_1]' => 'Не удалось сохранить тег: [_1]', + 'Duplicate asset (\'[_1]\') found. Skipping.' => 'Найдено повторяющееся медиа («[_1]»). Пропуск.', + 'Saving asset (\'[_1]\')...' => 'Сохранение медиа («[_1]»)…', + ' and asset will be tagged (\'[_1]\')...' => ' и медиа будет с тегом («[_1]»)…', + 'Duplicate entry (\'[_1]\') found. Skipping.' => 'Найдена повторяющаяся запись («[_1]»). Пропуск.', + 'Saving page (\'[_1]\')...' => 'Сохранение страницы («[_1]»)…', + ## plugins/WXRImporter/tmpl/options.tmpl 'Before you import WordPress posts to Movable Type, we recommend that you configure your blog\'s publishing paths first.' => 'Прежде чем импортировать контент из Wordpress в Movable Type, рекомендуем настроить путь публикации блога.', 'Upload path for this WordPress blog' => 'Путь к загруженным файлам этого WordPress блога', @@ -4350,11 +4564,10 @@ 'Clone Blog' => 'Клонировать блог', ## Special for MT.ru - 'Reset Password' => 'Сброс пароля', 'Russian' => 'Русский', ); -## New words: 535 +## New words: 594 1; Index: lib/MT/Meta/Proxy.pm =================================================================== --- lib/MT/Meta/Proxy.pm (revision 92) +++ lib/MT/Meta/Proxy.pm (working copy) @@ -291,8 +291,11 @@ my $dataref = shift; return $dataref unless defined $$dataref; - $$dataref =~ s/^([ABCINS]{3})://; - my $prefix = $1; + my $prefix; + if ( $$dataref =~ m/^([ABCINS]{3}):/ ) { + $$dataref =~ s/^([ABCINS]{3})://; + $prefix = $1; + } unless (defined $prefix) { return $dataref; } Index: lib/MT/Object.pm =================================================================== --- lib/MT/Object.pm (revision 92) +++ lib/MT/Object.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Object.pm 3510 2009-03-09 04:13:54Z asawada $ +# $Id: Object.pm 3774 2009-06-01 21:52:50Z jmarcotte $ package MT::Object; @@ -136,6 +136,13 @@ $type_id = $props->{datasource}; } + $props->{get_driver} ||= sub { + require MT::ObjectDriverFactory; + my $coderef = MT::ObjectDriverFactory->driver_for_class($class); + $class->get_driver($coderef); + return $coderef->(@_); + }; + $class->SUPER::install_properties($props); # check for any supplemental columns from other components @@ -225,12 +232,6 @@ $class->add_trigger( post_load => _get_date_translator(\&_db2ts, 0) ); } - if ( exists($props->{cacheable}) && !$props->{cacheable} ) { - no warnings 'redefine'; - no strict 'refs'; ## no critic - *{$class . '::driver'} = sub { $_[0]->dbi_driver(@_) }; - } - # inherit parent's metadata setup if ($props->{meta}) { # if ($super_props && $super_props->{meta_installed}) { $class->install_meta({ ( %meta ? ( column_defs => \%meta ) : ( columns => [] ) ) }); @@ -556,9 +557,11 @@ sub _post_save_save_metadata { my $obj = shift; + my ($orig_obj) = @_; if (defined $obj && exists $obj->{__meta}) { $obj->{__meta}->set_primary_keys($obj); $obj->{__meta}->save; + $orig_obj->{__meta} = $obj->{__meta}; } } @@ -855,15 +858,18 @@ our $DRIVER; sub driver { - require MT::ObjectDriverFactory; - return $DRIVER ||= MT::ObjectDriverFactory->new; + my $class = shift; + return $DRIVER ||= MT::ObjectDriverFactory->instance + if UNIVERSAL::isa($class, 'MT::Object'); + my $driver = $class->SUPER::driver(@_); + return $driver; } -# ref to the fallback driver for non-cacheable classes -our $DBI_DRIVER; sub dbi_driver { - unless ($DBI_DRIVER) { - my $driver = driver(@_); + my $class = shift; + my $props = $class->properties || {}; + unless ($props->{dbi_driver}) { + my $driver = $class->driver(@_); while ( $driver->can('fallback') ) { if ($driver->fallback) { $driver = $driver->fallback; @@ -871,9 +877,9 @@ last; } } - $DBI_DRIVER = $driver; + $props->{dbi_driver} = $driver; } - return $DBI_DRIVER; + return $props->{dbi_driver}; } sub table_name { @@ -887,6 +893,10 @@ if ($clone->properties->{meta_installed}) { $clone->init_meta(); $clone->meta( $obj->meta ); + for my $meta ( keys %{ $clone->{__meta}->{__objects} } ) { + $clone->{__meta}->{__objects}{$meta}->{changed_cols} + = $obj->{__meta}->{__objects}->{$meta}->{changed_cols} || {}; + } } return $clone; } @@ -1083,18 +1093,15 @@ return $obj; } -# We override D::OD's set_values method here only allowing the -# assignment of a column if the value given is defined. There are -# some legacy reasons for doing this, mostly for backward -# compatibility. sub set_values { my $obj = shift; my ($values) = @_; for my $col (keys %$values) { - unless ( $obj->has_column($col) ) { - Carp::croak("You tried to set inexistent column $col to value $values->{$col} on " . ref($obj)); + if ( $obj->has_column($col) ) { + # there's no point in croaking here; just set the + # values that are defined; ignore any others + $obj->$col($values->{$col}) if defined $values->{$col}; } - $obj->$col($values->{$col}) if defined $values->{$col}; } } @@ -1217,7 +1224,7 @@ my $hash = {}; my $props = $obj->properties; my $pfx = $obj->datasource; - my $values = $obj->column_values; + my $values = $obj->get_values; foreach (keys %$values) { $hash->{"${pfx}.$_"} = $values->{$_}; } @@ -1255,6 +1262,7 @@ }; my $meta_class = $class->meta_pkg; my $meta_pk = $meta_class->primary_key_tuple; + $meta_pk = [ $meta_pk->[0] ]; # we only need the first column, that's the id my @metaobjs = $meta_class->search( $meta_terms, { %$args, fetchonly => $meta_pk } ); @@ -1278,9 +1286,18 @@ my ($props) = @_; $props->{column_defs}->{$_} ||= 'string' for @{ $props->{columns} }; + + $props->{get_driver} ||= sub { + require MT::ObjectDriverFactory; + my $coderef = MT::ObjectDriverFactory->driver_for_class($class); + $class->get_driver($coderef); + return $coderef->(@_); + }; + $class->SUPER::install_properties(@_); } +sub __properties { } sub meta_pkg { undef } *table_name = \&MT::Object::table_name; @@ -1291,9 +1308,8 @@ *__parse_def = \&MT::Object::__parse_def; *count = \&MT::Object::count; *columns_of_type = \&MT::Object::columns_of_type; +*join_on = \&MT::Object::join_on; -*driver = \&MT::Object::dbi_driver; - # TODO: copy this too sub blob_requires_zip {} Index: lib/MT/ObjectAsset.pm =================================================================== --- lib/MT/ObjectAsset.pm (revision 92) +++ lib/MT/ObjectAsset.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: ObjectAsset.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: ObjectAsset.pm 3729 2009-05-15 16:04:57Z jmarcotte $ package MT::ObjectAsset; @@ -23,6 +23,10 @@ blog_obj => { columns => ['blog_id', 'object_ds', 'object_id'], }, + # TODO: Figure out how we benefit from this (from Percona-Advance recommendation) + id_ds => { + columns => ['object_id', 'object_ds'], + }, asset_id => 1, }, defaults => { Index: lib/MT/ObjectDriver/Driver/Cache/RAM.pm =================================================================== --- lib/MT/ObjectDriver/Driver/Cache/RAM.pm (revision 92) +++ lib/MT/ObjectDriver/Driver/Cache/RAM.pm (working copy) @@ -1,4 +1,4 @@ -# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. +# Movable Type (r) Open Source (C) 2001-2009 Six Apart, Ltd. # This program is distributed under the terms of the # GNU General Public License, version 2. # @@ -9,19 +9,34 @@ use strict; use warnings; -use base qw( MT::Object::BaseCache ); +use base qw( Data::ObjectDriver::Driver::BaseCache ); -sub MAX_CACHE_SIZE () { 1000 } +my $cache_limit; +sub MAX_CACHE_SIZE () { + return $cache_limit if defined $cache_limit; + return $cache_limit = MT->config->ObjectCacheLimit || 1000; +} my %Cache; +my $trigger_installed; sub init { my $driver = shift; my %param = @_; $param{cache} ||= 1; # hack + + unless (defined $trigger_installed) { + MT->add_callback( 'takedown', 9, undef, \&_takedown ); + $trigger_installed = 1; + } + $driver->SUPER::init(%param); } +sub takedown { + __PACKAGE__->clear_cache; +} + sub get_from_cache { my $driver = shift; @@ -36,8 +51,6 @@ sub add_to_cache { my $driver = shift; - return if !$driver->is_cacheable($_[1]); - if (scalar keys %Cache > MAX_CACHE_SIZE) { $driver->clear_cache(); } @@ -53,8 +66,6 @@ sub update_cache { my $driver = shift; - return if !$driver->is_cacheable($_[1]); - $driver->start_query('RAMCACHE_SET ?', \@_); my $ret = $Cache{$_[0]} = $_[1]; $driver->end_query(undef); @@ -77,9 +88,9 @@ sub clear_cache { my $driver = shift; - $driver->start_query('RAMCACHE_CLEAR'); + $driver->start_query('RAMCACHE_CLEAR') if ref $driver; %Cache = (); - $driver->end_query(undef); + $driver->end_query(undef) if ref $driver; return; } Index: lib/MT/ObjectDriver/Driver/CacheWrapper.pm =================================================================== --- lib/MT/ObjectDriver/Driver/CacheWrapper.pm (revision 0) +++ lib/MT/ObjectDriver/Driver/CacheWrapper.pm (revision 0) @@ -0,0 +1,72 @@ +# Movable Type (r) Open Source (C) 2001-2008 Six Apart Ltd. +# This program is distributed under the terms of the +# GNU General Public License, version 2. +# +# $Id: CacheWrapper.pm 3782 2009-06-03 13:11:14Z fumiakiy $ + +package MT::ObjectDriver::Driver::CacheWrapper; + +use strict; +use MT; + +my $CACHE_ENABLED; +sub wrap { + my $class = shift; + my($fallback, $object_class) = @_; + + # prevent caching if so configured + unless (defined $CACHE_ENABLED) { + $CACHE_ENABLED = MT->config->DisableObjectCache ? 0 : 1; + } + my $use_caching = 1; + if ($CACHE_ENABLED && $object_class) { + if (my $props = $object_class->properties) { + $use_caching = 0 if (defined $props->{cacheable}) && (!$props->{cacheable}); + } + } + elsif (!$CACHE_ENABLED) { + $use_caching = 0; + } + + if ( $use_caching ) { + ## If running under mod_perl, using request->pnotes; otherwise, + ## just use a hash. + my $ram_cache; + if ($ENV{MOD_PERL}) { + require Data::ObjectDriver::Driver::Cache::Apache; + $ram_cache = 'Data::ObjectDriver::Driver::Cache::Apache'; + } else { + require MT::ObjectDriver::Driver::Cache::RAM; + $ram_cache = 'MT::ObjectDriver::Driver::Cache::RAM'; + } + + my $driver; + + require MT::Memcached; + if (MT::Memcached->is_available) { + $driver = sub { + ## Look first in mod_perl/memory; then in memcached; then fall back + ## to hitting the database. + require Data::ObjectDriver::Driver::Cache::Memcached; + $ram_cache->new( + fallback => + Data::ObjectDriver::Driver::Cache::Memcached->new( + cache => MT::Memcached->instance, + fallback => $fallback->(), + ) + ); + }; + } else { + $driver = sub { + return $ram_cache->new( + fallback => $fallback->(), + ); + }; + } + return $driver; + } else { + return $fallback; + } +} + +1; Index: lib/MT/ObjectDriver/Driver/DBD/mysql.pm =================================================================== --- lib/MT/ObjectDriver/Driver/DBD/mysql.pm (revision 92) +++ lib/MT/ObjectDriver/Driver/DBD/mysql.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: mysql.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: mysql.pm 3466 2009-02-27 19:55:09Z bchoate $ package MT::ObjectDriver::Driver::DBD::mysql; @@ -76,12 +76,12 @@ if (!defined $set_names) { # SQLSetNames has never been assigned; we had a successful # 'SET NAMES' command, so it's safe to SET NAMES in the future. - $cfg->SQLSetNames(1, 1); + $cfg->SQLSetNames(1); } } else { # 'set names' command isn't working for this verison of mysql, # assign SQLSetNames to 0 to prevent further errors. - $cfg->SQLSetNames(0, 1); + $cfg->SQLSetNames(0); return 0; } }; Index: lib/MT/ObjectDriver/Driver/DBD/Pg.pm =================================================================== --- lib/MT/ObjectDriver/Driver/DBD/Pg.pm (revision 92) +++ lib/MT/ObjectDriver/Driver/DBD/Pg.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Pg.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: Pg.pm 3466 2009-02-27 19:55:09Z bchoate $ package MT::ObjectDriver::Driver::DBD::Pg; @@ -112,13 +112,13 @@ if (!$dbh->do("SET NAMES '" . $c . "'")) { # 'set names' command isn't working for this verison of PostgreSQL, # assign SQLSetNames to 0 to prevent further errors. - $cfg->SQLSetNames(0, 1); + $cfg->SQLSetNames(0); return 0; } else { if (!defined $set_names) { # SQLSetNames has never been assigned; we had a successful # 'SET NAMES' command, so it's safe to SET NAMES in the future. - $cfg->SQLSetNames(1, 1); + $cfg->SQLSetNames(1); } } }; Index: lib/MT/ObjectDriver/Driver/DBI.pm =================================================================== --- lib/MT/ObjectDriver/Driver/DBI.pm (revision 92) +++ lib/MT/ObjectDriver/Driver/DBI.pm (working copy) @@ -2,13 +2,17 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: DBI.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: DBI.pm 3783 2009-06-03 13:46:10Z fumiakiy $ package MT::ObjectDriver::Driver::DBI; use strict; use base qw( Data::ObjectDriver::Driver::DBI ); +sub PING_CHECK_THROTTLE () { 5 } + +__PACKAGE__->mk_accessors(qw( role )); + sub init { my $driver = shift; my (%param) = @_; @@ -30,6 +34,39 @@ return $driver->SUPER::start_query(@_); } +sub dbh_handle { + my $driver = shift; + my ($opt) = @_; + my $dbh = $driver->dbh; + if ($dbh) { + if ( !$dbh->{private_last_ping} || ($dbh->{private_last_ping} + PING_CHECK_THROTTLE < time) ) { + if ( $dbh->ping ) { + $dbh->{private_last_ping} = time; + } else { + $driver->dbh($dbh = undef); + } + } + } + unless ($dbh) { + if (my $getter = $driver->get_dbh) { + local $opt->{driver} = $driver; + $dbh = $getter->($opt); + $dbh->{private_last_ping} = time if $dbh; + } else { + $dbh = $driver->init_db() or die $driver->last_error; + $dbh->{private_last_ping} = time; + $driver->dbh($dbh); + } + } + $dbh; +} +*rw_handle = \&dbh_handle; + +sub r_handle { + my $driver = shift; + return $driver->dbh_handle( { readonly => 1 } ); +} + sub configure { my $driver = shift; $driver->dbd->configure($driver, @_); @@ -103,6 +140,11 @@ $driver->SUPER::direct_remove(@_); } +sub search { + my $driver = shift; + $driver->SUPER::search(@_); +} + sub count_group_by { my $driver = shift; my ($class, $terms, $args) = @_; Index: lib/MT/ObjectDriverFactory.pm =================================================================== --- lib/MT/ObjectDriverFactory.pm (revision 92) +++ lib/MT/ObjectDriverFactory.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: ObjectDriverFactory.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: ObjectDriverFactory.pm 3466 2009-02-27 19:55:09Z bchoate $ package MT::ObjectDriverFactory; @@ -24,61 +24,83 @@ our @drivers; -#sub init { -# @drivers = (); -# __PACKAGE__->new(); -#} - sub new { my $pkg = shift; + my $get_driver = $pkg->driver_for_class(); + return $get_driver->(); +} + +our $DRIVER; +sub instance { + my $pkg = shift; + $DRIVER = $pkg->new unless $DRIVER; + return $DRIVER; +} + +# Returns a coderef for an object driver that is suitable +# for the $class given. $class is optional +sub driver_for_class { + my $pkg = shift; + my ($class) = @_; + require MT::ObjectDriver::Driver::CacheWrapper; + my $driver_code = MT::ObjectDriver::Driver::CacheWrapper->wrap( + sub { + my $cfg = MT->config; + my $Password = $cfg->DBPassword; + my $Username = $cfg->DBUser; + my $dbd = $pkg->dbd_class; + my $driver = MT::ObjectDriver::Driver::DBI->new( + dbd => $dbd, + dsn => $dbd->dsn_from_config($cfg), + reuse_dbh => 1, + ($Username ? ( username => $Username) : ()), + ($Password ? ( password => $Password) : ()), + ); + push @drivers, $driver; + return $driver; + }, $class + ); + return $driver_code; +} + +our $dbd_class; +sub dbd_class { + return $dbd_class if defined $dbd_class; + my $pkg = shift; + my ($type) = @_; $type ||= MT->config('ObjectDriver'); - my $class; + my $dbd_class; foreach my $driver (@$drivers) { if ((lc $type) =~ m/^$driver->[0]$/) { - $class = $driver->[1]; + $dbd_class = $driver->[1]; last; } } - $class ||= $type; - die "Unsupported driver :" unless $class; - $class = 'MT::ObjectDriver::Driver::DBD::' . $class - unless $class =~ m/::/; - eval "use $class;"; - die "Unsupported driver $type: $@" if $@; - my $cfg = MT->config; - my $Password ||= $cfg->DBPassword; - my $Username = $cfg->DBUser; + unless ( $dbd_class ) { + my $all_drivers = MT->registry("object_drivers"); + foreach my $driver ( %$all_drivers ) { + if ( my $re = $all_drivers->{$driver}{match} ) { + if ( (lc $type) =~ m/^$re$/ ) { + $dbd_class = $all_drivers->{$driver}{config_package}; + last; + } + } + } + } - my $dbi_driver = MT::ObjectDriver::Driver::DBI->new( - dsn => $class->dsn_from_config($cfg), - ($Username ? ( username => $Username) : ()), - ($Password ? ( password => $Password) : ()), - ($class ? ( dbd => $class) : ()), - ); + $dbd_class ||= $type; + die "Unsupported driver $type" unless $dbd_class; - require MT::ObjectDriver::Driver::Cache::RAM; - require MT::Memcached; + $dbd_class = 'MT::ObjectDriver::Driver::DBD::' . $dbd_class + unless $dbd_class =~ m/::/; - my $driver; - if (MT::Memcached->is_available) { - require Data::ObjectDriver::Driver::Cache::Memcached; - $driver = MT::ObjectDriver::Driver::Cache::RAM->new( - fallback => Data::ObjectDriver::Driver::Cache::Memcached->new( - cache => MT::Memcached->instance, - fallback => $dbi_driver, - ), - ); - } else { - $driver = MT::ObjectDriver::Driver::Cache::RAM->new( - fallback => $dbi_driver, - ); - } + eval "use $dbd_class;"; + die "Unsupported driver $type: $@" if $@; - push @drivers, $driver; - return $driver; + return $dbd_class; } sub configure { @@ -87,14 +109,7 @@ } sub cleanup { - @drivers = (); - if ( my $driver = $MT::Object::DRIVER ) { - if ( my $dbh = $driver->dbh ) { - $dbh->disconnect; - } - $MT::Object::DRIVER = undef; - $MT::Object::DBI_DRIVER = undef; - } + undef $DRIVER; } 1; @@ -104,10 +119,6 @@ MT::ObjectDriverFactory -=head1 METHODS - -TODO - =head1 AUTHOR & COPYRIGHT Please see L. Index: lib/MT/Session.pm =================================================================== --- lib/MT/Session.pm (revision 92) +++ lib/MT/Session.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Session.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: Session.pm 3692 2009-05-12 18:11:26Z jmarcotte $ package MT::Session; use strict; @@ -83,6 +83,9 @@ sub set { my $sess = shift; my ($var, $val) = @_; + if ( $sess->kind eq q{US} and $var eq q{US} ) { + $sess->name($val); + } my $data = $sess->thaw_data; $sess->{__dirty} = 1; $data->{$var} = $val; Index: lib/MT/Template.pm =================================================================== --- lib/MT/Template.pm (revision 92) +++ lib/MT/Template.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Template.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: Template.pm 3474 2009-02-27 20:23:48Z bchoate $ package MT::Template; @@ -321,7 +321,7 @@ $obj->modulesets( join ',', @inst ); } else { - @inst = split /,/, $obj->modulesets; + @inst = split /,/, ($obj->modulesets || ''); } my @widgets = MT::Template->load( Index: lib/MT/Template/ContextHandlers.pm =================================================================== --- lib/MT/Template/ContextHandlers.pm (revision 92) +++ lib/MT/Template/ContextHandlers.pm (working copy) @@ -6367,7 +6367,7 @@ the score within that namespace. This specifies the maximum score to consider the author for inclusion. -=item * min_rank +=item * min_rate If 'namespace' is also specified, filters the authors based on the rank within that namespace. This specifies the minimum rank @@ -8006,19 +8006,19 @@ (($cat_class_type eq 'category' && !$args->{include_subcategories}) || ($cat_class_type ne 'category' && !$args->{include_subfolders}))) { - my @cats = cat_path_to_category($category_arg, [ \%blog_terms, \%blog_args ], $cat_class_type); - if (@cats) { - $cats = \@cats; + if ($blog_terms{blog_id}) { + my %cat_blog_terms = %blog_terms; + $cat_blog_terms{label} = $category_arg; + $cats = [ $cat_class->load(\%cat_blog_terms, \%blog_args) ]; + } else { + my @cats = cat_path_to_category($category_arg, [ \%blog_terms, \%blog_args ], $cat_class_type); + if (@cats) { + $cats = \@cats; + $cexpr = $ctx->compile_category_filter(undef, $cats, { 'and' => 0 }); + } } - $cexpr = $ctx->compile_category_filter($category_arg, $cats); } else { - my @cats; - my @args_cat = split /\s*\b(?:AND|OR|NOT)\b\s|[\s*(?:|&)\s*]/i, $category_arg; - @args_cat = grep { $_ } @args_cat; - for my $c (@args_cat) { - my @categories = cat_path_to_category($c, [ \%blog_terms, \%blog_args ], $cat_class_type); - push @cats, @categories; - } + my @cats = $cat_class->load(\%blog_terms, \%blog_args); if (@cats) { $cats = \@cats; $cexpr = $ctx->compile_category_filter($category_arg, $cats, @@ -8028,6 +8028,11 @@ }); } } + $cexpr ||= $ctx->compile_category_filter($category_arg, $cats, + { children => $cat_class_type eq 'category' ? + ($args->{include_subcategories} ? 1 : 0) : + ($args->{include_subfolders} ? 1 : 0) + }); } if ($cexpr) { my %map; @@ -8102,6 +8107,9 @@ tag_id => \@tag_ids, object_datasource => 'entry', %blog_terms }, { %blog_args, unique => 1 } ); + if (my $last = $args->{lastn} || $args->{limit}) { + $args{limit} = $last; + } } } push @filters, sub { $cexpr->($preloader->($_[0]->id)) }; @@ -10425,7 +10433,7 @@ the score within that namespace. This specifies the maximum score to consider the comment for inclusion. -=item * min_rank +=item * min_rate If 'namespace' is also specified, filters the comments based on the rank within that namespace. This specifies the minimum rank @@ -12581,7 +12589,7 @@ return '' unless $archiver; my $save_stamps; - if ($ctx->{current_archive_type} && $arg_at && ($ctx->{current_archive_type} eq $arg_at)) { + if (!$ctx->{inside_archive_list} || $ctx->{current_archive_type} && $arg_at && ($ctx->{current_archive_type} eq $arg_at)) { $save_stamps = 1; } Index: lib/MT/TheSchwartz.pm =================================================================== --- lib/MT/TheSchwartz.pm (revision 92) +++ lib/MT/TheSchwartz.pm (working copy) @@ -2,13 +2,13 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: TheSchwartz.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: TheSchwartz.pm 3733 2009-05-18 20:27:46Z jmarcotte $ package MT::TheSchwartz; use strict; use base qw( TheSchwartz ); -use MT::ObjectDriver::Driver::DBI; +use MT::ObjectDriver::Driver::Cache::RAM; use List::Util qw( shuffle ); my $instance; @@ -105,8 +105,8 @@ } sub driver_for { - my MT::TheSchwartz $client = shift; - return MT::Object->dbi_driver; + require MT::TheSchwartz::Job; + return MT::TheSchwartz::Job->dbi_driver; } sub shuffled_databases { @@ -126,6 +126,86 @@ return 0; } +sub _has_enough_swap { + my $memory_module; + eval { + require Sys::MemInfo; + $memory_module = q{Sys::MemInfo}; + }; + + my ($mem_limit) = @_; + if ( !defined($mem_limit) ) { + $mem_limit = MT->config('SchwartzSwapMemoryLimit'); + } + + if ( $mem_limit && $memory_module ) { + my $decoded_limit; + if ( $mem_limit =~ /^\d+[KGM]B?$/ ) { + my $multiplier = 1; + ( $mem_limit =~ /GB?$/ ) and $multiplier = 1073741824; + ( $mem_limit =~ /MB?$/ ) and $multiplier = 1048576; + ( $mem_limit =~ /KB?$/ ) and $multiplier = 1024; + $mem_limit =~ s/[KGM]B?$//; + $mem_limit = $mem_limit * $multiplier; + } + if ( $mem_limit =~ /\d+/ ) { + my $swap; + if ( $memory_module eq q{Sys::MemInfo} ) { + $swap = Sys::MemInfo::get("freeswap"); + } + + # not enough swap, lets get out of here! + if ( $swap < $mem_limit ) { + return 0; + } + } + } + + # default to returning true + # i.e., yes there is enough + return 1; +} + +sub _has_enough_memory { + my $memory_module; + eval { + require Sys::MemInfo; + $memory_module = q{Sys::MemInfo}; + }; + + my ($mem_limit) = @_; + if ( !defined($mem_limit) ) { + $mem_limit = MT->config('SchwartzFreeMemoryLimit'); + } + + if ( $mem_limit && $memory_module ) { + my $decoded_limit; + if ( $mem_limit =~ /^\d+[KGM]B?$/ ) { + my $multiplier = 1; + ( $mem_limit =~ /GB?$/ ) and $multiplier = 1073741824; + ( $mem_limit =~ /MB?$/ ) and $multiplier = 1048576; + ( $mem_limit =~ /KB?$/ ) and $multiplier = 1024; + $mem_limit =~ s/[KGM]B?$//; + $mem_limit = $mem_limit * $multiplier; + } + if ( $mem_limit =~ /\d+/ ) { + my $free; + if ( $memory_module eq q{Sys::MemInfo} ) { + $free = Sys::MemInfo::get("freemem"); + } + + # not enough free, lets get out of here! + if ( $free < $mem_limit ) { + return 0; + } + } + } + + # default to returning true + # i.e., yes there is enough + return 1; +} + # Replacement for TheSchwartz::get_server_time # to simply return value from dbd->sql_for_unixtime # if it is a plain number (the driver has no function, @@ -135,9 +215,37 @@ my($driver) = @_; my $unixtime_sql = $driver->dbd->sql_for_unixtime; return $unixtime_sql if $unixtime_sql =~ m/^\d+$/; - return $driver->rw_handle->selectrow_array("SELECT $unixtime_sql"); + return $driver->r_handle->selectrow_array("SELECT $unixtime_sql"); } +sub work_until_done { + my TheSchwartz $client = shift; + if ( ! $client ) { + return; + } + my $cap = MT->config('SchwartzClientDeadline'); # in seconds + my $mem_limit = MT->config('SchwartzFreeMemoryLimit'); + $mem_limit ||= 0; + my $swap_limit = MT->config('SchwartzSwapMemoryLimit'); + $swap_limit ||= 0; + my $deadline; + if ( $cap ) { + $deadline = time() + $cap; + while ( time() < $deadline ) { + $client->work_once or last; + last unless _has_enough_memory( $mem_limit ); + last unless _has_enough_memory( $swap_limit ); + } + } + else { + while ( 1 ) { + $client->work_once or last; + last unless _has_enough_memory( $mem_limit ); + last unless _has_enough_swap( $swap_limit ); + } + } +} + sub work_periodically { my TheSchwartz $client = shift; my ($delay) = @_; @@ -168,10 +276,11 @@ } if ($did_work) { - my $driver = MT::Object->driver; - $driver->clear_cache - if $driver->can('clear_cache'); + # Clear RAM cache + MT::ObjectDriver::Driver::Cache::RAM->clear_cache; + MT->request->reset(); + $did_work = 0; if ($OBJECT_REPORT) { my $report = leak_report(\%obj_start, \%obj_pre, \%Devel::Leak::Object::OBJECT_COUNT); Index: lib/MT/TheSchwartz/Error.pm =================================================================== --- lib/MT/TheSchwartz/Error.pm (revision 92) +++ lib/MT/TheSchwartz/Error.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Error.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: Error.pm 3683 2009-05-11 22:26:15Z jmarcotte $ package MT::TheSchwartz::Error; @@ -19,6 +19,7 @@ datasource => 'ts_error', indexes => { jobid => 1, + error_time => 1, funcid_time => { columns => ['funcid', 'error_time'], }, Index: lib/MT/TheSchwartz/Job.pm =================================================================== --- lib/MT/TheSchwartz/Job.pm (revision 92) +++ lib/MT/TheSchwartz/Job.pm (working copy) @@ -1,8 +1,8 @@ -# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. +# Movable Type (r) Open Source (C) 2001-2009 Six Apart, Ltd. # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Job.pm 1543 2008-03-18 00:26:27Z auno $ +# $Id: Job.pm 3710 2009-05-12 22:09:06Z jmarcotte $ package MT::TheSchwartz::Job; @@ -38,6 +38,7 @@ unique => 1, }, }, + role => q{global}, }); sub class_label { Index: lib/MT/Upgrade.pm =================================================================== --- lib/MT/Upgrade.pm (revision 92) +++ lib/MT/Upgrade.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: Upgrade.pm 3481 2009-03-02 06:42:45Z takayama $ +# $Id: Upgrade.pm 3487 2009-03-03 03:56:54Z fumiakiy $ package MT::Upgrade; @@ -2094,6 +2094,8 @@ my $install = $opt{Install} || 0; + return 1 if $DryRun; + my $updated = 0; my $tmpl_list; @@ -2236,12 +2238,13 @@ $self->progress($self->translate_escape('Removing unnecessary indexes...')); my $driver = MT::Object->driver; + my $dbh = $driver->rw_handle; + local $dbh->{RaiseError} = 0; if ($driver->dbd =~ m/::Pg$|::Oracle$/) { $driver->sql([ 'drop index mt_asset_url', 'drop index mt_asset_file_path', - 'drop index mt_blocklist_name', 'drop index mt_entry_blog_id', 'drop index mt_template_build_dynamic' ]); @@ -2249,7 +2252,6 @@ $driver->sql([ 'drop index mt_asset_url on mt_asset', 'drop index mt_asset_file_path on mt_asset', - 'drop index mt_blocklist_name on mt_blocklist', 'drop index mt_entry_blog_id on mt_entry', 'drop index mt_template_build_dynamic on mt_tempalte' ]); @@ -2257,7 +2259,6 @@ $driver->sql([ 'drop index mt_asset.mt_asset_url', 'drop index mt_asset.mt_asset_file_path', - 'drop index mt_blocklist.mt_blocklist_name', 'drop index mt_entry.mt_entry_blog_id', 'drop index mt_tempalte.mt_template_build_dynamic' ]); @@ -2351,6 +2352,10 @@ my $plugin_ver = MT->config('PluginSchemaVersion') || {}; $plugin_ver->{'core'} = $from; + if ( $DryRun ) { + return 1; + } + # run any functions that define a version_limit and where the schema we're # upgrading from is below that limit. foreach my $fn (keys %functions) { @@ -2579,6 +2584,7 @@ } else { if ($dbh && !$DryRun) { my $err; + local $dbh->{RaiseError} = 0; $dbh->do($stmt) or $err = $dbh->errstr; if ($err) { # ignore drop errors; the table/sequence/constraint @@ -2626,6 +2632,8 @@ sub core_finish { my $self = shift; + return 1 if $DryRun; + my $user; if ((ref $App) && ($App->{author})) { $user = $App->{author}; @@ -2636,7 +2644,7 @@ my $old_schema = $cfg->SchemaVersion || 0; if ($cur_schema > $old_schema) { $self->progress($self->translate_escape("Database has been upgraded to version [_1].", $cur_schema)) ; - if ($user && !$DryRun) { + if ($user) { MT->log(MT->translate("User '[_1]' upgraded database to version [_2]", $user->name, $cur_schema)); } $cfg->SchemaVersion( $cur_schema, 1 ); @@ -2650,7 +2658,7 @@ my $old_plugin_schema = $plugin_schema->{$plugin->id} || 0; if ($old_plugin_schema && ($ver > $old_plugin_schema)) { $self->progress($self->translate_escape("Plugin '[_1]' upgraded successfully to version [_2] (schema version [_3]).", $plugin->label, $plugin->version || '-', $ver)); - if ($user && !$DryRun) { + if ($user) { MT->log(MT->translate("User '[_1]' upgraded plugin '[_2]' to version [_3] (schema version [_4]).", $user->name, $plugin->label, $plugin->version || '-', $ver)); } } elsif ($ver && !$old_plugin_schema) { @@ -2661,6 +2669,8 @@ } $plugin_schema->{$plugin->id} = $ver; } + + # Updates versioning in mt_config table if (keys %$plugin_schema) { $cfg->PluginSchemaVersion($plugin_schema, 1); } @@ -2669,7 +2679,7 @@ if ( !defined($cfg->MTVersion) || ( $cur_version > $cfg->MTVersion ) ) { $cfg->MTVersion( $cur_version, 1 ); } - $cfg->save_config unless $DryRun; + $cfg->save_config; # do one last thing.... if ((ref $App) && ($App->can('finish'))) { @@ -3067,8 +3077,9 @@ my $continue = 0; my $driver = $class->driver; - if ($sql && $DryRun) { - $self->run_callbacks('SQL', $sql); + if ($DryRun) { + $self->run_callbacks('SQL', $sql) if $sql; + return 1; } return 1 if $DryRun; Index: lib/MT/Util.pm =================================================================== --- lib/MT/Util.pm (revision 92) +++ lib/MT/Util.pm (working copy) @@ -31,6 +31,15 @@ my $Has_Weaken; sub weaken { no warnings; + my $disable_cache = MT->instance->config('DisableObjectCache'); + + return if $disable_cache; + if (!$disable_cache && UNIVERSAL::isa($_[0], 'MT::Object')) { + if (my $props = $_[0]->properties) { + return if (defined $props->{cacheable}) && (!$props->{cacheable}); + } + } + return Scalar::Util::weaken($_[0]) if $Has_Weaken; $Has_Weaken = eval 'use Scalar::Util; 1' && Scalar::Util->can('weaken') ? 1 : 0; Scalar::Util::weaken($_[0]) if $Has_Weaken; @@ -463,7 +472,7 @@ } else { $offset = MT->config->TimeOffset; } - $offset += 1 if (localtime $ts)[8]; + $offset += 1 if $blog && (localtime $ts)[8]; $offset *= -1 if $dir && $dir eq '-'; $ts += $offset * 3600; $ts; Index: lib/MT/WeblogPublisher.pm =================================================================== --- lib/MT/WeblogPublisher.pm (revision 92) +++ lib/MT/WeblogPublisher.pm (working copy) @@ -2,7 +2,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: WeblogPublisher.pm 3455 2009-02-23 02:29:31Z auno $ +# $Id: WeblogPublisher.pm 3669 2009-05-06 18:06:12Z jmarcotte $ package MT::WeblogPublisher; @@ -1951,7 +1951,8 @@ $cache->{ $blog->id . $at } = $map if $map; } } - my $file_tmpl = $map->file_template if $map; + my $file_tmpl; + $file_tmpl = $map->file_template if $map; unless ($file_tmpl) { if ( my $tmpls = $archiver->default_archive_templates ) { my ($default) = grep { $_->{default} } @$tmpls; Index: mt-static/css/main.css =================================================================== --- mt-static/css/main.css (revision 92) +++ mt-static/css/main.css (working copy) @@ -72,8 +72,7 @@ .field-left-label .field-header{float:left;width:120px;margin-right:10px;text-align:right;}.edit-author #main-content .field .field-content, .edit-folder #main-content .field .field-content, .edit-category #main-content .field .field-content, -#adjust-sitepath .field-left-label .field-content, -#main-content .field-left-label .field-content{margin-left:130px;}.field-display-options .field-header{float:left;width:60px;margin-right:10px;text-align:right;}.field-display-options .field-content{margin-left:70px;}.create-inline .field-inner, +.field-left-label .field-content{margin-left:130px;}.field-display-options .field-header{float:left;width:60px;margin-right:10px;text-align:right;}.field-display-options .field-content{margin-left:70px;}.create-inline .field-inner, .create-inline .field-inline, .create-inline .field-header, .create-inline .field-content, Index: mt-static/css/structure.css =================================================================== --- mt-static/css/structure.css (revision 92) +++ mt-static/css/structure.css (working copy) @@ -1706,8 +1706,7 @@ .edit-author #main-content .field .field-content, .edit-folder #main-content .field .field-content, .edit-category #main-content .field .field-content, -#adjust-sitepath .field-left-label .field-content, -#main-content .field-left-label .field-content { +.field-left-label .field-content { margin-left: 130px; } Index: php/lib/mtdb_base.php =================================================================== --- php/lib/mtdb_base.php (revision 92) +++ php/lib/mtdb_base.php (working copy) @@ -3,7 +3,7 @@ # This program is distributed under the terms of the # GNU General Public License, version 2. # -# $Id: mtdb_base.php 3489 2009-03-04 11:01:48Z takayama $ +# $Id: mtdb_base.php 3776 2009-06-02 09:57:36Z takayama $ class MTDatabaseBase extends ezsql { var $savedqueries = array(); @@ -87,6 +87,7 @@ and ((fileinfo_url = '%1\$s' or fileinfo_url = '%1\$s/') or (fileinfo_url like '%1\$s/$escindex%%')) and blog_id = fileinfo_blog_id and template_id = fileinfo_template_id + and template_identifier != 'backup' order by length(fileinfo_url) asc "; $rows = $this->get_results(sprintf($sql,$p), ARRAY_A); Index: php/mt.php =================================================================== --- php/mt.php (revision 92) +++ php/mt.php (working copy) @@ -5,9 +5,9 @@ # # $Id$ -define('VERSION', '4.25'); -define('VERSION_ID', '4.25-ru'); -define('PRODUCT_VERSION', '4.25'); +define('VERSION', '4.26'); +define('VERSION_ID', '4.26-ru'); +define('PRODUCT_VERSION', '4.26'); define('PRODUCT_NAME', 'Movable Type'); global $Lexicon; Index: tmpl/cms/edit_entry.tmpl =================================================================== --- tmpl/cms/edit_entry.tmpl (revision 92) +++ tmpl/cms/edit_entry.tmpl (working copy) @@ -490,6 +490,11 @@ Editor.strings.enterEmailAddress = '<__trans phrase="Enter email address:" escape="js">'; Editor.strings.enterLinkAddress = '<__trans phrase="Enter the link address:" escape="js">'; Editor.strings.enterTextToLinkTo = '<__trans phrase="Enter the text to link to:" escape="js">'; + function restoreBarPosition() { + var current_bar_position = 'topbottombothtop'; + setBarPosition( current_bar_position ); + getByID( 'bar_position_' + current_bar_position ).checked = 'checked'; + } /* ]]> */ @@ -969,6 +974,7 @@ title="<__trans phrase="Save display options">" ><__trans phrase="OK"> " ><__trans phrase="Cancel"> Index: tmpl/cms/include/display_options.tmpl =================================================================== --- tmpl/cms/include/display_options.tmpl (revision 92) +++ tmpl/cms/include/display_options.tmpl (working copy) @@ -1,4 +1,13 @@ <$mt:setvar name="show_display_options_link" value="1"$> +